diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 49fe2333dac632..2c689a6328b8e2 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,5 +1,5 @@ -# Help +# Help #### The issues section is for bug reports and feature requests only. If you need help, please use the [forum](http://discourse.threejs.org/) or [stackoverflow](http://stackoverflow.com/questions/tagged/three.js). --- # Bugs @@ -25,4 +25,5 @@ 2. Fork the repository on GitHub. 3. Check the [Contribution Guidelines](https://github.com/mrdoob/three.js/wiki/How-to-contribute-to-three.js). 4. Make changes to your clone of the repository. -5. Submit a pull request. Don't include build files in the PR. +5. If your changes leads to a change in examples, make a new screenshot with `npm run make-screenshot `. +6. Submit a pull request. Don't include build files in the PR. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 94acdd9875e887..ddde421d4260f0 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -11,15 +11,13 @@ Always include a code snippet, screenshots, and any relevant models or textures Please also include a live example if possible. You can start from these templates: -* [jsfiddle](https://jsfiddle.net/3foLr7sn/) (latest release branch) -* [jsfiddle](https://jsfiddle.net/qgu17w5o/) (dev branch) -* [codepen](https://codepen.io/anon/pen/aEBKxR) (latest release branch) -* [codepen](https://codepen.io/anon/pen/BJWzaN) (dev branch) +* [jsfiddle](https://jsfiddle.net/hyok6tvj/) (latest release branch) +* [jsfiddle](https://jsfiddle.net/c5m1kazu/) (dev branch) ##### Three.js version - [ ] Dev -- [ ] r107 +- [ ] r114 - [ ] ... ##### Browser diff --git a/.gitignore b/.gitignore index e5f2db52a401b0..9b69ecf9e473c7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ node_modules npm-debug.log .jshintrc .vs/ -test/unit/three.*.unit.js +test/unit/three.*.unit.js \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 2e53aa5fa7d4f9..27445e8eec2cf9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,27 @@ language: node_js -node_js: - - node -script: - - npm run travis +node_js: node +services: xvfb +cache: bundler + +jobs: + include: + + - &lint-n-unit + stage: lint & unit + name: lint + script: npm run test-lint + - <<: *lint-n-unit + name: unit + script: npm run test-unit + + - &e2e + stage: e2e + name: e2e + script: npm run test-e2e + env: FORCE_COLOR=0 CI=0 + - <<: *e2e + env: FORCE_COLOR=0 CI=1 + - <<: *e2e + env: FORCE_COLOR=0 CI=2 + - <<: *e2e + env: FORCE_COLOR=0 CI=3 diff --git a/LICENSE b/LICENSE index d3400897d5960f..9ef721c2749c95 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright © 2010-2019 three.js authors +Copyright © 2010-2020 three.js authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 04fa48c9ab223b..0dfd953ee8b66f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ three.js ======== -[![NPM package][npm]][npm-url] +[![NPM Package][npm]][npm-url] [![Build Size][build-size]][build-size-url] -[![Build Status][build-status]][build-status-url] -[![Dependencies][dependencies]][dependencies-url] +[![NPM Downloads][npm-downloads]][npmtrends-url] [![Dev Dependencies][dev-dependencies]][dev-dependencies-url] [![Language Grade][lgtm]][lgtm-url] @@ -18,21 +17,16 @@ The aim of the project is to create an easy to use, lightweight, 3D library with [Migrating](https://github.com/mrdoob/three.js/wiki/Migration-Guide) — [Questions](http://stackoverflow.com/questions/tagged/three.js) — [Forum](https://discourse.threejs.org/) — -[Gitter](https://gitter.im/mrdoob/three.js) — -[Slack](https://join.slack.com/t/threejs/shared_invite/enQtMzYxMzczODM2OTgxLTQ1YmY4YTQxOTFjNDAzYmQ4NjU2YzRhNzliY2RiNDEyYjU2MjhhODgyYWQ5Y2MyZTU3MWNkOGVmOGRhOTQzYTk) +[Slack](https://join.slack.com/t/threejs/shared_invite/enQtMzYxMzczODM2OTgxLTQ1YmY4YTQxOTFjNDAzYmQ4NjU2YzRhNzliY2RiNDEyYjU2MjhhODgyYWQ5Y2MyZTU3MWNkOGVmOGRhOTQzYTk) — +[Discord](https://discordapp.com/invite/HF4UdyF) ### Usage ### -Download the [minified library](http://threejs.org/build/three.min.js) and include it in your HTML, or install and import it as a [module](http://threejs.org/docs/#manual/introduction/Import-via-modules), -Alternatively, see [how to build the library yourself](https://github.com/mrdoob/three.js/wiki/Build-instructions). - -```html - -``` - This code creates a scene, a camera, and a geometric cube, and it adds the cube to the scene. It then creates a `WebGL` renderer for the scene and camera, and it adds that viewport to the `document.body` element. Finally, it animates the cube within the scene for the camera. ```javascript +import * as THREE from 'js/three.module.js'; + var camera, scene, renderer; var geometry, material, mesh; @@ -77,15 +71,13 @@ If everything went well you should see [this](https://jsfiddle.net/f2Lommf5/). [Releases](https://github.com/mrdoob/three.js/releases) -[npm]: https://img.shields.io/npm/v/three.svg +[npm]: https://img.shields.io/npm/v/three [npm-url]: https://www.npmjs.com/package/three [build-size]: https://badgen.net/bundlephobia/minzip/three [build-size-url]: https://bundlephobia.com/result?p=three -[build-status]: https://travis-ci.org/mrdoob/three.js.svg?branch=dev -[build-status-url]: https://travis-ci.org/mrdoob/three.js -[dependencies]: https://img.shields.io/david/mrdoob/three.js.svg -[dependencies-url]: https://david-dm.org/mrdoob/three.js -[dev-dependencies]: https://img.shields.io/david/dev/mrdoob/three.js.svg +[npm-downloads]: https://img.shields.io/npm/dw/three +[npmtrends-url]: https://www.npmtrends.com/three +[dev-dependencies]: https://img.shields.io/david/dev/mrdoob/three.js [dev-dependencies-url]: https://david-dm.org/mrdoob/three.js#info=devDependencies -[lgtm]: https://img.shields.io/lgtm/grade/javascript/g/mrdoob/three.js.svg?label=code%20quality +[lgtm]: https://img.shields.io/lgtm/alerts/github/mrdoob/three.js [lgtm-url]: https://lgtm.com/projects/g/mrdoob/three.js/ diff --git a/build/three.js b/build/three.js index 0944d6847d7891..4f07d18b0f1f55 100644 --- a/build/three.js +++ b/build/three.js @@ -2,7 +2,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.THREE = {})); -}(this, function (exports) { 'use strict'; +}(this, (function (exports) { 'use strict'; // Polyfills @@ -97,91 +97,7 @@ } - /** - * https://github.com/mrdoob/eventdispatcher.js/ - */ - - function EventDispatcher() {} - - Object.assign( EventDispatcher.prototype, { - - addEventListener: function ( type, listener ) { - - if ( this._listeners === undefined ) this._listeners = {}; - - var listeners = this._listeners; - - if ( listeners[ type ] === undefined ) { - - listeners[ type ] = []; - - } - - if ( listeners[ type ].indexOf( listener ) === - 1 ) { - - listeners[ type ].push( listener ); - - } - - }, - - hasEventListener: function ( type, listener ) { - - if ( this._listeners === undefined ) return false; - - var listeners = this._listeners; - - return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; - - }, - - removeEventListener: function ( type, listener ) { - - if ( this._listeners === undefined ) return; - - var listeners = this._listeners; - var listenerArray = listeners[ type ]; - - if ( listenerArray !== undefined ) { - - var index = listenerArray.indexOf( listener ); - - if ( index !== - 1 ) { - - listenerArray.splice( index, 1 ); - - } - - } - - }, - - dispatchEvent: function ( event ) { - - if ( this._listeners === undefined ) return; - - var listeners = this._listeners; - var listenerArray = listeners[ event.type ]; - - if ( listenerArray !== undefined ) { - - event.target = this; - - var array = listenerArray.slice( 0 ); - - for ( var i = 0, l = array.length; i < l; i ++ ) { - - array[ i ].call( this, event ); - - } - - } - - } - - } ); - - var REVISION = '108dev'; + var REVISION = '115dev'; var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 }; var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 }; var CullFaceNone = 0; @@ -193,14 +109,12 @@ var BasicShadowMap = 0; var PCFShadowMap = 1; var PCFSoftShadowMap = 2; + var VSMShadowMap = 3; var FrontSide = 0; var BackSide = 1; var DoubleSide = 2; var FlatShading = 1; var SmoothShading = 2; - var NoColors = 0; - var FaceColors = 1; - var VertexColors = 2; var NoBlending = 0; var NormalBlending = 1; var AdditiveBlending = 2; @@ -283,6 +197,12 @@ var DepthFormat = 1026; var DepthStencilFormat = 1027; var RedFormat = 1028; + var RedIntegerFormat = 1029; + var RGFormat = 1030; + var RGIntegerFormat = 1031; + var RGBIntegerFormat = 1032; + var RGBAIntegerFormat = 1033; + var RGB_S3TC_DXT1_Format = 33776; var RGBA_S3TC_DXT1_Format = 33777; var RGBA_S3TC_DXT3_Format = 33778; @@ -292,6 +212,8 @@ var RGBA_PVRTC_4BPPV1_Format = 35842; var RGBA_PVRTC_2BPPV1_Format = 35843; var RGB_ETC1_Format = 36196; + var RGB_ETC2_Format = 37492; + var RGBA_ETC2_EAC_Format = 37496; var RGBA_ASTC_4x4_Format = 37808; var RGBA_ASTC_5x4_Format = 37809; var RGBA_ASTC_5x5_Format = 37810; @@ -306,6 +228,20 @@ var RGBA_ASTC_10x10_Format = 37819; var RGBA_ASTC_12x10_Format = 37820; var RGBA_ASTC_12x12_Format = 37821; + var SRGB8_ALPHA8_ASTC_4x4_Format = 37840; + var SRGB8_ALPHA8_ASTC_5x4_Format = 37841; + var SRGB8_ALPHA8_ASTC_5x5_Format = 37842; + var SRGB8_ALPHA8_ASTC_6x5_Format = 37843; + var SRGB8_ALPHA8_ASTC_6x6_Format = 37844; + var SRGB8_ALPHA8_ASTC_8x5_Format = 37845; + var SRGB8_ALPHA8_ASTC_8x6_Format = 37846; + var SRGB8_ALPHA8_ASTC_8x8_Format = 37847; + var SRGB8_ALPHA8_ASTC_10x5_Format = 37848; + var SRGB8_ALPHA8_ASTC_10x6_Format = 37849; + var SRGB8_ALPHA8_ASTC_10x8_Format = 37850; + var SRGB8_ALPHA8_ASTC_10x10_Format = 37851; + var SRGB8_ALPHA8_ASTC_12x10_Format = 37852; + var SRGB8_ALPHA8_ASTC_12x12_Format = 37853; var LoopOnce = 2200; var LoopRepeat = 2201; var LoopPingPong = 2202; @@ -349,9 +285,105 @@ var GreaterEqualStencilFunc = 518; var AlwaysStencilFunc = 519; + var StaticDrawUsage = 35044; + var DynamicDrawUsage = 35048; + var StreamDrawUsage = 35040; + var StaticReadUsage = 35045; + var DynamicReadUsage = 35049; + var StreamReadUsage = 35041; + var StaticCopyUsage = 35046; + var DynamicCopyUsage = 35050; + var StreamCopyUsage = 35042; + + /** + * https://github.com/mrdoob/eventdispatcher.js/ + */ + + function EventDispatcher() {} + + Object.assign( EventDispatcher.prototype, { + + addEventListener: function ( type, listener ) { + + if ( this._listeners === undefined ) { this._listeners = {}; } + + var listeners = this._listeners; + + if ( listeners[ type ] === undefined ) { + + listeners[ type ] = []; + + } + + if ( listeners[ type ].indexOf( listener ) === - 1 ) { + + listeners[ type ].push( listener ); + + } + + }, + + hasEventListener: function ( type, listener ) { + + if ( this._listeners === undefined ) { return false; } + + var listeners = this._listeners; + + return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; + + }, + + removeEventListener: function ( type, listener ) { + + if ( this._listeners === undefined ) { return; } + + var listeners = this._listeners; + var listenerArray = listeners[ type ]; + + if ( listenerArray !== undefined ) { + + var index = listenerArray.indexOf( listener ); + + if ( index !== - 1 ) { + + listenerArray.splice( index, 1 ); + + } + + } + + }, + + dispatchEvent: function ( event ) { + + if ( this._listeners === undefined ) { return; } + + var listeners = this._listeners; + var listenerArray = listeners[ event.type ]; + + if ( listenerArray !== undefined ) { + + event.target = this; + + var array = listenerArray.slice( 0 ); + + for ( var i = 0, l = array.length; i < l; i ++ ) { + + array[ i ].call( this, event ); + + } + + } + + } + + } ); + /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + * @author thezwap */ var _lut = []; @@ -362,7 +394,7 @@ } - var _Math = { + var MathUtils = { DEG2RAD: Math.PI / 180, RAD2DEG: 180 / Math.PI, @@ -420,8 +452,8 @@ smoothstep: function ( x, min, max ) { - if ( x <= min ) return 0; - if ( x >= max ) return 1; + if ( x <= min ) { return 0; } + if ( x >= max ) { return 1; } x = ( x - min ) / ( max - min ); @@ -431,8 +463,8 @@ smootherstep: function ( x, min, max ) { - if ( x <= min ) return 0; - if ( x >= max ) return 1; + if ( x <= min ) { return 0; } + if ( x >= max ) { return 1; } x = ( x - min ) / ( max - min ); @@ -466,13 +498,13 @@ degToRad: function ( degrees ) { - return degrees * _Math.DEG2RAD; + return degrees * MathUtils.DEG2RAD; }, radToDeg: function ( radians ) { - return radians * _Math.RAD2DEG; + return radians * MathUtils.RAD2DEG; }, @@ -492,6 +524,61 @@ return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); + }, + + setQuaternionFromProperEuler: function ( q, a, b, c, order ) { + + // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles + + // rotations are applied to the axes in the order specified by 'order' + // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' + // angles are in radians + + var cos = Math.cos; + var sin = Math.sin; + + var c2 = cos( b / 2 ); + var s2 = sin( b / 2 ); + + var c13 = cos( ( a + c ) / 2 ); + var s13 = sin( ( a + c ) / 2 ); + + var c1_3 = cos( ( a - c ) / 2 ); + var s1_3 = sin( ( a - c ) / 2 ); + + var c3_1 = cos( ( c - a ) / 2 ); + var s3_1 = sin( ( c - a ) / 2 ); + + if ( order === 'XYX' ) { + + q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 ); + + } else if ( order === 'YZY' ) { + + q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 ); + + } else if ( order === 'ZXZ' ) { + + q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 ); + + } else if ( order === 'XZX' ) { + + q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 ); + + } else if ( order === 'YXY' ) { + + q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 ); + + } else if ( order === 'ZYZ' ) { + + q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 ); + + } else { + + console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order.' ); + + } + } }; @@ -878,9 +965,7 @@ // computes the angle in radians with respect to the positive x-axis - var angle = Math.atan2( this.y, this.x ); - - if ( angle < 0 ) angle += 2 * Math.PI; + var angle = Math.atan2( - this.y, - this.x ) + Math.PI; return angle; @@ -934,7 +1019,7 @@ fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) { offset = 0; } this.x = array[ offset ]; this.y = array[ offset + 1 ]; @@ -945,8 +1030,8 @@ toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } array[ offset ] = this.x; array[ offset + 1 ] = this.y; @@ -987,771 +1072,931 @@ } ); /** - * @author mikael emtinger / http://gomo.se/ * @author alteredq / http://alteredqualia.com/ * @author WestLangley / http://github.com/WestLangley * @author bhouston / http://clara.io + * @author tschw */ - function Quaternion( x, y, z, w ) { - - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._w = ( w !== undefined ) ? w : 1; - - } - - Object.assign( Quaternion, { - - slerp: function ( qa, qb, qm, t ) { - - return qm.copy( qa ).slerp( qb, t ); + function Matrix3() { - }, + this.elements = [ - slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 - // fuzz-free, array-based Quaternion SLERP operation + ]; - var x0 = src0[ srcOffset0 + 0 ], - y0 = src0[ srcOffset0 + 1 ], - z0 = src0[ srcOffset0 + 2 ], - w0 = src0[ srcOffset0 + 3 ], + if ( arguments.length > 0 ) { - x1 = src1[ srcOffset1 + 0 ], - y1 = src1[ srcOffset1 + 1 ], - z1 = src1[ srcOffset1 + 2 ], - w1 = src1[ srcOffset1 + 3 ]; + console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); - if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { + } - var s = 1 - t, + } - cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, + Object.assign( Matrix3.prototype, { - dir = ( cos >= 0 ? 1 : - 1 ), - sqrSin = 1 - cos * cos; + isMatrix3: true, - // Skip the Slerp for tiny steps to avoid numeric problems: - if ( sqrSin > Number.EPSILON ) { + set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { - var sin = Math.sqrt( sqrSin ), - len = Math.atan2( sin, cos * dir ); + var te = this.elements; - s = Math.sin( s * len ) / sin; - t = Math.sin( t * len ) / sin; + te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; + te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; + te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; - } + return this; - var tDir = t * dir; + }, - x0 = x0 * s + x1 * tDir; - y0 = y0 * s + y1 * tDir; - z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; + identity: function () { - // Normalize in case we just did a lerp: - if ( s === 1 - t ) { + this.set( - var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 - x0 *= f; - y0 *= f; - z0 *= f; - w0 *= f; + ); - } + return this; - } + }, - dst[ dstOffset ] = x0; - dst[ dstOffset + 1 ] = y0; - dst[ dstOffset + 2 ] = z0; - dst[ dstOffset + 3 ] = w0; + clone: function () { - } + return new this.constructor().fromArray( this.elements ); - } ); + }, - Object.defineProperties( Quaternion.prototype, { + copy: function ( m ) { - x: { + var te = this.elements; + var me = m.elements; - get: function () { + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; + te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; + te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; - return this._x; + return this; - }, + }, - set: function ( value ) { + extractBasis: function ( xAxis, yAxis, zAxis ) { - this._x = value; - this._onChangeCallback(); + xAxis.setFromMatrix3Column( this, 0 ); + yAxis.setFromMatrix3Column( this, 1 ); + zAxis.setFromMatrix3Column( this, 2 ); - } + return this; }, - y: { - - get: function () { + setFromMatrix4: function ( m ) { - return this._y; + var me = m.elements; - }, + this.set( - set: function ( value ) { + me[ 0 ], me[ 4 ], me[ 8 ], + me[ 1 ], me[ 5 ], me[ 9 ], + me[ 2 ], me[ 6 ], me[ 10 ] - this._y = value; - this._onChangeCallback(); + ); - } + return this; }, - z: { - - get: function () { - - return this._z; + multiply: function ( m ) { - }, + return this.multiplyMatrices( this, m ); - set: function ( value ) { + }, - this._z = value; - this._onChangeCallback(); + premultiply: function ( m ) { - } + return this.multiplyMatrices( m, this ); }, - w: { - - get: function () { - - return this._w; + multiplyMatrices: function ( a, b ) { - }, + var ae = a.elements; + var be = b.elements; + var te = this.elements; - set: function ( value ) { + var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; + var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; + var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; - this._w = value; - this._onChangeCallback(); + var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; + var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; + var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; - } + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; + te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; + te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; - } + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; + te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; + te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; - } ); + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; + te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; + te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; - Object.assign( Quaternion.prototype, { + return this; - isQuaternion: true, + }, - set: function ( x, y, z, w ) { + multiplyScalar: function ( s ) { - this._x = x; - this._y = y; - this._z = z; - this._w = w; + var te = this.elements; - this._onChangeCallback(); + te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; + te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; + te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; return this; }, - clone: function () { + determinant: function () { - return new this.constructor( this._x, this._y, this._z, this._w ); + var te = this.elements; - }, + var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], + d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], + g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; - copy: function ( quaternion ) { + return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; - this._x = quaternion.x; - this._y = quaternion.y; - this._z = quaternion.z; - this._w = quaternion.w; + }, - this._onChangeCallback(); + getInverse: function ( matrix, throwOnDegenerate ) { - return this; + if ( matrix && matrix.isMatrix4 ) { - }, + console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." ); - setFromEuler: function ( euler, update ) { + } - if ( ! ( euler && euler.isEuler ) ) { + var me = matrix.elements, + te = this.elements, - throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); + n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], + n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], + n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], - } + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, - var x = euler._x, y = euler._y, z = euler._z, order = euler.order; + det = n11 * t11 + n21 * t12 + n31 * t13; - // http://www.mathworks.com/matlabcentral/fileexchange/ - // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ - // content/SpinCalc.m + if ( det === 0 ) { - var cos = Math.cos; - var sin = Math.sin; + var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"; - var c1 = cos( x / 2 ); - var c2 = cos( y / 2 ); - var c3 = cos( z / 2 ); + if ( throwOnDegenerate === true ) { - var s1 = sin( x / 2 ); - var s2 = sin( y / 2 ); - var s3 = sin( z / 2 ); + throw new Error( msg ); - if ( order === 'XYZ' ) { + } else { - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + console.warn( msg ); - } else if ( order === 'YXZ' ) { + } - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + return this.identity(); - } else if ( order === 'ZXY' ) { + } - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + var detInv = 1 / det; - } else if ( order === 'ZYX' ) { + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; + te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + te[ 3 ] = t12 * detInv; + te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; + te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; - } else if ( order === 'YZX' ) { + te[ 6 ] = t13 * detInv; + te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; + te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + return this; - } else if ( order === 'XZY' ) { + }, - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + transpose: function () { - } + var tmp, m = this.elements; - if ( update !== false ) this._onChangeCallback(); + tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; + tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; + tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; return this; }, - setFromAxisAngle: function ( axis, angle ) { + getNormalMatrix: function ( matrix4 ) { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); - // assumes axis is normalized + }, - var halfAngle = angle / 2, s = Math.sin( halfAngle ); + transposeIntoArray: function ( r ) { - this._x = axis.x * s; - this._y = axis.y * s; - this._z = axis.z * s; - this._w = Math.cos( halfAngle ); + var m = this.elements; - this._onChangeCallback(); + r[ 0 ] = m[ 0 ]; + r[ 1 ] = m[ 3 ]; + r[ 2 ] = m[ 6 ]; + r[ 3 ] = m[ 1 ]; + r[ 4 ] = m[ 4 ]; + r[ 5 ] = m[ 7 ]; + r[ 6 ] = m[ 2 ]; + r[ 7 ] = m[ 5 ]; + r[ 8 ] = m[ 8 ]; return this; }, - setFromRotationMatrix: function ( m ) { + setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + var c = Math.cos( rotation ); + var s = Math.sin( rotation ); - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + this.set( + sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, + - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, + 0, 0, 1 + ); - var te = m.elements, + }, - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], + scale: function ( sx, sy ) { - trace = m11 + m22 + m33, - s; + var te = this.elements; - if ( trace > 0 ) { + te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; + te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; - s = 0.5 / Math.sqrt( trace + 1.0 ); + return this; - this._w = 0.25 / s; - this._x = ( m32 - m23 ) * s; - this._y = ( m13 - m31 ) * s; - this._z = ( m21 - m12 ) * s; + }, - } else if ( m11 > m22 && m11 > m33 ) { + rotate: function ( theta ) { - s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); + var c = Math.cos( theta ); + var s = Math.sin( theta ); - this._w = ( m32 - m23 ) / s; - this._x = 0.25 * s; - this._y = ( m12 + m21 ) / s; - this._z = ( m13 + m31 ) / s; + var te = this.elements; - } else if ( m22 > m33 ) { + var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; + var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; - s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); + te[ 0 ] = c * a11 + s * a21; + te[ 3 ] = c * a12 + s * a22; + te[ 6 ] = c * a13 + s * a23; - this._w = ( m13 - m31 ) / s; - this._x = ( m12 + m21 ) / s; - this._y = 0.25 * s; - this._z = ( m23 + m32 ) / s; + te[ 1 ] = - s * a11 + c * a21; + te[ 4 ] = - s * a12 + c * a22; + te[ 7 ] = - s * a13 + c * a23; - } else { + return this; - s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); + }, - this._w = ( m21 - m12 ) / s; - this._x = ( m13 + m31 ) / s; - this._y = ( m23 + m32 ) / s; - this._z = 0.25 * s; + translate: function ( tx, ty ) { - } + var te = this.elements; - this._onChangeCallback(); + te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; + te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; return this; }, - setFromUnitVectors: function ( vFrom, vTo ) { - - // assumes direction vectors vFrom and vTo are normalized - - var EPS = 0.000001; - - var r = vFrom.dot( vTo ) + 1; + equals: function ( matrix ) { - if ( r < EPS ) { + var te = this.elements; + var me = matrix.elements; - r = 0; + for ( var i = 0; i < 9; i ++ ) { - if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { + if ( te[ i ] !== me[ i ] ) { return false; } - this._x = - vFrom.y; - this._y = vFrom.x; - this._z = 0; - this._w = r; + } - } else { + return true; - this._x = 0; - this._y = - vFrom.z; - this._z = vFrom.y; - this._w = r; + }, - } + fromArray: function ( array, offset ) { - } else { + if ( offset === undefined ) { offset = 0; } - // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + for ( var i = 0; i < 9; i ++ ) { - this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; - this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; - this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; - this._w = r; + this.elements[ i ] = array[ i + offset ]; } - return this.normalize(); + return this; }, - angleTo: function ( q ) { - - return 2 * Math.acos( Math.abs( _Math.clamp( this.dot( q ), - 1, 1 ) ) ); + toArray: function ( array, offset ) { - }, + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } - rotateTowards: function ( q, step ) { + var te = this.elements; - var angle = this.angleTo( q ); + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; - if ( angle === 0 ) return this; + array[ offset + 3 ] = te[ 3 ]; + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; - var t = Math.min( 1, step / angle ); + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + array[ offset + 8 ] = te[ 8 ]; - this.slerp( q, t ); + return array; - return this; + } - }, + } ); - inverse: function () { + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + */ - // quaternion is assumed to have unit length + var _canvas; - return this.conjugate(); + var ImageUtils = { - }, + getDataURL: function ( image ) { - conjugate: function () { + var canvas; - this._x *= - 1; - this._y *= - 1; - this._z *= - 1; + if ( typeof HTMLCanvasElement == 'undefined' ) { - this._onChangeCallback(); + return image.src; - return this; + } else if ( image instanceof HTMLCanvasElement ) { - }, + canvas = image; - dot: function ( v ) { + } else { - return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; + if ( _canvas === undefined ) { _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); } - }, + _canvas.width = image.width; + _canvas.height = image.height; - lengthSq: function () { + var context = _canvas.getContext( '2d' ); - return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; + if ( image instanceof ImageData ) { - }, + context.putImageData( image, 0, 0 ); - length: function () { + } else { - return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); + context.drawImage( image, 0, 0, image.width, image.height ); - }, + } - normalize: function () { + canvas = _canvas; - var l = this.length(); + } - if ( l === 0 ) { + if ( canvas.width > 2048 || canvas.height > 2048 ) { - this._x = 0; - this._y = 0; - this._z = 0; - this._w = 1; + return canvas.toDataURL( 'image/jpeg', 0.6 ); } else { - l = 1 / l; - - this._x = this._x * l; - this._y = this._y * l; - this._z = this._z * l; - this._w = this._w * l; + return canvas.toDataURL( 'image/png' ); } - this._onChangeCallback(); - - return this; - - }, + } - multiply: function ( q, p ) { + }; - if ( p !== undefined ) { + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + */ - console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); - return this.multiplyQuaternions( q, p ); + var textureId = 0; - } + function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { - return this.multiplyQuaternions( this, q ); + Object.defineProperty( this, 'id', { value: textureId ++ } ); - }, + this.uuid = MathUtils.generateUUID(); - premultiply: function ( q ) { + this.name = ''; - return this.multiplyQuaternions( q, this ); + this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; + this.mipmaps = []; - }, + this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; - multiplyQuaternions: function ( a, b ) { + this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; + this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; - // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; + this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter; - var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; - var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; + this.anisotropy = anisotropy !== undefined ? anisotropy : 1; - this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; - this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; - this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; - this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + this.format = format !== undefined ? format : RGBAFormat; + this.internalFormat = null; + this.type = type !== undefined ? type : UnsignedByteType; - this._onChangeCallback(); + this.offset = new Vector2( 0, 0 ); + this.repeat = new Vector2( 1, 1 ); + this.center = new Vector2( 0, 0 ); + this.rotation = 0; - return this; + this.matrixAutoUpdate = true; + this.matrix = new Matrix3(); - }, + this.generateMipmaps = true; + this.premultiplyAlpha = false; + this.flipY = true; + this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) - slerp: function ( qb, t ) { + // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. + // + // Also changing the encoding after already used by a Material will not automatically make the Material + // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. + this.encoding = encoding !== undefined ? encoding : LinearEncoding; - if ( t === 0 ) return this; - if ( t === 1 ) return this.copy( qb ); + this.version = 0; + this.onUpdate = null; - var x = this._x, y = this._y, z = this._z, w = this._w; + } - // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + Texture.DEFAULT_IMAGE = undefined; + Texture.DEFAULT_MAPPING = UVMapping; - var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; + Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - if ( cosHalfTheta < 0 ) { + constructor: Texture, - this._w = - qb._w; - this._x = - qb._x; - this._y = - qb._y; - this._z = - qb._z; + isTexture: true, - cosHalfTheta = - cosHalfTheta; + updateMatrix: function () { - } else { + this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); - this.copy( qb ); + }, - } + clone: function () { - if ( cosHalfTheta >= 1.0 ) { + return new this.constructor().copy( this ); - this._w = w; - this._x = x; - this._y = y; - this._z = z; + }, - return this; + copy: function ( source ) { - } + this.name = source.name; - var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; + this.image = source.image; + this.mipmaps = source.mipmaps.slice( 0 ); - if ( sqrSinHalfTheta <= Number.EPSILON ) { + this.mapping = source.mapping; - var s = 1 - t; - this._w = s * w + t * this._w; - this._x = s * x + t * this._x; - this._y = s * y + t * this._y; - this._z = s * z + t * this._z; + this.wrapS = source.wrapS; + this.wrapT = source.wrapT; - this.normalize(); - this._onChangeCallback(); + this.magFilter = source.magFilter; + this.minFilter = source.minFilter; - return this; + this.anisotropy = source.anisotropy; - } + this.format = source.format; + this.internalFormat = source.internalFormat; + this.type = source.type; - var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); - var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); - var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, - ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; + this.offset.copy( source.offset ); + this.repeat.copy( source.repeat ); + this.center.copy( source.center ); + this.rotation = source.rotation; - this._w = ( w * ratioA + this._w * ratioB ); - this._x = ( x * ratioA + this._x * ratioB ); - this._y = ( y * ratioA + this._y * ratioB ); - this._z = ( z * ratioA + this._z * ratioB ); + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrix.copy( source.matrix ); - this._onChangeCallback(); + this.generateMipmaps = source.generateMipmaps; + this.premultiplyAlpha = source.premultiplyAlpha; + this.flipY = source.flipY; + this.unpackAlignment = source.unpackAlignment; + this.encoding = source.encoding; return this; }, - equals: function ( quaternion ) { + toJSON: function ( meta ) { - return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); + var isRootObject = ( meta === undefined || typeof meta === 'string' ); - }, + if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { - fromArray: function ( array, offset ) { + return meta.textures[ this.uuid ]; - if ( offset === undefined ) offset = 0; + } - this._x = array[ offset ]; - this._y = array[ offset + 1 ]; - this._z = array[ offset + 2 ]; - this._w = array[ offset + 3 ]; + var output = { - this._onChangeCallback(); + metadata: { + version: 4.5, + type: 'Texture', + generator: 'Texture.toJSON' + }, - return this; + uuid: this.uuid, + name: this.name, - }, + mapping: this.mapping, - toArray: function ( array, offset ) { + repeat: [ this.repeat.x, this.repeat.y ], + offset: [ this.offset.x, this.offset.y ], + center: [ this.center.x, this.center.y ], + rotation: this.rotation, - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + wrap: [ this.wrapS, this.wrapT ], - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._w; + format: this.format, + type: this.type, + encoding: this.encoding, - return array; + minFilter: this.minFilter, + magFilter: this.magFilter, + anisotropy: this.anisotropy, - }, + flipY: this.flipY, - _onChange: function ( callback ) { + premultiplyAlpha: this.premultiplyAlpha, + unpackAlignment: this.unpackAlignment - this._onChangeCallback = callback; + }; - return this; + if ( this.image !== undefined ) { - }, + // TODO: Move to THREE.Image - _onChangeCallback: function () {} + var image = this.image; - } ); + if ( image.uuid === undefined ) { - /** - * @author mrdoob / http://mrdoob.com/ - * @author kile / http://kile.stravaganza.org/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ + image.uuid = MathUtils.generateUUID(); // UGH - var _vector = new Vector3(); - var _quaternion = new Quaternion(); + } - function Vector3( x, y, z ) { + if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; + var url; - } + if ( Array.isArray( image ) ) { - Object.assign( Vector3.prototype, { + // process array of images e.g. CubeTexture - isVector3: true, + url = []; - set: function ( x, y, z ) { + for ( var i = 0, l = image.length; i < l; i ++ ) { - this.x = x; - this.y = y; - this.z = z; + url.push( ImageUtils.getDataURL( image[ i ] ) ); - return this; + } - }, + } else { - setScalar: function ( scalar ) { + // process single image - this.x = scalar; - this.y = scalar; - this.z = scalar; + url = ImageUtils.getDataURL( image ); - return this; + } - }, + meta.images[ image.uuid ] = { + uuid: image.uuid, + url: url + }; - setX: function ( x ) { + } - this.x = x; + output.image = image.uuid; - return this; + } - }, + if ( ! isRootObject ) { - setY: function ( y ) { + meta.textures[ this.uuid ] = output; - this.y = y; + } - return this; + return output; }, - setZ: function ( z ) { - - this.z = z; + dispose: function () { - return this; + this.dispatchEvent( { type: 'dispose' } ); }, - setComponent: function ( index, value ) { + transformUv: function ( uv ) { - switch ( index ) { + if ( this.mapping !== UVMapping ) { return uv; } - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - default: throw new Error( 'index is out of range: ' + index ); + uv.applyMatrix3( this.matrix ); - } + if ( uv.x < 0 || uv.x > 1 ) { - return this; + switch ( this.wrapS ) { - }, + case RepeatWrapping: - getComponent: function ( index ) { + uv.x = uv.x - Math.floor( uv.x ); + break; - switch ( index ) { + case ClampToEdgeWrapping: - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - default: throw new Error( 'index is out of range: ' + index ); + uv.x = uv.x < 0 ? 0 : 1; + break; - } + case MirroredRepeatWrapping: - }, + if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { - clone: function () { + uv.x = Math.ceil( uv.x ) - uv.x; - return new this.constructor( this.x, this.y, this.z ); + } else { - }, + uv.x = uv.x - Math.floor( uv.x ); - copy: function ( v ) { + } + break; - this.x = v.x; - this.y = v.y; - this.z = v.z; + } - return this; + } - }, + if ( uv.y < 0 || uv.y > 1 ) { - add: function ( v, w ) { + switch ( this.wrapT ) { - if ( w !== undefined ) { + case RepeatWrapping: - console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); + uv.y = uv.y - Math.floor( uv.y ); + break; - } + case ClampToEdgeWrapping: - this.x += v.x; - this.y += v.y; - this.z += v.z; + uv.y = uv.y < 0 ? 0 : 1; + break; - return this; + case MirroredRepeatWrapping: - }, + if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { + + uv.y = Math.ceil( uv.y ) - uv.y; + + } else { + + uv.y = uv.y - Math.floor( uv.y ); + + } + break; + + } + + } + + if ( this.flipY ) { + + uv.y = 1 - uv.y; + + } + + return uv; + + } + + } ); + + Object.defineProperty( Texture.prototype, "needsUpdate", { + + set: function ( value ) { + + if ( value === true ) { this.version ++; } + + } + + } ); + + /** + * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author philogb / http://blog.thejit.org/ + * @author mikael emtinger / http://gomo.se/ + * @author egraether / http://egraether.com/ + * @author WestLangley / http://github.com/WestLangley + */ + + function Vector4( x, y, z, w ) { + + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = ( w !== undefined ) ? w : 1; + + } + + Object.defineProperties( Vector4.prototype, { + + "width": { + + get: function () { + + return this.z; + + }, + + set: function ( value ) { + + this.z = value; + + } + + }, + + "height": { + + get: function () { + + return this.w; + + }, + + set: function ( value ) { + + this.w = value; + + } + + } + + } ); + + Object.assign( Vector4.prototype, { + + isVector4: true, + + set: function ( x, y, z, w ) { + + this.x = x; + this.y = y; + this.z = z; + this.w = w; + + return this; + + }, + + setScalar: function ( scalar ) { + + this.x = scalar; + this.y = scalar; + this.z = scalar; + this.w = scalar; + + return this; + + }, + + setX: function ( x ) { + + this.x = x; + + return this; + + }, + + setY: function ( y ) { + + this.y = y; + + return this; + + }, + + setZ: function ( z ) { + + this.z = z; + + return this; + + }, + + setW: function ( w ) { + + this.w = w; + + return this; + + }, + + setComponent: function ( index, value ) { + + switch ( index ) { + + case 0: this.x = value; break; + case 1: this.y = value; break; + case 2: this.z = value; break; + case 3: this.w = value; break; + default: throw new Error( 'index is out of range: ' + index ); + + } + + return this; + + }, + + getComponent: function ( index ) { + + switch ( index ) { + + case 0: return this.x; + case 1: return this.y; + case 2: return this.z; + case 3: return this.w; + default: throw new Error( 'index is out of range: ' + index ); + + } + + }, + + clone: function () { + + return new this.constructor( this.x, this.y, this.z, this.w ); + + }, + + copy: function ( v ) { + + this.x = v.x; + this.y = v.y; + this.z = v.z; + this.w = ( v.w !== undefined ) ? v.w : 1; + + return this; + + }, + + add: function ( v, w ) { + + if ( w !== undefined ) { + + console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + return this.addVectors( v, w ); + + } + + this.x += v.x; + this.y += v.y; + this.z += v.z; + this.w += v.w; + + return this; + + }, addScalar: function ( s ) { this.x += s; this.y += s; this.z += s; + this.w += s; return this; @@ -1762,6 +2007,7 @@ this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; + this.w = a.w + b.w; return this; @@ -1772,6 +2018,7 @@ this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; + this.w += v.w * s; return this; @@ -1781,7 +2028,7 @@ if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -1789,6 +2036,7 @@ this.x -= v.x; this.y -= v.y; this.z -= v.z; + this.w -= v.w; return this; @@ -1799,6 +2047,7 @@ this.x -= s; this.y -= s; this.z -= s; + this.w -= s; return this; @@ -1809,157 +2058,198 @@ this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; + this.w = a.w - b.w; return this; }, - multiply: function ( v, w ) { + multiplyScalar: function ( scalar ) { - if ( w !== undefined ) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + this.w *= scalar; - console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); - return this.multiplyVectors( v, w ); + return this; - } + }, - this.x *= v.x; - this.y *= v.y; - this.z *= v.z; + applyMatrix4: function ( m ) { + + var x = this.x, y = this.y, z = this.z, w = this.w; + var e = m.elements; + + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; + this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; return this; }, - multiplyScalar: function ( scalar ) { - - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; + divideScalar: function ( scalar ) { - return this; + return this.multiplyScalar( 1 / scalar ); }, - multiplyVectors: function ( a, b ) { + setAxisAngleFromQuaternion: function ( q ) { - this.x = a.x * b.x; - this.y = a.y * b.y; - this.z = a.z * b.z; + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm - return this; + // q is assumed to be normalized - }, + this.w = 2 * Math.acos( q.w ); - applyEuler: function ( euler ) { + var s = Math.sqrt( 1 - q.w * q.w ); - if ( ! ( euler && euler.isEuler ) ) { + if ( s < 0.0001 ) { - console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); + this.x = 1; + this.y = 0; + this.z = 0; + + } else { + + this.x = q.x / s; + this.y = q.y / s; + this.z = q.z / s; } - return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); + return this; }, - applyAxisAngle: function ( axis, angle ) { + setAxisAngleFromRotationMatrix: function ( m ) { - return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - }, + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - applyMatrix3: function ( m ) { + var angle, x, y, z, // variables for result + epsilon = 0.01, // margin to allow for rounding errors + epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + te = m.elements, - this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; - this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; - this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - return this; + if ( ( Math.abs( m12 - m21 ) < epsilon ) && + ( Math.abs( m13 - m31 ) < epsilon ) && + ( Math.abs( m23 - m32 ) < epsilon ) ) { - }, + // singularity found + // first check for identity matrix which must have +1 for all terms + // in leading diagonal and zero in other terms - applyMatrix4: function ( m ) { + if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && + ( Math.abs( m13 + m31 ) < epsilon2 ) && + ( Math.abs( m23 + m32 ) < epsilon2 ) && + ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + // this singularity is identity matrix so angle = 0 - var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); + this.set( 1, 0, 0, 0 ); - this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; - this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; - this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; + return this; // zero angle, arbitrary axis - return this; + } - }, + // otherwise this singularity is angle = 180 - applyQuaternion: function ( q ) { + angle = Math.PI; - var x = this.x, y = this.y, z = this.z; - var qx = q.x, qy = q.y, qz = q.z, qw = q.w; + var xx = ( m11 + 1 ) / 2; + var yy = ( m22 + 1 ) / 2; + var zz = ( m33 + 1 ) / 2; + var xy = ( m12 + m21 ) / 4; + var xz = ( m13 + m31 ) / 4; + var yz = ( m23 + m32 ) / 4; - // calculate quat * vector + if ( ( xx > yy ) && ( xx > zz ) ) { - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = - qx * x - qy * y - qz * z; + // m11 is the largest diagonal term - // calculate result * inverse quat + if ( xx < epsilon ) { - this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; - this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; - this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; + x = 0; + y = 0.707106781; + z = 0.707106781; - return this; + } else { - }, + x = Math.sqrt( xx ); + y = xy / x; + z = xz / x; - project: function ( camera ) { + } - return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); + } else if ( yy > zz ) { - }, + // m22 is the largest diagonal term - unproject: function ( camera ) { + if ( yy < epsilon ) { - return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); + x = 0.707106781; + y = 0; + z = 0.707106781; - }, + } else { - transformDirection: function ( m ) { + y = Math.sqrt( yy ); + x = xy / y; + z = yz / y; - // input: THREE.Matrix4 affine matrix - // vector interpreted as a direction + } - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + } else { - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; + // m33 is the largest diagonal term so base result on this - return this.normalize(); + if ( zz < epsilon ) { - }, + x = 0.707106781; + y = 0.707106781; + z = 0; - divide: function ( v ) { + } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z; + z = Math.sqrt( zz ); + x = xz / z; + y = yz / z; - return this; + } - }, + } - divideScalar: function ( scalar ) { + this.set( x, y, z, angle ); - return this.multiplyScalar( 1 / scalar ); + return this; // return 180 deg rotation + + } + + // as we have reached here there are no singularities so we can handle normally + + var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + + ( m13 - m31 ) * ( m13 - m31 ) + + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize + + if ( Math.abs( s ) < 0.001 ) { s = 1; } + + // prevent divide by zero, should not happen if matrix is orthogonal and should be + // caught by singularity test above, but I've left it in just in case + + this.x = ( m32 - m23 ) / s; + this.y = ( m13 - m31 ) / s; + this.z = ( m21 - m12 ) / s; + this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + + return this; }, @@ -1968,6 +2258,7 @@ this.x = Math.min( this.x, v.x ); this.y = Math.min( this.y, v.y ); this.z = Math.min( this.z, v.z ); + this.w = Math.min( this.w, v.w ); return this; @@ -1978,6 +2269,7 @@ this.x = Math.max( this.x, v.x ); this.y = Math.max( this.y, v.y ); this.z = Math.max( this.z, v.z ); + this.w = Math.max( this.w, v.w ); return this; @@ -1990,6 +2282,7 @@ this.x = Math.max( min.x, Math.min( max.x, this.x ) ); this.y = Math.max( min.y, Math.min( max.y, this.y ) ); this.z = Math.max( min.z, Math.min( max.z, this.z ) ); + this.w = Math.max( min.w, Math.min( max.w, this.w ) ); return this; @@ -2000,6 +2293,7 @@ this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); + this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); return this; @@ -2018,6 +2312,7 @@ this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); return this; @@ -2028,6 +2323,7 @@ this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); return this; @@ -2038,6 +2334,7 @@ this.x = Math.round( this.x ); this.y = Math.round( this.y ); this.z = Math.round( this.z ); + this.w = Math.round( this.w ); return this; @@ -2048,6 +2345,7 @@ this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); return this; @@ -2058,6 +2356,7 @@ this.x = - this.x; this.y = - this.y; this.z = - this.z; + this.w = - this.w; return this; @@ -2065,27 +2364,25 @@ dot: function ( v ) { - return this.x * v.x + this.y * v.y + this.z * v.z; + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; }, - // TODO lengthSquared? - lengthSq: function () { - return this.x * this.x + this.y * this.y + this.z * this.z; + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; }, length: function () { - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); }, manhattanLength: function () { - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); }, @@ -2106,6 +2403,7 @@ this.x += ( v.x - this.x ) * alpha; this.y += ( v.y - this.y ) * alpha; this.z += ( v.z - this.z ) * alpha; + this.w += ( v.w - this.w ) * alpha; return this; @@ -2117,195 +2415,176 @@ }, - cross: function ( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); - return this.crossVectors( v, w ); - - } + equals: function ( v ) { - return this.crossVectors( this, v ); + return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); }, - crossVectors: function ( a, b ) { + fromArray: function ( array, offset ) { - var ax = a.x, ay = a.y, az = a.z; - var bx = b.x, by = b.y, bz = b.z; + if ( offset === undefined ) { offset = 0; } - this.x = ay * bz - az * by; - this.y = az * bx - ax * bz; - this.z = ax * by - ay * bx; + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + this.w = array[ offset + 3 ]; return this; }, - projectOnVector: function ( vector ) { + toArray: function ( array, offset ) { + + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } - var scalar = vector.dot( this ) / vector.lengthSq(); + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + array[ offset + 3 ] = this.w; - return this.copy( vector ).multiplyScalar( scalar ); + return array; }, - projectOnPlane: function ( planeNormal ) { + fromBufferAttribute: function ( attribute, index, offset ) { - _vector.copy( this ).projectOnVector( planeNormal ); + if ( offset !== undefined ) { - return this.sub( _vector ); + console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); - }, + } - reflect: function ( normal ) { + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); + this.w = attribute.getW( index ); - // reflect incident vector off plane orthogonal to normal - // normal is assumed to have unit length + return this; - return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); + } - }, + } ); - angleTo: function ( v ) { + /** + * @author szimek / https://github.com/szimek/ + * @author alteredq / http://alteredqualia.com/ + * @author Marius Kintel / https://github.com/kintel + */ - var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) ); + /* + In options, we can specify: + * Texture parameters for an auto-generated target texture + * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers + */ + function WebGLRenderTarget( width, height, options ) { - // clamp, to handle numerical problems + this.width = width; + this.height = height; - return Math.acos( _Math.clamp( theta, - 1, 1 ) ); + this.scissor = new Vector4( 0, 0, width, height ); + this.scissorTest = false; - }, + this.viewport = new Vector4( 0, 0, width, height ); - distanceTo: function ( v ) { + options = options || {}; - return Math.sqrt( this.distanceToSquared( v ) ); - - }, - - distanceToSquared: function ( v ) { - - var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; - - return dx * dx + dy * dy + dz * dz; + this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); - }, + this.texture.image = {}; + this.texture.image.width = width; + this.texture.image.height = height; - manhattanDistanceTo: function ( v ) { + this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; + this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; - return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); + this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; + this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; + this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; - }, + } - setFromSpherical: function ( s ) { + WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); + constructor: WebGLRenderTarget, - }, + isWebGLRenderTarget: true, - setFromSphericalCoords: function ( radius, phi, theta ) { + setSize: function ( width, height ) { - var sinPhiRadius = Math.sin( phi ) * radius; + if ( this.width !== width || this.height !== height ) { - this.x = sinPhiRadius * Math.sin( theta ); - this.y = Math.cos( phi ) * radius; - this.z = sinPhiRadius * Math.cos( theta ); + this.width = width; + this.height = height; - return this; + this.texture.image.width = width; + this.texture.image.height = height; - }, + this.dispose(); - setFromCylindrical: function ( c ) { + } - return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); + this.viewport.set( 0, 0, width, height ); + this.scissor.set( 0, 0, width, height ); }, - setFromCylindricalCoords: function ( radius, theta, y ) { - - this.x = radius * Math.sin( theta ); - this.y = y; - this.z = radius * Math.cos( theta ); + clone: function () { - return this; + return new this.constructor().copy( this ); }, - setFromMatrixPosition: function ( m ) { - - var e = m.elements; - - this.x = e[ 12 ]; - this.y = e[ 13 ]; - this.z = e[ 14 ]; - - return this; + copy: function ( source ) { - }, + this.width = source.width; + this.height = source.height; - setFromMatrixScale: function ( m ) { + this.viewport.copy( source.viewport ); - var sx = this.setFromMatrixColumn( m, 0 ).length(); - var sy = this.setFromMatrixColumn( m, 1 ).length(); - var sz = this.setFromMatrixColumn( m, 2 ).length(); + this.texture = source.texture.clone(); - this.x = sx; - this.y = sy; - this.z = sz; + this.depthBuffer = source.depthBuffer; + this.stencilBuffer = source.stencilBuffer; + this.depthTexture = source.depthTexture; return this; }, - setFromMatrixColumn: function ( m, index ) { - - return this.fromArray( m.elements, index * 4 ); - - }, - - equals: function ( v ) { - - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); - - }, - - fromArray: function ( array, offset ) { + dispose: function () { - if ( offset === undefined ) offset = 0; + this.dispatchEvent( { type: 'dispose' } ); - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; + } - return this; + } ); - }, + /** + * @author Mugen87 / https://github.com/Mugen87 + * @author Matt DesLauriers / @mattdesl + */ - toArray: function ( array, offset ) { + function WebGLMultisampleRenderTarget( width, height, options ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + WebGLRenderTarget.call( this, width, height, options ); - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; + this.samples = 4; - return array; + } - }, + WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), { - fromBufferAttribute: function ( attribute, index, offset ) { + constructor: WebGLMultisampleRenderTarget, - if ( offset !== undefined ) { + isWebGLMultisampleRenderTarget: true, - console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); + copy: function ( source ) { - } + WebGLRenderTarget.prototype.copy.call( this, source ); - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); + this.samples = source.samples; return this; @@ -2314,820 +2593,666 @@ } ); /** + * @author mikael emtinger / http://gomo.se/ * @author alteredq / http://alteredqualia.com/ * @author WestLangley / http://github.com/WestLangley * @author bhouston / http://clara.io - * @author tschw */ - var _vector$1 = new Vector3(); + function Quaternion( x, y, z, w ) { - function Matrix3() { + this._x = x || 0; + this._y = y || 0; + this._z = z || 0; + this._w = ( w !== undefined ) ? w : 1; - this.elements = [ + } - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 + Object.assign( Quaternion, { - ]; + slerp: function ( qa, qb, qm, t ) { - if ( arguments.length > 0 ) { + return qm.copy( qa ).slerp( qb, t ); - console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); + }, - } + slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { - } + // fuzz-free, array-based Quaternion SLERP operation - Object.assign( Matrix3.prototype, { + var x0 = src0[ srcOffset0 + 0 ], + y0 = src0[ srcOffset0 + 1 ], + z0 = src0[ srcOffset0 + 2 ], + w0 = src0[ srcOffset0 + 3 ], - isMatrix3: true, + x1 = src1[ srcOffset1 + 0 ], + y1 = src1[ srcOffset1 + 1 ], + z1 = src1[ srcOffset1 + 2 ], + w1 = src1[ srcOffset1 + 3 ]; - set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { + if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { - var te = this.elements; + var s = 1 - t, - te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; - te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; - te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; + cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, - return this; + dir = ( cos >= 0 ? 1 : - 1 ), + sqrSin = 1 - cos * cos; - }, + // Skip the Slerp for tiny steps to avoid numeric problems: + if ( sqrSin > Number.EPSILON ) { - identity: function () { + var sin = Math.sqrt( sqrSin ), + len = Math.atan2( sin, cos * dir ); - this.set( + s = Math.sin( s * len ) / sin; + t = Math.sin( t * len ) / sin; - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 + } - ); + var tDir = t * dir; - return this; + x0 = x0 * s + x1 * tDir; + y0 = y0 * s + y1 * tDir; + z0 = z0 * s + z1 * tDir; + w0 = w0 * s + w1 * tDir; - }, + // Normalize in case we just did a lerp: + if ( s === 1 - t ) { - clone: function () { + var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); - return new this.constructor().fromArray( this.elements ); + x0 *= f; + y0 *= f; + z0 *= f; + w0 *= f; - }, + } - copy: function ( m ) { + } - var te = this.elements; - var me = m.elements; + dst[ dstOffset ] = x0; + dst[ dstOffset + 1 ] = y0; + dst[ dstOffset + 2 ] = z0; + dst[ dstOffset + 3 ] = w0; - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; - te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; - te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; + } - return this; + } ); - }, + Object.defineProperties( Quaternion.prototype, { - setFromMatrix4: function ( m ) { + x: { - var me = m.elements; + get: function () { - this.set( + return this._x; - me[ 0 ], me[ 4 ], me[ 8 ], - me[ 1 ], me[ 5 ], me[ 9 ], - me[ 2 ], me[ 6 ], me[ 10 ] + }, - ); + set: function ( value ) { - return this; + this._x = value; + this._onChangeCallback(); + + } }, - applyToBufferAttribute: function ( attribute ) { + y: { - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + get: function () { - _vector$1.x = attribute.getX( i ); - _vector$1.y = attribute.getY( i ); - _vector$1.z = attribute.getZ( i ); + return this._y; - _vector$1.applyMatrix3( this ); + }, - attribute.setXYZ( i, _vector$1.x, _vector$1.y, _vector$1.z ); + set: function ( value ) { - } + this._y = value; + this._onChangeCallback(); - return attribute; + } }, - multiply: function ( m ) { + z: { - return this.multiplyMatrices( this, m ); + get: function () { - }, + return this._z; - premultiply: function ( m ) { + }, - return this.multiplyMatrices( m, this ); + set: function ( value ) { + + this._z = value; + this._onChangeCallback(); + + } }, - multiplyMatrices: function ( a, b ) { + w: { - var ae = a.elements; - var be = b.elements; - var te = this.elements; + get: function () { - var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; - var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; - var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; + return this._w; - var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; - var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; - var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; + }, - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; - te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; - te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; + set: function ( value ) { - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; - te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; - te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; + this._w = value; + this._onChangeCallback(); - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; - te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; - te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; + } - return this; + } - }, + } ); - multiplyScalar: function ( s ) { + Object.assign( Quaternion.prototype, { - var te = this.elements; + isQuaternion: true, - te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; - te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; - te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; + set: function ( x, y, z, w ) { + + this._x = x; + this._y = y; + this._z = z; + this._w = w; + + this._onChangeCallback(); return this; }, - determinant: function () { + clone: function () { - var te = this.elements; + return new this.constructor( this._x, this._y, this._z, this._w ); - var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], - d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], - g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; + }, - return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; + copy: function ( quaternion ) { - }, + this._x = quaternion.x; + this._y = quaternion.y; + this._z = quaternion.z; + this._w = quaternion.w; - getInverse: function ( matrix, throwOnDegenerate ) { + this._onChangeCallback(); - if ( matrix && matrix.isMatrix4 ) { + return this; - console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." ); + }, - } + setFromEuler: function ( euler, update ) { - var me = matrix.elements, - te = this.elements, + if ( ! ( euler && euler.isEuler ) ) { - n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], - n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], - n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], + throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, + } - det = n11 * t11 + n21 * t12 + n31 * t13; + var x = euler._x, y = euler._y, z = euler._z, order = euler.order; - if ( det === 0 ) { + // http://www.mathworks.com/matlabcentral/fileexchange/ + // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ + // content/SpinCalc.m - var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"; + var cos = Math.cos; + var sin = Math.sin; - if ( throwOnDegenerate === true ) { + var c1 = cos( x / 2 ); + var c2 = cos( y / 2 ); + var c3 = cos( z / 2 ); - throw new Error( msg ); + var s1 = sin( x / 2 ); + var s2 = sin( y / 2 ); + var s3 = sin( z / 2 ); - } else { + if ( order === 'XYZ' ) { - console.warn( msg ); + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - } + } else if ( order === 'YXZ' ) { - return this.identity(); + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - } + } else if ( order === 'ZXY' ) { - var detInv = 1 / det; + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - te[ 0 ] = t11 * detInv; - te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; - te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; + } else if ( order === 'ZYX' ) { - te[ 3 ] = t12 * detInv; - te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; - te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - te[ 6 ] = t13 * detInv; - te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; - te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; + } else if ( order === 'YZX' ) { - return this; + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - }, + } else if ( order === 'XZY' ) { - transpose: function () { + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - var tmp, m = this.elements; + } - tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; - tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; - tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; + if ( update !== false ) { this._onChangeCallback(); } return this; }, - getNormalMatrix: function ( matrix4 ) { + setFromAxisAngle: function ( axis, angle ) { - return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm - }, + // assumes axis is normalized - transposeIntoArray: function ( r ) { + var halfAngle = angle / 2, s = Math.sin( halfAngle ); - var m = this.elements; + this._x = axis.x * s; + this._y = axis.y * s; + this._z = axis.z * s; + this._w = Math.cos( halfAngle ); - r[ 0 ] = m[ 0 ]; - r[ 1 ] = m[ 3 ]; - r[ 2 ] = m[ 6 ]; - r[ 3 ] = m[ 1 ]; - r[ 4 ] = m[ 4 ]; - r[ 5 ] = m[ 7 ]; - r[ 6 ] = m[ 2 ]; - r[ 7 ] = m[ 5 ]; - r[ 8 ] = m[ 8 ]; + this._onChangeCallback(); return this; }, - setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { + setFromRotationMatrix: function ( m ) { - var c = Math.cos( rotation ); - var s = Math.sin( rotation ); + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - this.set( - sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, - - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, - 0, 0, 1 - ); + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - }, + var te = m.elements, - scale: function ( sx, sy ) { + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], - var te = this.elements; + trace = m11 + m22 + m33, + s; - te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; - te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; + if ( trace > 0 ) { - return this; + s = 0.5 / Math.sqrt( trace + 1.0 ); - }, + this._w = 0.25 / s; + this._x = ( m32 - m23 ) * s; + this._y = ( m13 - m31 ) * s; + this._z = ( m21 - m12 ) * s; - rotate: function ( theta ) { + } else if ( m11 > m22 && m11 > m33 ) { - var c = Math.cos( theta ); - var s = Math.sin( theta ); + s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); - var te = this.elements; + this._w = ( m32 - m23 ) / s; + this._x = 0.25 * s; + this._y = ( m12 + m21 ) / s; + this._z = ( m13 + m31 ) / s; - var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; - var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; + } else if ( m22 > m33 ) { - te[ 0 ] = c * a11 + s * a21; - te[ 3 ] = c * a12 + s * a22; - te[ 6 ] = c * a13 + s * a23; + s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); - te[ 1 ] = - s * a11 + c * a21; - te[ 4 ] = - s * a12 + c * a22; - te[ 7 ] = - s * a13 + c * a23; + this._w = ( m13 - m31 ) / s; + this._x = ( m12 + m21 ) / s; + this._y = 0.25 * s; + this._z = ( m23 + m32 ) / s; - return this; + } else { - }, + s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); - translate: function ( tx, ty ) { + this._w = ( m21 - m12 ) / s; + this._x = ( m13 + m31 ) / s; + this._y = ( m23 + m32 ) / s; + this._z = 0.25 * s; - var te = this.elements; + } - te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; - te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; + this._onChangeCallback(); return this; }, - equals: function ( matrix ) { + setFromUnitVectors: function ( vFrom, vTo ) { - var te = this.elements; - var me = matrix.elements; + // assumes direction vectors vFrom and vTo are normalized - for ( var i = 0; i < 9; i ++ ) { - - if ( te[ i ] !== me[ i ] ) return false; - - } - - return true; - - }, - - fromArray: function ( array, offset ) { - - if ( offset === undefined ) offset = 0; - - for ( var i = 0; i < 9; i ++ ) { - - this.elements[ i ] = array[ i + offset ]; - - } - - return this; - - }, - - toArray: function ( array, offset ) { - - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; - - var te = this.elements; - - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - - array[ offset + 3 ] = te[ 3 ]; - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; - array[ offset + 8 ] = te[ 8 ]; - - return array; - - } - - } ); - - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ - - var _canvas; - - var ImageUtils = { - - getDataURL: function ( image ) { - - var canvas; - - if ( typeof HTMLCanvasElement == 'undefined' ) { - - return image.src; - - } else if ( image instanceof HTMLCanvasElement ) { - - canvas = image; - - } else { + var EPS = 0.000001; - if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); + var r = vFrom.dot( vTo ) + 1; - _canvas.width = image.width; - _canvas.height = image.height; + if ( r < EPS ) { - var context = _canvas.getContext( '2d' ); + r = 0; - if ( image instanceof ImageData ) { + if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { - context.putImageData( image, 0, 0 ); + this._x = - vFrom.y; + this._y = vFrom.x; + this._z = 0; + this._w = r; } else { - context.drawImage( image, 0, 0, image.width, image.height ); + this._x = 0; + this._y = - vFrom.z; + this._z = vFrom.y; + this._w = r; } - canvas = _canvas; - - } - - if ( canvas.width > 2048 || canvas.height > 2048 ) { - - return canvas.toDataURL( 'image/jpeg', 0.6 ); - } else { - return canvas.toDataURL( 'image/png' ); + // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + + this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; + this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; + this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; + this._w = r; } - } + return this.normalize(); - }; + }, - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ + angleTo: function ( q ) { - var textureId = 0; + return 2 * Math.acos( Math.abs( MathUtils.clamp( this.dot( q ), - 1, 1 ) ) ); - function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + }, - Object.defineProperty( this, 'id', { value: textureId ++ } ); + rotateTowards: function ( q, step ) { - this.uuid = _Math.generateUUID(); + var angle = this.angleTo( q ); - this.name = ''; + if ( angle === 0 ) { return this; } - this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; - this.mipmaps = []; + var t = Math.min( 1, step / angle ); - this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; + this.slerp( q, t ); - this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; - this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; + return this; - this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; - this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter; + }, - this.anisotropy = anisotropy !== undefined ? anisotropy : 1; + inverse: function () { - this.format = format !== undefined ? format : RGBAFormat; - this.type = type !== undefined ? type : UnsignedByteType; + // quaternion is assumed to have unit length - this.offset = new Vector2( 0, 0 ); - this.repeat = new Vector2( 1, 1 ); - this.center = new Vector2( 0, 0 ); - this.rotation = 0; + return this.conjugate(); - this.matrixAutoUpdate = true; - this.matrix = new Matrix3(); + }, - this.generateMipmaps = true; - this.premultiplyAlpha = false; - this.flipY = true; - this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + conjugate: function () { - // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. - // - // Also changing the encoding after already used by a Material will not automatically make the Material - // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. - this.encoding = encoding !== undefined ? encoding : LinearEncoding; + this._x *= - 1; + this._y *= - 1; + this._z *= - 1; - this.version = 0; - this.onUpdate = null; + this._onChangeCallback(); - } + return this; - Texture.DEFAULT_IMAGE = undefined; - Texture.DEFAULT_MAPPING = UVMapping; + }, - Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + dot: function ( v ) { - constructor: Texture, + return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; - isTexture: true, + }, - updateMatrix: function () { + lengthSq: function () { - this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); + return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; }, - clone: function () { + length: function () { - return new this.constructor().copy( this ); + return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); }, - copy: function ( source ) { - - this.name = source.name; - - this.image = source.image; - this.mipmaps = source.mipmaps.slice( 0 ); + normalize: function () { - this.mapping = source.mapping; + var l = this.length(); - this.wrapS = source.wrapS; - this.wrapT = source.wrapT; + if ( l === 0 ) { - this.magFilter = source.magFilter; - this.minFilter = source.minFilter; + this._x = 0; + this._y = 0; + this._z = 0; + this._w = 1; - this.anisotropy = source.anisotropy; + } else { - this.format = source.format; - this.type = source.type; + l = 1 / l; - this.offset.copy( source.offset ); - this.repeat.copy( source.repeat ); - this.center.copy( source.center ); - this.rotation = source.rotation; + this._x = this._x * l; + this._y = this._y * l; + this._z = this._z * l; + this._w = this._w * l; - this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrix.copy( source.matrix ); + } - this.generateMipmaps = source.generateMipmaps; - this.premultiplyAlpha = source.premultiplyAlpha; - this.flipY = source.flipY; - this.unpackAlignment = source.unpackAlignment; - this.encoding = source.encoding; + this._onChangeCallback(); return this; }, - toJSON: function ( meta ) { - - var isRootObject = ( meta === undefined || typeof meta === 'string' ); + multiply: function ( q, p ) { - if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { + if ( p !== undefined ) { - return meta.textures[ this.uuid ]; + console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); + return this.multiplyQuaternions( q, p ); } - var output = { + return this.multiplyQuaternions( this, q ); - metadata: { - version: 4.5, - type: 'Texture', - generator: 'Texture.toJSON' - }, + }, - uuid: this.uuid, - name: this.name, + premultiply: function ( q ) { - mapping: this.mapping, + return this.multiplyQuaternions( q, this ); - repeat: [ this.repeat.x, this.repeat.y ], - offset: [ this.offset.x, this.offset.y ], - center: [ this.center.x, this.center.y ], - rotation: this.rotation, + }, - wrap: [ this.wrapS, this.wrapT ], + multiplyQuaternions: function ( a, b ) { - format: this.format, - type: this.type, - encoding: this.encoding, + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm - minFilter: this.minFilter, - magFilter: this.magFilter, - anisotropy: this.anisotropy, + var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; + var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; - flipY: this.flipY, + this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - premultiplyAlpha: this.premultiplyAlpha, - unpackAlignment: this.unpackAlignment + this._onChangeCallback(); - }; + return this; - if ( this.image !== undefined ) { + }, - // TODO: Move to THREE.Image + slerp: function ( qb, t ) { - var image = this.image; + if ( t === 0 ) { return this; } + if ( t === 1 ) { return this.copy( qb ); } - if ( image.uuid === undefined ) { + var x = this._x, y = this._y, z = this._z, w = this._w; - image.uuid = _Math.generateUUID(); // UGH + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ - } + var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; - if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { + if ( cosHalfTheta < 0 ) { - var url; + this._w = - qb._w; + this._x = - qb._x; + this._y = - qb._y; + this._z = - qb._z; - if ( Array.isArray( image ) ) { + cosHalfTheta = - cosHalfTheta; - // process array of images e.g. CubeTexture + } else { - url = []; + this.copy( qb ); - for ( var i = 0, l = image.length; i < l; i ++ ) { + } - url.push( ImageUtils.getDataURL( image[ i ] ) ); + if ( cosHalfTheta >= 1.0 ) { - } + this._w = w; + this._x = x; + this._y = y; + this._z = z; - } else { + return this; - // process single image + } - url = ImageUtils.getDataURL( image ); + var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - } + if ( sqrSinHalfTheta <= Number.EPSILON ) { - meta.images[ image.uuid ] = { - uuid: image.uuid, - url: url - }; + var s = 1 - t; + this._w = s * w + t * this._w; + this._x = s * x + t * this._x; + this._y = s * y + t * this._y; + this._z = s * z + t * this._z; - } + this.normalize(); + this._onChangeCallback(); - output.image = image.uuid; + return this; } - if ( ! isRootObject ) { + var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); + var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); + var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, + ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; - meta.textures[ this.uuid ] = output; + this._w = ( w * ratioA + this._w * ratioB ); + this._x = ( x * ratioA + this._x * ratioB ); + this._y = ( y * ratioA + this._y * ratioB ); + this._z = ( z * ratioA + this._z * ratioB ); - } + this._onChangeCallback(); - return output; + return this; }, - dispose: function () { + equals: function ( quaternion ) { - this.dispatchEvent( { type: 'dispose' } ); + return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); }, - transformUv: function ( uv ) { - - if ( this.mapping !== UVMapping ) return uv; - - uv.applyMatrix3( this.matrix ); - - if ( uv.x < 0 || uv.x > 1 ) { - - switch ( this.wrapS ) { - - case RepeatWrapping: - - uv.x = uv.x - Math.floor( uv.x ); - break; - - case ClampToEdgeWrapping: - - uv.x = uv.x < 0 ? 0 : 1; - break; - - case MirroredRepeatWrapping: - - if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { - - uv.x = Math.ceil( uv.x ) - uv.x; - - } else { - - uv.x = uv.x - Math.floor( uv.x ); - - } - break; - - } - - } - - if ( uv.y < 0 || uv.y > 1 ) { - - switch ( this.wrapT ) { - - case RepeatWrapping: - - uv.y = uv.y - Math.floor( uv.y ); - break; - - case ClampToEdgeWrapping: - - uv.y = uv.y < 0 ? 0 : 1; - break; - - case MirroredRepeatWrapping: - - if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { - - uv.y = Math.ceil( uv.y ) - uv.y; + fromArray: function ( array, offset ) { - } else { + if ( offset === undefined ) { offset = 0; } - uv.y = uv.y - Math.floor( uv.y ); + this._x = array[ offset ]; + this._y = array[ offset + 1 ]; + this._z = array[ offset + 2 ]; + this._w = array[ offset + 3 ]; - } - break; + this._onChangeCallback(); - } + return this; - } + }, - if ( this.flipY ) { + toArray: function ( array, offset ) { - uv.y = 1 - uv.y; + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } - } + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._w; - return uv; + return array; - } + }, - } ); + _onChange: function ( callback ) { - Object.defineProperty( Texture.prototype, "needsUpdate", { + this._onChangeCallback = callback; - set: function ( value ) { + return this; - if ( value === true ) this.version ++; + }, - } + _onChangeCallback: function () {} } ); /** - * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author mrdoob / http://mrdoob.com/ + * @author kile / http://kile.stravaganza.org/ * @author philogb / http://blog.thejit.org/ * @author mikael emtinger / http://gomo.se/ * @author egraether / http://egraether.com/ * @author WestLangley / http://github.com/WestLangley */ - function Vector4( x, y, z, w ) { + var _vector = new Vector3(); + var _quaternion = new Quaternion(); + + function Vector3( x, y, z ) { this.x = x || 0; this.y = y || 0; this.z = z || 0; - this.w = ( w !== undefined ) ? w : 1; } - Object.defineProperties( Vector4.prototype, { - - "width": { - - get: function () { - - return this.z; - - }, - - set: function ( value ) { - - this.z = value; - - } - - }, - - "height": { - - get: function () { - - return this.w; - - }, - - set: function ( value ) { - - this.w = value; - - } - - } - - } ); - - Object.assign( Vector4.prototype, { + Object.assign( Vector3.prototype, { - isVector4: true, + isVector3: true, - set: function ( x, y, z, w ) { + set: function ( x, y, z ) { this.x = x; this.y = y; this.z = z; - this.w = w; return this; @@ -3138,7 +3263,6 @@ this.x = scalar; this.y = scalar; this.z = scalar; - this.w = scalar; return this; @@ -3168,14 +3292,6 @@ }, - setW: function ( w ) { - - this.w = w; - - return this; - - }, - setComponent: function ( index, value ) { switch ( index ) { @@ -3183,7 +3299,6 @@ case 0: this.x = value; break; case 1: this.y = value; break; case 2: this.z = value; break; - case 3: this.w = value; break; default: throw new Error( 'index is out of range: ' + index ); } @@ -3199,7 +3314,6 @@ case 0: return this.x; case 1: return this.y; case 2: return this.z; - case 3: return this.w; default: throw new Error( 'index is out of range: ' + index ); } @@ -3208,7 +3322,7 @@ clone: function () { - return new this.constructor( this.x, this.y, this.z, this.w ); + return new this.constructor( this.x, this.y, this.z ); }, @@ -3217,7 +3331,6 @@ this.x = v.x; this.y = v.y; this.z = v.z; - this.w = ( v.w !== undefined ) ? v.w : 1; return this; @@ -3227,7 +3340,7 @@ if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -3235,7 +3348,6 @@ this.x += v.x; this.y += v.y; this.z += v.z; - this.w += v.w; return this; @@ -3246,7 +3358,6 @@ this.x += s; this.y += s; this.z += s; - this.w += s; return this; @@ -3257,7 +3368,6 @@ this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; - this.w = a.w + b.w; return this; @@ -3268,7 +3378,6 @@ this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; - this.w += v.w * s; return this; @@ -3278,7 +3387,7 @@ if ( w !== undefined ) { - console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -3286,7 +3395,6 @@ this.x -= v.x; this.y -= v.y; this.z -= v.z; - this.w -= v.w; return this; @@ -3297,7 +3405,6 @@ this.x -= s; this.y -= s; this.z -= s; - this.w -= s; return this; @@ -3308,198 +3415,163 @@ this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; - this.w = a.w - b.w; return this; }, - multiplyScalar: function ( scalar ) { + multiply: function ( v, w ) { - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; - this.w *= scalar; + if ( w !== undefined ) { - return this; - - }, - - applyMatrix4: function ( m ) { + console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); + return this.multiplyVectors( v, w ); - var x = this.x, y = this.y, z = this.z, w = this.w; - var e = m.elements; + } - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; - this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; + this.x *= v.x; + this.y *= v.y; + this.z *= v.z; return this; }, - divideScalar: function ( scalar ) { - - return this.multiplyScalar( 1 / scalar ); + multiplyScalar: function ( scalar ) { - }, + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; - setAxisAngleFromQuaternion: function ( q ) { + return this; - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm + }, - // q is assumed to be normalized + multiplyVectors: function ( a, b ) { - this.w = 2 * Math.acos( q.w ); + this.x = a.x * b.x; + this.y = a.y * b.y; + this.z = a.z * b.z; - var s = Math.sqrt( 1 - q.w * q.w ); + return this; - if ( s < 0.0001 ) { + }, - this.x = 1; - this.y = 0; - this.z = 0; + applyEuler: function ( euler ) { - } else { + if ( ! ( euler && euler.isEuler ) ) { - this.x = q.x / s; - this.y = q.y / s; - this.z = q.z / s; + console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); } - return this; + return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); }, - setAxisAngleFromRotationMatrix: function ( m ) { - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - - var angle, x, y, z, // variables for result - epsilon = 0.01, // margin to allow for rounding errors - epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees - - te = m.elements, + applyAxisAngle: function ( axis, angle ) { - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); - if ( ( Math.abs( m12 - m21 ) < epsilon ) && - ( Math.abs( m13 - m31 ) < epsilon ) && - ( Math.abs( m23 - m32 ) < epsilon ) ) { + }, - // singularity found - // first check for identity matrix which must have +1 for all terms - // in leading diagonal and zero in other terms + applyMatrix3: function ( m ) { - if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && - ( Math.abs( m13 + m31 ) < epsilon2 ) && - ( Math.abs( m23 + m32 ) < epsilon2 ) && - ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - // this singularity is identity matrix so angle = 0 + this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; + this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; + this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; - this.set( 1, 0, 0, 0 ); + return this; - return this; // zero angle, arbitrary axis + }, - } + applyNormalMatrix: function ( m ) { - // otherwise this singularity is angle = 180 + return this.applyMatrix3( m ).normalize(); - angle = Math.PI; + }, - var xx = ( m11 + 1 ) / 2; - var yy = ( m22 + 1 ) / 2; - var zz = ( m33 + 1 ) / 2; - var xy = ( m12 + m21 ) / 4; - var xz = ( m13 + m31 ) / 4; - var yz = ( m23 + m32 ) / 4; + applyMatrix4: function ( m ) { - if ( ( xx > yy ) && ( xx > zz ) ) { + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - // m11 is the largest diagonal term + var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); - if ( xx < epsilon ) { + this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; + this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; + this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; - x = 0; - y = 0.707106781; - z = 0.707106781; + return this; - } else { + }, - x = Math.sqrt( xx ); - y = xy / x; - z = xz / x; + applyQuaternion: function ( q ) { - } + var x = this.x, y = this.y, z = this.z; + var qx = q.x, qy = q.y, qz = q.z, qw = q.w; - } else if ( yy > zz ) { + // calculate quat * vector - // m22 is the largest diagonal term + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = - qx * x - qy * y - qz * z; - if ( yy < epsilon ) { + // calculate result * inverse quat - x = 0.707106781; - y = 0; - z = 0.707106781; + this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; + this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; + this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; - } else { + return this; - y = Math.sqrt( yy ); - x = xy / y; - z = yz / y; + }, - } + project: function ( camera ) { - } else { + return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); - // m33 is the largest diagonal term so base result on this + }, - if ( zz < epsilon ) { + unproject: function ( camera ) { - x = 0.707106781; - y = 0.707106781; - z = 0; + return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); - } else { + }, - z = Math.sqrt( zz ); - x = xz / z; - y = yz / z; + transformDirection: function ( m ) { - } + // input: THREE.Matrix4 affine matrix + // vector interpreted as a direction - } + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - this.set( x, y, z, angle ); + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; - return this; // return 180 deg rotation + return this.normalize(); - } + }, - // as we have reached here there are no singularities so we can handle normally + divide: function ( v ) { - var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + - ( m13 - m31 ) * ( m13 - m31 ) + - ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize + this.x /= v.x; + this.y /= v.y; + this.z /= v.z; - if ( Math.abs( s ) < 0.001 ) s = 1; + return this; - // prevent divide by zero, should not happen if matrix is orthogonal and should be - // caught by singularity test above, but I've left it in just in case + }, - this.x = ( m32 - m23 ) / s; - this.y = ( m13 - m31 ) / s; - this.z = ( m21 - m12 ) / s; - this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + divideScalar: function ( scalar ) { - return this; + return this.multiplyScalar( 1 / scalar ); }, @@ -3508,7 +3580,6 @@ this.x = Math.min( this.x, v.x ); this.y = Math.min( this.y, v.y ); this.z = Math.min( this.z, v.z ); - this.w = Math.min( this.w, v.w ); return this; @@ -3519,7 +3590,6 @@ this.x = Math.max( this.x, v.x ); this.y = Math.max( this.y, v.y ); this.z = Math.max( this.z, v.z ); - this.w = Math.max( this.w, v.w ); return this; @@ -3532,7 +3602,6 @@ this.x = Math.max( min.x, Math.min( max.x, this.x ) ); this.y = Math.max( min.y, Math.min( max.y, this.y ) ); this.z = Math.max( min.z, Math.min( max.z, this.z ) ); - this.w = Math.max( min.w, Math.min( max.w, this.w ) ); return this; @@ -3543,7 +3612,6 @@ this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); - this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); return this; @@ -3562,7 +3630,6 @@ this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); return this; @@ -3573,7 +3640,6 @@ this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); return this; @@ -3584,7 +3650,6 @@ this.x = Math.round( this.x ); this.y = Math.round( this.y ); this.z = Math.round( this.z ); - this.w = Math.round( this.w ); return this; @@ -3595,7 +3660,6 @@ this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); return this; @@ -3606,7 +3670,6 @@ this.x = - this.x; this.y = - this.y; this.z = - this.z; - this.w = - this.w; return this; @@ -3614,25 +3677,27 @@ dot: function ( v ) { - return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + return this.x * v.x + this.y * v.y + this.z * v.z; }, + // TODO lengthSquared? + lengthSq: function () { - return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + return this.x * this.x + this.y * this.y + this.z * this.z; }, length: function () { - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); }, manhattanLength: function () { - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); }, @@ -3653,7 +3718,6 @@ this.x += ( v.x - this.x ) * alpha; this.y += ( v.y - this.y ) * alpha; this.z += ( v.z - this.z ) * alpha; - this.w += ( v.w - this.w ) * alpha; return this; @@ -3665,176 +3729,209 @@ }, - equals: function ( v ) { + cross: function ( v, w ) { - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); + if ( w !== undefined ) { + + console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); + return this.crossVectors( v, w ); + + } + + return this.crossVectors( this, v ); }, - fromArray: function ( array, offset ) { + crossVectors: function ( a, b ) { - if ( offset === undefined ) offset = 0; + var ax = a.x, ay = a.y, az = a.z; + var bx = b.x, by = b.y, bz = b.z; - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; - this.w = array[ offset + 3 ]; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; return this; }, - toArray: function ( array, offset ) { + projectOnVector: function ( v ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + var denominator = v.lengthSq(); - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; - array[ offset + 3 ] = this.w; + if ( denominator === 0 ) { return this.set( 0, 0, 0 ); } - return array; + var scalar = v.dot( this ) / denominator; + + return this.copy( v ).multiplyScalar( scalar ); }, - fromBufferAttribute: function ( attribute, index, offset ) { + projectOnPlane: function ( planeNormal ) { - if ( offset !== undefined ) { + _vector.copy( this ).projectOnVector( planeNormal ); - console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); + return this.sub( _vector ); - } + }, - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); - this.w = attribute.getW( index ); + reflect: function ( normal ) { - return this; + // reflect incident vector off plane orthogonal to normal + // normal is assumed to have unit length - } + return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); - } ); + }, - /** - * @author szimek / https://github.com/szimek/ - * @author alteredq / http://alteredqualia.com/ - * @author Marius Kintel / https://github.com/kintel - */ + angleTo: function ( v ) { - /* - In options, we can specify: - * Texture parameters for an auto-generated target texture - * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers - */ - function WebGLRenderTarget( width, height, options ) { + var denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); - this.width = width; - this.height = height; + if ( denominator === 0 ) { return Math.PI / 2; } - this.scissor = new Vector4( 0, 0, width, height ); - this.scissorTest = false; + var theta = this.dot( v ) / denominator; - this.viewport = new Vector4( 0, 0, width, height ); + // clamp, to handle numerical problems - options = options || {}; + return Math.acos( MathUtils.clamp( theta, - 1, 1 ) ); - this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); + }, - this.texture.image = {}; - this.texture.image.width = width; - this.texture.image.height = height; + distanceTo: function ( v ) { - this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; - this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; + return Math.sqrt( this.distanceToSquared( v ) ); - this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; - this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; - this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; + }, - } + distanceToSquared: function ( v ) { - WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; - constructor: WebGLRenderTarget, + return dx * dx + dy * dy + dz * dz; - isWebGLRenderTarget: true, + }, - setSize: function ( width, height ) { + manhattanDistanceTo: function ( v ) { - if ( this.width !== width || this.height !== height ) { + return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); - this.width = width; - this.height = height; + }, - this.texture.image.width = width; - this.texture.image.height = height; + setFromSpherical: function ( s ) { - this.dispose(); + return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); - } + }, - this.viewport.set( 0, 0, width, height ); - this.scissor.set( 0, 0, width, height ); + setFromSphericalCoords: function ( radius, phi, theta ) { + + var sinPhiRadius = Math.sin( phi ) * radius; + + this.x = sinPhiRadius * Math.sin( theta ); + this.y = Math.cos( phi ) * radius; + this.z = sinPhiRadius * Math.cos( theta ); + + return this; }, - clone: function () { + setFromCylindrical: function ( c ) { - return new this.constructor().copy( this ); + return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); }, - copy: function ( source ) { + setFromCylindricalCoords: function ( radius, theta, y ) { - this.width = source.width; - this.height = source.height; + this.x = radius * Math.sin( theta ); + this.y = y; + this.z = radius * Math.cos( theta ); - this.viewport.copy( source.viewport ); + return this; - this.texture = source.texture.clone(); + }, - this.depthBuffer = source.depthBuffer; - this.stencilBuffer = source.stencilBuffer; - this.depthTexture = source.depthTexture; + setFromMatrixPosition: function ( m ) { + + var e = m.elements; + + this.x = e[ 12 ]; + this.y = e[ 13 ]; + this.z = e[ 14 ]; return this; }, - dispose: function () { + setFromMatrixScale: function ( m ) { - this.dispatchEvent( { type: 'dispose' } ); + var sx = this.setFromMatrixColumn( m, 0 ).length(); + var sy = this.setFromMatrixColumn( m, 1 ).length(); + var sz = this.setFromMatrixColumn( m, 2 ).length(); - } + this.x = sx; + this.y = sy; + this.z = sz; - } ); + return this; - /** - * @author Mugen87 / https://github.com/Mugen87 - * @author Matt DesLauriers / @mattdesl - */ + }, - function WebGLMultisampleRenderTarget( width, height, options ) { + setFromMatrixColumn: function ( m, index ) { - WebGLRenderTarget.call( this, width, height, options ); + return this.fromArray( m.elements, index * 4 ); - this.samples = 4; + }, - } + setFromMatrix3Column: function ( m, index ) { - WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), { + return this.fromArray( m.elements, index * 3 ); - constructor: WebGLMultisampleRenderTarget, + }, - isWebGLMultisampleRenderTarget: true, + equals: function ( v ) { - copy: function ( source ) { + return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); - WebGLRenderTarget.prototype.copy.call( this, source ); + }, - this.samples = source.samples; + fromArray: function ( array, offset ) { + + if ( offset === undefined ) { offset = 0; } + + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + + return this; + + }, + + toArray: function ( array, offset ) { + + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + + return array; + + }, + + fromBufferAttribute: function ( attribute, index, offset ) { + + if ( offset !== undefined ) { + + console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); + + } + + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); return this; @@ -4257,24 +4354,6 @@ }, - applyToBufferAttribute: function ( attribute ) { - - for ( var i = 0, l = attribute.count; i < l; i ++ ) { - - _v1.x = attribute.getX( i ); - _v1.y = attribute.getY( i ); - _v1.z = attribute.getZ( i ); - - _v1.applyMatrix4( this ); - - attribute.setXYZ( i, _v1.x, _v1.y, _v1.z ); - - } - - return attribute; - - }, - determinant: function () { var te = this.elements; @@ -4617,7 +4696,7 @@ // if determine is negative, we need to invert one scale var det = this.determinant(); - if ( det < 0 ) sx = - sx; + if ( det < 0 ) { sx = - sx; } position.x = te[ 12 ]; position.y = te[ 13 ]; @@ -4705,7 +4784,7 @@ for ( var i = 0; i < 16; i ++ ) { - if ( te[ i ] !== me[ i ] ) return false; + if ( te[ i ] !== me[ i ] ) { return false; } } @@ -4715,7 +4794,7 @@ fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) { offset = 0; } for ( var i = 0; i < 16; i ++ ) { @@ -4729,8 +4808,8 @@ toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } var te = this.elements; @@ -4892,7 +4971,7 @@ setFromRotationMatrix: function ( m, order, update ) { - var clamp = _Math.clamp; + var clamp = MathUtils.clamp; // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) @@ -5007,7 +5086,7 @@ this._order = order; - if ( update !== false ) this._onChangeCallback(); + if ( update !== false ) { this._onChangeCallback(); } return this; @@ -5048,7 +5127,7 @@ this._x = array[ 0 ]; this._y = array[ 1 ]; this._z = array[ 2 ]; - if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; + if ( array[ 3 ] !== undefined ) { this._order = array[ 3 ]; } this._onChangeCallback(); @@ -5058,8 +5137,8 @@ toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } array[ offset ] = this._x; array[ offset + 1 ] = this._y; @@ -5120,6 +5199,12 @@ }, + enableAll: function () { + + this.mask = 0xffffffff | 0; + + }, + toggle: function ( channel ) { this.mask ^= 1 << channel | 0; @@ -5132,6 +5217,12 @@ }, + disableAll: function () { + + this.mask = 0; + + }, + test: function ( layers ) { return ( this.mask & layers.mask ) !== 0; @@ -5170,7 +5261,7 @@ Object.defineProperty( this, 'id', { value: _object3DId ++ } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'Object3D'; @@ -5260,9 +5351,9 @@ onBeforeRender: function () {}, onAfterRender: function () {}, - applyMatrix: function ( matrix ) { + applyMatrix4: function ( matrix ) { - if ( this.matrixAutoUpdate ) this.updateMatrix(); + if ( this.matrixAutoUpdate ) { this.updateMatrix(); } this.matrix.premultiply( matrix ); @@ -5527,7 +5618,7 @@ } - object.applyMatrix( _m1$1 ); + object.applyMatrix4( _m1$1 ); object.updateWorldMatrix( false, false ); @@ -5551,7 +5642,7 @@ getObjectByProperty: function ( name, value ) { - if ( this[ name ] === value ) return this; + if ( this[ name ] === value ) { return this; } for ( var i = 0, l = this.children.length; i < l; i ++ ) { @@ -5654,7 +5745,7 @@ traverseVisible: function ( callback ) { - if ( this.visible === false ) return; + if ( this.visible === false ) { return; } callback( this ); @@ -5692,7 +5783,7 @@ updateMatrixWorld: function ( force ) { - if ( this.matrixAutoUpdate ) this.updateMatrix(); + if ( this.matrixAutoUpdate ) { this.updateMatrix(); } if ( this.matrixWorldNeedsUpdate || force ) { @@ -5734,7 +5825,7 @@ } - if ( this.matrixAutoUpdate ) this.updateMatrix(); + if ( this.matrixAutoUpdate ) { this.updateMatrix(); } if ( this.parent === null ) { @@ -5798,22 +5889,28 @@ object.uuid = this.uuid; object.type = this.type; - if ( this.name !== '' ) object.name = this.name; - if ( this.castShadow === true ) object.castShadow = true; - if ( this.receiveShadow === true ) object.receiveShadow = true; - if ( this.visible === false ) object.visible = false; - if ( this.frustumCulled === false ) object.frustumCulled = false; - if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; - if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; + if ( this.name !== '' ) { object.name = this.name; } + if ( this.castShadow === true ) { object.castShadow = true; } + if ( this.receiveShadow === true ) { object.receiveShadow = true; } + if ( this.visible === false ) { object.visible = false; } + if ( this.frustumCulled === false ) { object.frustumCulled = false; } + if ( this.renderOrder !== 0 ) { object.renderOrder = this.renderOrder; } + if ( JSON.stringify( this.userData ) !== '{}' ) { object.userData = this.userData; } object.layers = this.layers.mask; object.matrix = this.matrix.toArray(); - if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; + if ( this.matrixAutoUpdate === false ) { object.matrixAutoUpdate = false; } // object specific properties - if ( this.isMesh && this.drawMode !== TrianglesDrawMode ) object.drawMode = this.drawMode; + if ( this.isInstancedMesh ) { + + object.type = 'InstancedMesh'; + object.count = this.count; + object.instanceMatrix = this.instanceMatrix.toJSON(); + + } // @@ -5903,11 +6000,11 @@ var images = extractFromCache( meta.images ); var shapes = extractFromCache( meta.shapes ); - if ( geometries.length > 0 ) output.geometries = geometries; - if ( materials.length > 0 ) output.materials = materials; - if ( textures.length > 0 ) output.textures = textures; - if ( images.length > 0 ) output.images = images; - if ( shapes.length > 0 ) output.shapes = shapes; + if ( geometries.length > 0 ) { output.geometries = geometries; } + if ( materials.length > 0 ) { output.materials = materials; } + if ( textures.length > 0 ) { output.textures = textures; } + if ( images.length > 0 ) { output.images = images; } + if ( shapes.length > 0 ) { output.shapes = shapes; } } @@ -5942,7 +6039,7 @@ copy: function ( source, recursive ) { - if ( recursive === undefined ) recursive = true; + if ( recursive === undefined ) { recursive = true; } this.name = source.name; @@ -5997,7 +6094,9 @@ this.type = 'Scene'; this.background = null; + this.environment = null; this.fog = null; + this.overrideMaterial = null; this.autoUpdate = true; // checked by the renderer @@ -6020,9 +6119,11 @@ Object3D.prototype.copy.call( this, source, recursive ); - if ( source.background !== null ) this.background = source.background.clone(); - if ( source.fog !== null ) this.fog = source.fog.clone(); - if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); + if ( source.background !== null ) { this.background = source.background.clone(); } + if ( source.environment !== null ) { this.environment = source.environment.clone(); } + if ( source.fog !== null ) { this.fog = source.fog.clone(); } + + if ( source.overrideMaterial !== null ) { this.overrideMaterial = source.overrideMaterial.clone(); } this.autoUpdate = source.autoUpdate; this.matrixAutoUpdate = source.matrixAutoUpdate; @@ -6035,8 +6136,9 @@ var data = Object3D.prototype.toJSON.call( this, meta ); - if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); - if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); + if ( this.background !== null ) { data.object.background = this.background.toJSON( meta ); } + if ( this.environment !== null ) { data.object.environment = this.environment.toJSON( meta ); } + if ( this.fog !== null ) { data.object.fog = this.fog.toJSON(); } return data; @@ -6060,7 +6162,10 @@ new Vector3(), new Vector3() ]; - var _vector$2 = new Vector3(); + + var _vector$1 = new Vector3(); + + var _box = new Box3(); // triangle centered vertices @@ -6091,6 +6196,7 @@ } + Object.assign( Box3.prototype, { isBox3: true, @@ -6120,13 +6226,13 @@ var y = array[ i + 1 ]; var z = array[ i + 2 ]; - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( z < minZ ) minZ = z; + if ( x < minX ) { minX = x; } + if ( y < minY ) { minY = y; } + if ( z < minZ ) { minZ = z; } - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; - if ( z > maxZ ) maxZ = z; + if ( x > maxX ) { maxX = x; } + if ( y > maxY ) { maxY = y; } + if ( z > maxZ ) { maxZ = z; } } @@ -6153,13 +6259,13 @@ var y = attribute.getY( i ); var z = attribute.getZ( i ); - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( z < minZ ) minZ = z; + if ( x < minX ) { minX = x; } + if ( y < minY ) { minY = y; } + if ( z < minZ ) { minZ = z; } - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; - if ( z > maxZ ) maxZ = z; + if ( x > maxX ) { maxX = x; } + if ( y > maxY ) { maxY = y; } + if ( z > maxZ ) { maxZ = z; } } @@ -6186,7 +6292,7 @@ setFromCenterAndSize: function ( center, size ) { - var halfSize = _vector$2.copy( size ).multiplyScalar( 0.5 ); + var halfSize = _vector$1.copy( size ).multiplyScalar( 0.5 ); this.min.copy( center ).sub( halfSize ); this.max.copy( center ).add( halfSize ); @@ -6290,8 +6396,6 @@ expandByObject: function ( object ) { - var i, l; - // Computes the world-axis-aligned bounding box of an object (including its children), // accounting for both the object's, and children's, world transforms @@ -6301,44 +6405,22 @@ if ( geometry !== undefined ) { - if ( geometry.isGeometry ) { - - var vertices = geometry.vertices; + if ( geometry.boundingBox === null ) { - for ( i = 0, l = vertices.length; i < l; i ++ ) { + geometry.computeBoundingBox(); - _vector$2.copy( vertices[ i ] ); - _vector$2.applyMatrix4( object.matrixWorld ); - - this.expandByPoint( _vector$2 ); - - } - - } else if ( geometry.isBufferGeometry ) { - - var attribute = geometry.attributes.position; - - if ( attribute !== undefined ) { - - for ( i = 0, l = attribute.count; i < l; i ++ ) { - - _vector$2.fromBufferAttribute( attribute, i ).applyMatrix4( object.matrixWorld ); - - this.expandByPoint( _vector$2 ); + } - } + _box.copy( geometry.boundingBox ); + _box.applyMatrix4( object.matrixWorld ); - } - - } + this.union( _box ); } - // - var children = object.children; - for ( i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { this.expandByObject( children[ i ] ); @@ -6396,10 +6478,10 @@ intersectsSphere: function ( sphere ) { // Find the point on the AABB closest to the sphere center. - this.clampPoint( sphere.center, _vector$2 ); + this.clampPoint( sphere.center, _vector$1 ); // If that point is inside the sphere, the AABB and sphere intersect. - return _vector$2.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); + return _vector$1.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); }, @@ -6518,7 +6600,7 @@ distanceToPoint: function ( point ) { - var clampedPoint = _vector$2.copy( point ).clamp( this.min, this.max ); + var clampedPoint = _vector$1.copy( point ).clamp( this.min, this.max ); return clampedPoint.sub( point ).length(); @@ -6535,7 +6617,7 @@ this.getCenter( target.center ); - target.radius = this.getSize( _vector$2 ).length() * 0.5; + target.radius = this.getSize( _vector$1 ).length() * 0.5; return target; @@ -6547,7 +6629,7 @@ this.max.min( box.max ); // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. - if ( this.isEmpty() ) this.makeEmpty(); + if ( this.isEmpty() ) { this.makeEmpty(); } return this; @@ -6565,7 +6647,7 @@ applyMatrix4: function ( matrix ) { // transform of empty box is an empty box. - if ( this.isEmpty() ) return this; + if ( this.isEmpty() ) { return this; } // NOTE: I am using a binary pattern to specify all 2^3 combinations below _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 @@ -6628,7 +6710,7 @@ } - var _box = new Box3(); + var _box$1 = new Box3(); /** * @author bhouston / http://clara.io @@ -6663,7 +6745,7 @@ } else { - _box.setFromPoints( points ).getCenter( center ); + _box$1.setFromPoints( points ).getCenter( center ); } @@ -6799,7 +6881,7 @@ } ); - var _vector$3 = new Vector3(); + var _vector$2 = new Vector3(); var _segCenter = new Vector3(); var _segDir = new Vector3(); var _diff = new Vector3(); @@ -6815,7 +6897,7 @@ function Ray( origin, direction ) { this.origin = ( origin !== undefined ) ? origin : new Vector3(); - this.direction = ( direction !== undefined ) ? direction : new Vector3(); + this.direction = ( direction !== undefined ) ? direction : new Vector3( 0, 0, - 1 ); } @@ -6868,7 +6950,7 @@ recast: function ( t ) { - this.origin.copy( this.at( t, _vector$3 ) ); + this.origin.copy( this.at( t, _vector$2 ) ); return this; @@ -6905,7 +6987,7 @@ distanceSqToPoint: function ( point ) { - var directionDistance = _vector$3.subVectors( point, this.origin ).dot( this.direction ); + var directionDistance = _vector$2.subVectors( point, this.origin ).dot( this.direction ); // point behind the ray @@ -6915,9 +6997,9 @@ } - _vector$3.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + _vector$2.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - return _vector$3.distanceToSquared( point ); + return _vector$2.distanceToSquared( point ); }, @@ -7042,12 +7124,12 @@ intersectSphere: function ( sphere, target ) { - _vector$3.subVectors( sphere.center, this.origin ); - var tca = _vector$3.dot( this.direction ); - var d2 = _vector$3.dot( _vector$3 ) - tca * tca; + _vector$2.subVectors( sphere.center, this.origin ); + var tca = _vector$2.dot( this.direction ); + var d2 = _vector$2.dot( _vector$2 ) - tca * tca; var radius2 = sphere.radius * sphere.radius; - if ( d2 > radius2 ) return null; + if ( d2 > radius2 ) { return null; } var thc = Math.sqrt( radius2 - d2 ); @@ -7058,12 +7140,12 @@ var t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null - if ( t0 < 0 && t1 < 0 ) return null; + if ( t0 < 0 && t1 < 0 ) { return null; } // test to see if t0 is behind the ray: // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, // in order to always return an intersect point that is in front of the ray. - if ( t0 < 0 ) return this.at( t1, target ); + if ( t0 < 0 ) { return this.at( t1, target ); } // else t0 is in front of the ray, so return the first collision point scaled by t0 return this.at( t0, target ); @@ -7177,14 +7259,14 @@ } - if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + if ( ( tmin > tymax ) || ( tymin > tmax ) ) { return null; } // These lines also handle the case where tmin or tmax is NaN // (result of 0 * Infinity). x !== x returns true if x is NaN - if ( tymin > tmin || tmin !== tmin ) tmin = tymin; + if ( tymin > tmin || tmin !== tmin ) { tmin = tymin; } - if ( tymax < tmax || tmax !== tmax ) tmax = tymax; + if ( tymax < tmax || tmax !== tmax ) { tmax = tymax; } if ( invdirz >= 0 ) { @@ -7198,15 +7280,15 @@ } - if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; + if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) { return null; } - if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; + if ( tzmin > tmin || tmin !== tmin ) { tmin = tzmin; } - if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; + if ( tzmax < tmax || tmax !== tmax ) { tmax = tzmax; } //return point closest to the ray (positive side) - if ( tmax < 0 ) return null; + if ( tmax < 0 ) { return null; } return this.at( tmin >= 0 ? tmin : tmax, target ); @@ -7214,7 +7296,7 @@ intersectsBox: function ( box ) { - return this.intersectBox( box, _vector$3 ) !== null; + return this.intersectBox( box, _vector$2 ) !== null; }, @@ -7238,7 +7320,7 @@ if ( DdN > 0 ) { - if ( backfaceCulling ) return null; + if ( backfaceCulling ) { return null; } sign = 1; } else if ( DdN < 0 ) { @@ -7310,6 +7392,232 @@ } ); + /** + * @author bhouston / http://clara.io + */ + + var _vector1 = new Vector3(); + var _vector2 = new Vector3(); + var _normalMatrix = new Matrix3(); + + function Plane( normal, constant ) { + + // normal is assumed to be normalized + + this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); + this.constant = ( constant !== undefined ) ? constant : 0; + + } + + Object.assign( Plane.prototype, { + + isPlane: true, + + set: function ( normal, constant ) { + + this.normal.copy( normal ); + this.constant = constant; + + return this; + + }, + + setComponents: function ( x, y, z, w ) { + + this.normal.set( x, y, z ); + this.constant = w; + + return this; + + }, + + setFromNormalAndCoplanarPoint: function ( normal, point ) { + + this.normal.copy( normal ); + this.constant = - point.dot( this.normal ); + + return this; + + }, + + setFromCoplanarPoints: function ( a, b, c ) { + + var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); + + // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? + + this.setFromNormalAndCoplanarPoint( normal, a ); + + return this; + + }, + + clone: function () { + + return new this.constructor().copy( this ); + + }, + + copy: function ( plane ) { + + this.normal.copy( plane.normal ); + this.constant = plane.constant; + + return this; + + }, + + normalize: function () { + + // Note: will lead to a divide by zero if the plane is invalid. + + var inverseNormalLength = 1.0 / this.normal.length(); + this.normal.multiplyScalar( inverseNormalLength ); + this.constant *= inverseNormalLength; + + return this; + + }, + + negate: function () { + + this.constant *= - 1; + this.normal.negate(); + + return this; + + }, + + distanceToPoint: function ( point ) { + + return this.normal.dot( point ) + this.constant; + + }, + + distanceToSphere: function ( sphere ) { + + return this.distanceToPoint( sphere.center ) - sphere.radius; + + }, + + projectPoint: function ( point, target ) { + + if ( target === undefined ) { + + console.warn( 'THREE.Plane: .projectPoint() target is now required' ); + target = new Vector3(); + + } + + return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); + + }, + + intersectLine: function ( line, target ) { + + if ( target === undefined ) { + + console.warn( 'THREE.Plane: .intersectLine() target is now required' ); + target = new Vector3(); + + } + + var direction = line.delta( _vector1 ); + + var denominator = this.normal.dot( direction ); + + if ( denominator === 0 ) { + + // line is coplanar, return origin + if ( this.distanceToPoint( line.start ) === 0 ) { + + return target.copy( line.start ); + + } + + // Unsure if this is the correct method to handle this case. + return undefined; + + } + + var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + + if ( t < 0 || t > 1 ) { + + return undefined; + + } + + return target.copy( direction ).multiplyScalar( t ).add( line.start ); + + }, + + intersectsLine: function ( line ) { + + // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + + var startSign = this.distanceToPoint( line.start ); + var endSign = this.distanceToPoint( line.end ); + + return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); + + }, + + intersectsBox: function ( box ) { + + return box.intersectsPlane( this ); + + }, + + intersectsSphere: function ( sphere ) { + + return sphere.intersectsPlane( this ); + + }, + + coplanarPoint: function ( target ) { + + if ( target === undefined ) { + + console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); + target = new Vector3(); + + } + + return target.copy( this.normal ).multiplyScalar( - this.constant ); + + }, + + applyMatrix4: function ( matrix, optionalNormalMatrix ) { + + var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); + + var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); + + var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); + + this.constant = - referencePoint.dot( normal ); + + return this; + + }, + + translate: function ( offset ) { + + this.constant -= offset.dot( this.normal ); + + return this; + + }, + + equals: function ( plane ) { + + return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); + + } + + } ); + /** * @author bhouston / http://clara.io * @author mrdoob / http://mrdoob.com/ @@ -7506,7 +7814,7 @@ if ( target === undefined ) { console.warn( 'THREE.Triangle: .getPlane() target is now required' ); - target = new Vector3(); + target = new Plane(); } @@ -7687,11 +7995,11 @@ function hue2rgb( p, q, t ) { - if ( t < 0 ) t += 1; - if ( t > 1 ) t -= 1; - if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; - if ( t < 1 / 2 ) return q; - if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); + if ( t < 0 ) { t += 1; } + if ( t > 1 ) { t -= 1; } + if ( t < 1 / 6 ) { return p + ( q - p ) * 6 * t; } + if ( t < 1 / 2 ) { return q; } + if ( t < 2 / 3 ) { return p + ( q - p ) * 6 * ( 2 / 3 - t ); } return p; } @@ -7769,9 +8077,9 @@ setHSL: function ( h, s, l ) { // h,s,l ranges are in 0.0 - 1.0 - h = _Math.euclideanModulo( h, 1 ); - s = _Math.clamp( s, 0, 1 ); - l = _Math.clamp( l, 0, 1 ); + h = MathUtils.euclideanModulo( h, 1 ); + s = MathUtils.clamp( s, 0, 1 ); + l = MathUtils.clamp( l, 0, 1 ); if ( s === 0 ) { @@ -7796,7 +8104,7 @@ function handleAlpha( string ) { - if ( string === undefined ) return; + if ( string === undefined ) { return; } if ( parseFloat( string ) < 1 ) { @@ -7901,20 +8209,28 @@ if ( style && style.length > 0 ) { - // color keywords - var hex = _colorKeywords[ style ]; + return this.setColorName( style ); - if ( hex !== undefined ) { + } - // red - this.setHex( hex ); + return this; - } else { + }, - // unknown color - console.warn( 'THREE.Color: Unknown color ' + style ); + setColorName: function ( style ) { - } + // color keywords + var hex = _colorKeywords[ style ]; + + if ( hex !== undefined ) { + + // red + this.setHex( hex ); + + } else { + + // unknown color + console.warn( 'THREE.Color: Unknown color ' + style ); } @@ -7940,7 +8256,7 @@ copyGammaToLinear: function ( color, gammaFactor ) { - if ( gammaFactor === undefined ) gammaFactor = 2.0; + if ( gammaFactor === undefined ) { gammaFactor = 2.0; } this.r = Math.pow( color.r, gammaFactor ); this.g = Math.pow( color.g, gammaFactor ); @@ -7952,7 +8268,7 @@ copyLinearToGamma: function ( color, gammaFactor ) { - if ( gammaFactor === undefined ) gammaFactor = 2.0; + if ( gammaFactor === undefined ) { gammaFactor = 2.0; } var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; @@ -8171,9 +8487,9 @@ this.getHSL( _hslA ); color.getHSL( _hslB ); - var h = _Math.lerp( _hslA.h, _hslB.h, alpha ); - var s = _Math.lerp( _hslA.s, _hslB.s, alpha ); - var l = _Math.lerp( _hslA.l, _hslB.l, alpha ); + var h = MathUtils.lerp( _hslA.h, _hslB.h, alpha ); + var s = MathUtils.lerp( _hslA.s, _hslB.s, alpha ); + var l = MathUtils.lerp( _hslA.l, _hslB.l, alpha ); this.setHSL( h, s, l ); @@ -8189,7 +8505,7 @@ fromArray: function ( array, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) { offset = 0; } this.r = array[ offset ]; this.g = array[ offset + 1 ]; @@ -8201,8 +8517,8 @@ toArray: function ( array, offset ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } array[ offset ] = this.r; array[ offset + 1 ] = this.g; @@ -8220,6 +8536,8 @@ } ); + Color.NAMES = _colorKeywords; + /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ @@ -8289,19 +8607,17 @@ Object.defineProperty( this, 'id', { value: materialId ++ } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'Material'; this.fog = true; - this.lights = true; this.blending = NormalBlending; this.side = FrontSide; this.flatShading = false; - this.vertexTangents = false; - this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors + this.vertexColors = false; this.opacity = 1; this.transparent = false; @@ -8317,9 +8633,10 @@ this.depthTest = true; this.depthWrite = true; + this.stencilWriteMask = 0xff; this.stencilFunc = AlwaysStencilFunc; this.stencilRef = 0; - this.stencilMask = 0xff; + this.stencilFuncMask = 0xff; this.stencilFail = KeepStencilOp; this.stencilZFail = KeepStencilOp; this.stencilZPass = KeepStencilOp; @@ -8346,9 +8663,11 @@ this.visible = true; + this.toneMapped = true; + this.userData = {}; - this.needsUpdate = true; + this.version = 0; } @@ -8362,7 +8681,7 @@ setValues: function ( values ) { - if ( values === undefined ) return; + if ( values === undefined ) { return; } for ( var key in values ) { @@ -8436,32 +8755,45 @@ data.uuid = this.uuid; data.type = this.type; - if ( this.name !== '' ) data.name = this.name; + if ( this.name !== '' ) { data.name = this.name; } - if ( this.color && this.color.isColor ) data.color = this.color.getHex(); + if ( this.color && this.color.isColor ) { data.color = this.color.getHex(); } - if ( this.roughness !== undefined ) data.roughness = this.roughness; - if ( this.metalness !== undefined ) data.metalness = this.metalness; + if ( this.roughness !== undefined ) { data.roughness = this.roughness; } + if ( this.metalness !== undefined ) { data.metalness = this.metalness; } - if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); - if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; + if ( this.sheen && this.sheen.isColor ) { data.sheen = this.sheen.getHex(); } + if ( this.emissive && this.emissive.isColor ) { data.emissive = this.emissive.getHex(); } + if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) { data.emissiveIntensity = this.emissiveIntensity; } - if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); - if ( this.shininess !== undefined ) data.shininess = this.shininess; - if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; - if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; + if ( this.specular && this.specular.isColor ) { data.specular = this.specular.getHex(); } + if ( this.shininess !== undefined ) { data.shininess = this.shininess; } + if ( this.clearcoat !== undefined ) { data.clearcoat = this.clearcoat; } + if ( this.clearcoatRoughness !== undefined ) { data.clearcoatRoughness = this.clearcoatRoughness; } - if ( this.clearCoatNormalMap && this.clearCoatNormalMap.isTexture ) { + if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { - data.clearCoatNormalMap = this.clearCoatNormalMap.toJSON( meta ).uuid; - data.clearCoatNormalScale = this.clearCoatNormalScale.toArray(); + data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; } - if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; - if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; - if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; - if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid; + if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { + + data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; + + } + + if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { + + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; + data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); + + } + + if ( this.map && this.map.isTexture ) { data.map = this.map.toJSON( meta ).uuid; } + if ( this.matcap && this.matcap.isTexture ) { data.matcap = this.matcap.toJSON( meta ).uuid; } + if ( this.alphaMap && this.alphaMap.isTexture ) { data.alphaMap = this.alphaMap.toJSON( meta ).uuid; } + if ( this.lightMap && this.lightMap.isTexture ) { data.lightMap = this.lightMap.toJSON( meta ).uuid; } if ( this.aoMap && this.aoMap.isTexture ) { @@ -8493,11 +8825,11 @@ } - if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; - if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; + if ( this.roughnessMap && this.roughnessMap.isTexture ) { data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; } + if ( this.metalnessMap && this.metalnessMap.isTexture ) { data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; } - if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; - if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; + if ( this.emissiveMap && this.emissiveMap.isTexture ) { data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; } + if ( this.specularMap && this.specularMap.isTexture ) { data.specularMap = this.specularMap.toJSON( meta ).uuid; } if ( this.envMap && this.envMap.isTexture ) { @@ -8505,8 +8837,8 @@ data.reflectivity = this.reflectivity; // Scale behind envMap data.refractionRatio = this.refractionRatio; - if ( this.combine !== undefined ) data.combine = this.combine; - if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; + if ( this.combine !== undefined ) { data.combine = this.combine; } + if ( this.envMapIntensity !== undefined ) { data.envMapIntensity = this.envMapIntensity; } } @@ -8516,57 +8848,61 @@ } - if ( this.size !== undefined ) data.size = this.size; - if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; + if ( this.size !== undefined ) { data.size = this.size; } + if ( this.sizeAttenuation !== undefined ) { data.sizeAttenuation = this.sizeAttenuation; } - if ( this.blending !== NormalBlending ) data.blending = this.blending; - if ( this.flatShading === true ) data.flatShading = this.flatShading; - if ( this.side !== FrontSide ) data.side = this.side; - if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors; + if ( this.blending !== NormalBlending ) { data.blending = this.blending; } + if ( this.flatShading === true ) { data.flatShading = this.flatShading; } + if ( this.side !== FrontSide ) { data.side = this.side; } + if ( this.vertexColors ) { data.vertexColors = true; } - if ( this.opacity < 1 ) data.opacity = this.opacity; - if ( this.transparent === true ) data.transparent = this.transparent; + if ( this.opacity < 1 ) { data.opacity = this.opacity; } + if ( this.transparent === true ) { data.transparent = this.transparent; } data.depthFunc = this.depthFunc; data.depthTest = this.depthTest; data.depthWrite = this.depthWrite; data.stencilWrite = this.stencilWrite; + data.stencilWriteMask = this.stencilWriteMask; data.stencilFunc = this.stencilFunc; data.stencilRef = this.stencilRef; - data.stencilMask = this.stencilMask; + data.stencilFuncMask = this.stencilFuncMask; data.stencilFail = this.stencilFail; data.stencilZFail = this.stencilZFail; data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial) - if ( this.rotation && this.rotation !== 0 ) data.rotation = this.rotation; + if ( this.rotation && this.rotation !== 0 ) { data.rotation = this.rotation; } + + if ( this.polygonOffset === true ) { data.polygonOffset = true; } + if ( this.polygonOffsetFactor !== 0 ) { data.polygonOffsetFactor = this.polygonOffsetFactor; } + if ( this.polygonOffsetUnits !== 0 ) { data.polygonOffsetUnits = this.polygonOffsetUnits; } - if ( this.polygonOffset === true ) data.polygonOffset = true; - if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; - if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; + if ( this.linewidth && this.linewidth !== 1 ) { data.linewidth = this.linewidth; } + if ( this.dashSize !== undefined ) { data.dashSize = this.dashSize; } + if ( this.gapSize !== undefined ) { data.gapSize = this.gapSize; } + if ( this.scale !== undefined ) { data.scale = this.scale; } - if ( this.linewidth && this.linewidth !== 1 ) data.linewidth = this.linewidth; - if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; - if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; - if ( this.scale !== undefined ) data.scale = this.scale; + if ( this.dithering === true ) { data.dithering = true; } - if ( this.dithering === true ) data.dithering = true; + if ( this.alphaTest > 0 ) { data.alphaTest = this.alphaTest; } + if ( this.premultipliedAlpha === true ) { data.premultipliedAlpha = this.premultipliedAlpha; } - if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; - if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; + if ( this.wireframe === true ) { data.wireframe = this.wireframe; } + if ( this.wireframeLinewidth > 1 ) { data.wireframeLinewidth = this.wireframeLinewidth; } + if ( this.wireframeLinecap !== 'round' ) { data.wireframeLinecap = this.wireframeLinecap; } + if ( this.wireframeLinejoin !== 'round' ) { data.wireframeLinejoin = this.wireframeLinejoin; } - if ( this.wireframe === true ) data.wireframe = this.wireframe; - if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; - if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; - if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; + if ( this.morphTargets === true ) { data.morphTargets = true; } + if ( this.morphNormals === true ) { data.morphNormals = true; } + if ( this.skinning === true ) { data.skinning = true; } - if ( this.morphTargets === true ) data.morphTargets = true; - if ( this.morphNormals === true ) data.morphNormals = true; - if ( this.skinning === true ) data.skinning = true; + if ( this.visible === false ) { data.visible = false; } - if ( this.visible === false ) data.visible = false; - if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; + if ( this.toneMapped === false ) { data.toneMapped = false; } + + if ( JSON.stringify( this.userData ) !== '{}' ) { data.userData = this.userData; } // TODO: Copied from Object3D.toJSON @@ -8591,8 +8927,8 @@ var textures = extractFromCache( meta.textures ); var images = extractFromCache( meta.images ); - if ( textures.length > 0 ) data.textures = textures; - if ( images.length > 0 ) data.images = images; + if ( textures.length > 0 ) { data.textures = textures; } + if ( images.length > 0 ) { data.images = images; } } @@ -8611,7 +8947,6 @@ this.name = source.name; this.fog = source.fog; - this.lights = source.lights; this.blending = source.blending; this.side = source.side; @@ -8632,13 +8967,33 @@ this.depthTest = source.depthTest; this.depthWrite = source.depthWrite; - this.stencilWrite = source.stencilWrite; + this.stencilWriteMask = source.stencilWriteMask; this.stencilFunc = source.stencilFunc; this.stencilRef = source.stencilRef; - this.stencilMask = source.stencilMask; + this.stencilFuncMask = source.stencilFuncMask; this.stencilFail = source.stencilFail; this.stencilZFail = source.stencilZFail; this.stencilZPass = source.stencilZPass; + this.stencilWrite = source.stencilWrite; + + var srcPlanes = source.clippingPlanes, + dstPlanes = null; + + if ( srcPlanes !== null ) { + + var n = srcPlanes.length; + dstPlanes = new Array( n ); + + for ( var i = 0; i !== n; ++ i ) + { dstPlanes[ i ] = srcPlanes[ i ].clone(); } + + } + + this.clippingPlanes = dstPlanes; + this.clipIntersection = source.clipIntersection; + this.clipShadows = source.clipShadows; + + this.shadowSide = source.shadowSide; this.colorWrite = source.colorWrite; @@ -8654,35 +9009,28 @@ this.premultipliedAlpha = source.premultipliedAlpha; this.visible = source.visible; - this.userData = JSON.parse( JSON.stringify( source.userData ) ); - this.clipShadows = source.clipShadows; - this.clipIntersection = source.clipIntersection; + this.toneMapped = source.toneMapped; - var srcPlanes = source.clippingPlanes, - dstPlanes = null; - - if ( srcPlanes !== null ) { + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - var n = srcPlanes.length; - dstPlanes = new Array( n ); + return this; - for ( var i = 0; i !== n; ++ i ) - dstPlanes[ i ] = srcPlanes[ i ].clone(); + }, - } + dispose: function () { - this.clippingPlanes = dstPlanes; + this.dispatchEvent( { type: 'dispose' } ); - this.shadowSide = source.shadowSide; + } - return this; + } ); - }, + Object.defineProperty( Material.prototype, 'needsUpdate', { - dispose: function () { + set: function ( value ) { - this.dispatchEvent( { type: 'dispose' } ); + if ( value === true ) { this.version ++; } } @@ -8756,8 +9104,6 @@ this.skinning = false; this.morphTargets = false; - this.lights = false; - this.setValues( parameters ); } @@ -8806,6 +9152,8 @@ * @author mrdoob / http://mrdoob.com/ */ + var _vector$3 = new Vector3(); + function BufferAttribute( array, itemSize, normalized ) { if ( Array.isArray( array ) ) { @@ -8821,7 +9169,7 @@ this.count = array !== undefined ? array.length / itemSize : 0; this.normalized = normalized === true; - this.dynamic = false; + this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: - 1 }; this.version = 0; @@ -8832,7 +9180,7 @@ set: function ( value ) { - if ( value === true ) this.version ++; + if ( value === true ) { this.version ++; } } @@ -8844,24 +9192,9 @@ onUploadCallback: function () {}, - setArray: function ( array ) { - - if ( Array.isArray( array ) ) { + setUsage: function ( value ) { - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - - } - - this.count = array !== undefined ? array.length / this.itemSize : 0; - this.array = array; - - return this; - - }, - - setDynamic: function ( value ) { - - this.dynamic = value; + this.usage = value; return this; @@ -8875,7 +9208,7 @@ this.count = source.count; this.normalized = source.normalized; - this.dynamic = source.dynamic; + this.usage = source.usage; return this; @@ -9004,9 +9337,81 @@ }, + applyMatrix3: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.applyMatrix3( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + + applyMatrix4: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.applyMatrix4( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + + applyNormalMatrix: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.applyNormalMatrix( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + + transformDirection: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.transformDirection( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + set: function ( value, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) { offset = 0; } this.array.set( value, offset ); @@ -9512,13 +9917,13 @@ function arrayMax( array ) { - if ( array.length === 0 ) return - Infinity; + if ( array.length === 0 ) { return - Infinity; } var max = array[ 0 ]; for ( var i = 1, l = array.length; i < l; ++ i ) { - if ( array[ i ] > max ) max = array[ i ]; + if ( array[ i ] > max ) { max = array[ i ]; } } @@ -9536,7 +9941,7 @@ var _m1$2 = new Matrix4(); var _obj = new Object3D(); var _offset = new Vector3(); - var _box$1 = new Box3(); + var _box$2 = new Box3(); var _boxMorphTargets = new Box3(); var _vector$4 = new Vector3(); @@ -9544,7 +9949,7 @@ Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'BufferGeometry'; @@ -9553,6 +9958,7 @@ this.attributes = {}; this.morphAttributes = {}; + this.morphTargetsRelative = false; this.groups = []; @@ -9591,24 +9997,13 @@ }, - addAttribute: function ( name, attribute ) { - - if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { - - console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); - - return this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); - - } - - if ( name === 'index' ) { + getAttribute: function ( name ) { - console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); - this.setIndex( attribute ); + return this.attributes[ name ]; - return this; + }, - } + setAttribute: function ( name, attribute ) { this.attributes[ name ] = attribute; @@ -9616,13 +10011,7 @@ }, - getAttribute: function ( name ) { - - return this.attributes[ name ]; - - }, - - removeAttribute: function ( name ) { + deleteAttribute: function ( name ) { delete this.attributes[ name ]; @@ -9655,13 +10044,14 @@ }, - applyMatrix: function ( matrix ) { + applyMatrix4: function ( matrix ) { var position = this.attributes.position; if ( position !== undefined ) { - matrix.applyToBufferAttribute( position ); + position.applyMatrix4( matrix ); + position.needsUpdate = true; } @@ -9672,7 +10062,8 @@ var normalMatrix = new Matrix3().getNormalMatrix( matrix ); - normalMatrix.applyToBufferAttribute( normal ); + normal.applyNormalMatrix( normalMatrix ); + normal.needsUpdate = true; } @@ -9681,10 +10072,8 @@ if ( tangent !== undefined ) { - var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + tangent.transformDirection( matrix ); - // Tangent is vec4, but the '.w' component is a sign value (+1/-1). - normalMatrix.applyToBufferAttribute( tangent ); tangent.needsUpdate = true; } @@ -9711,7 +10100,7 @@ _m1$2.makeRotationX( angle ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9723,7 +10112,7 @@ _m1$2.makeRotationY( angle ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9735,7 +10124,7 @@ _m1$2.makeRotationZ( angle ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9747,7 +10136,7 @@ _m1$2.makeTranslation( x, y, z ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9759,7 +10148,7 @@ _m1$2.makeScale( x, y, z ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9771,7 +10160,7 @@ _obj.updateMatrix(); - this.applyMatrix( _obj.matrix ); + this.applyMatrix4( _obj.matrix ); return this; @@ -9800,14 +10189,14 @@ var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); - this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); - this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); + this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); + this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); - this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); + this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); } @@ -9848,7 +10237,7 @@ } - this.addAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); return this; @@ -9992,33 +10381,33 @@ fromDirectGeometry: function ( geometry ) { var positions = new Float32Array( geometry.vertices.length * 3 ); - this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); + this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); if ( geometry.normals.length > 0 ) { var normals = new Float32Array( geometry.normals.length * 3 ); - this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); + this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); } if ( geometry.colors.length > 0 ) { var colors = new Float32Array( geometry.colors.length * 3 ); - this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); + this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); } if ( geometry.uvs.length > 0 ) { var uvs = new Float32Array( geometry.uvs.length * 2 ); - this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); + this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); } if ( geometry.uvs2.length > 0 ) { var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); - this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); + this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); } @@ -10053,14 +10442,14 @@ if ( geometry.skinIndices.length > 0 ) { var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); - this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); + this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); } if ( geometry.skinWeights.length > 0 ) { var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); - this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); + this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); } @@ -10104,10 +10493,22 @@ for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { var morphAttribute = morphAttributesPosition[ i ]; - _box$1.setFromBufferAttribute( morphAttribute ); + _box$2.setFromBufferAttribute( morphAttribute ); + + if ( this.morphTargetsRelative ) { - this.boundingBox.expandByPoint( _box$1.min ); - this.boundingBox.expandByPoint( _box$1.max ); + _vector$4.addVectors( this.boundingBox.min, _box$2.min ); + this.boundingBox.expandByPoint( _vector$4 ); + + _vector$4.addVectors( this.boundingBox.max, _box$2.max ); + this.boundingBox.expandByPoint( _vector$4 ); + + } else { + + this.boundingBox.expandByPoint( _box$2.min ); + this.boundingBox.expandByPoint( _box$2.max ); + + } } @@ -10144,7 +10545,7 @@ var center = this.boundingSphere.center; - _box$1.setFromBufferAttribute( position ); + _box$2.setFromBufferAttribute( position ); // process morph attributes if present @@ -10155,14 +10556,26 @@ var morphAttribute = morphAttributesPosition[ i ]; _boxMorphTargets.setFromBufferAttribute( morphAttribute ); - _box$1.expandByPoint( _boxMorphTargets.min ); - _box$1.expandByPoint( _boxMorphTargets.max ); + if ( this.morphTargetsRelative ) { + + _vector$4.addVectors( _box$2.min, _boxMorphTargets.min ); + _box$2.expandByPoint( _vector$4 ); + + _vector$4.addVectors( _box$2.max, _boxMorphTargets.max ); + _box$2.expandByPoint( _vector$4 ); + + } else { + + _box$2.expandByPoint( _boxMorphTargets.min ); + _box$2.expandByPoint( _boxMorphTargets.max ); + + } } } - _box$1.getCenter( center ); + _box$2.getCenter( center ); // second, try to find a boundingSphere with a radius smaller than the // boundingSphere of the boundingBox: sqrt(3) smaller in the best case @@ -10184,11 +10597,19 @@ for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { var morphAttribute = morphAttributesPosition[ i ]; + var morphTargetsRelative = this.morphTargetsRelative; for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { _vector$4.fromBufferAttribute( morphAttribute, j ); + if ( morphTargetsRelative ) { + + _offset.fromBufferAttribute( position, j ); + _vector$4.add( _offset ); + + } + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); } @@ -10226,7 +10647,7 @@ if ( attributes.normal === undefined ) { - this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); + this.setAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); } else { @@ -10344,7 +10765,7 @@ for ( var key in attributes ) { - if ( geometry.attributes[ key ] === undefined ) continue; + if ( geometry.attributes[ key ] === undefined ) { continue; } var attribute1 = attributes[ key ]; var attributeArray1 = attribute1.array; @@ -10434,7 +10855,7 @@ var newAttribute = convertBufferAttribute( attribute, indices ); - geometry2.addAttribute( name, newAttribute ); + geometry2.setAttribute( name, newAttribute ); } @@ -10461,6 +10882,8 @@ } + geometry2.morphTargetsRelative = this.morphTargetsRelative; + // groups var groups = this.groups; @@ -10490,8 +10913,8 @@ data.uuid = this.uuid; data.type = this.type; - if ( this.name !== '' ) data.name = this.name; - if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; + if ( this.name !== '' ) { data.name = this.name; } + if ( Object.keys( this.userData ).length > 0 ) { data.userData = this.userData; } if ( this.parameters !== undefined ) { @@ -10499,7 +10922,7 @@ for ( var key in parameters ) { - if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; } } @@ -10528,7 +10951,7 @@ var attributeData = attribute.toJSON(); - if ( attribute.name !== '' ) attributeData.name = attribute.name; + if ( attribute.name !== '' ) { attributeData.name = attribute.name; } data.data.attributes[ key ] = attributeData; @@ -10549,7 +10972,7 @@ var attributeData = attribute.toJSON(); - if ( attribute.name !== '' ) attributeData.name = attribute.name; + if ( attribute.name !== '' ) { attributeData.name = attribute.name; } array.push( attributeData ); @@ -10565,7 +10988,12 @@ } - if ( hasMorphAttributes ) data.data.morphAttributes = morphAttributes; + if ( hasMorphAttributes ) { + + data.data.morphAttributes = morphAttributes; + data.data.morphTargetsRelative = this.morphTargetsRelative; + + } var groups = this.groups; @@ -10654,7 +11082,7 @@ for ( name in attributes ) { var attribute = attributes[ name ]; - this.addAttribute( name, attribute.clone() ); + this.setAttribute( name, attribute.clone() ); } @@ -10677,6 +11105,8 @@ } + this.morphTargetsRelative = source.morphTargetsRelative; + // groups var groups = source.groups; @@ -10766,9 +11196,7 @@ this.type = 'Mesh'; this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } ); - - this.drawMode = TrianglesDrawMode; + this.material = material !== undefined ? material : new MeshBasicMaterial(); this.updateMorphTargets(); @@ -10780,18 +11208,10 @@ isMesh: true, - setDrawMode: function ( value ) { - - this.drawMode = value; - - }, - copy: function ( source ) { Object3D.prototype.copy.call( this, source ); - this.drawMode = source.drawMode; - if ( source.morphTargetInfluences !== undefined ) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); @@ -10860,16 +11280,16 @@ var material = this.material; var matrixWorld = this.matrixWorld; - if ( material === undefined ) return; + if ( material === undefined ) { return; } // Checking boundingSphere distance to ray - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); } _sphere.copy( geometry.boundingSphere ); _sphere.applyMatrix4( matrixWorld ); - if ( raycaster.ray.intersectsSphere( _sphere ) === false ) return; + if ( raycaster.ray.intersectsSphere( _sphere ) === false ) { return; } // @@ -10880,7 +11300,7 @@ if ( geometry.boundingBox !== null ) { - if ( _ray.intersectsBox( geometry.boundingBox ) === false ) return; + if ( _ray.intersectsBox( geometry.boundingBox ) === false ) { return; } } @@ -10892,6 +11312,7 @@ var index = geometry.index; var position = geometry.attributes.position; var morphPosition = geometry.morphAttributes.position; + var morphTargetsRelative = geometry.morphTargetsRelative; var uv = geometry.attributes.uv; var uv2 = geometry.attributes.uv2; var groups = geometry.groups; @@ -10920,7 +11341,7 @@ b = index.getX( j + 1 ); c = index.getX( j + 2 ); - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -10945,7 +11366,7 @@ b = index.getX( i + 1 ); c = index.getX( i + 2 ); - intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -10978,7 +11399,7 @@ b = j + 1; c = j + 2; - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -11003,7 +11424,7 @@ b = i + 1; c = i + 2; - intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -11028,14 +11449,14 @@ var uvs; var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; - if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; + if ( faceVertexUvs.length > 0 ) { uvs = faceVertexUvs; } for ( var f = 0, fl = faces.length; f < fl; f ++ ) { var face = faces[ f ]; var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; - if ( faceMaterial === undefined ) continue; + if ( faceMaterial === undefined ) { continue; } fvA = vertices[ face.a ]; fvB = vertices[ face.b ]; @@ -11090,14 +11511,14 @@ } - if ( intersect === null ) return null; + if ( intersect === null ) { return null; } _intersectionPointWorld.copy( point ); _intersectionPointWorld.applyMatrix4( object.matrixWorld ); var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); - if ( distance < raycaster.near || distance > raycaster.far ) return null; + if ( distance < raycaster.near || distance > raycaster.far ) { return null; } return { distance: distance, @@ -11107,7 +11528,7 @@ } - function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) { + function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) { _vA.fromBufferAttribute( position, a ); _vB.fromBufferAttribute( position, b ); @@ -11126,15 +11547,25 @@ var influence = morphInfluences[ i ]; var morphAttribute = morphPosition[ i ]; - if ( influence === 0 ) continue; + if ( influence === 0 ) { continue; } _tempA.fromBufferAttribute( morphAttribute, a ); _tempB.fromBufferAttribute( morphAttribute, b ); _tempC.fromBufferAttribute( morphAttribute, c ); - _morphA.addScaledVector( _tempA.sub( _vA ), influence ); - _morphB.addScaledVector( _tempB.sub( _vB ), influence ); - _morphC.addScaledVector( _tempC.sub( _vC ), influence ); + if ( morphTargetsRelative ) { + + _morphA.addScaledVector( _tempA, influence ); + _morphB.addScaledVector( _tempB, influence ); + _morphC.addScaledVector( _tempC, influence ); + + } else { + + _morphA.addScaledVector( _tempA.sub( _vA ), influence ); + _morphB.addScaledVector( _tempB.sub( _vB ), influence ); + _morphC.addScaledVector( _tempC.sub( _vC ), influence ); + + } } @@ -11197,7 +11628,7 @@ Object.defineProperty( this, 'id', { value: _geometryId += 2 } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'Geometry'; @@ -11236,7 +11667,7 @@ isGeometry: true, - applyMatrix: function ( matrix ) { + applyMatrix4: function ( matrix ) { var normalMatrix = new Matrix3().getNormalMatrix( matrix ); @@ -11285,7 +11716,7 @@ _m1$3.makeRotationX( angle ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11297,7 +11728,7 @@ _m1$3.makeRotationY( angle ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11309,7 +11740,7 @@ _m1$3.makeRotationZ( angle ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11321,7 +11752,7 @@ _m1$3.makeTranslation( x, y, z ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11333,7 +11764,7 @@ _m1$3.makeScale( x, y, z ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11345,7 +11776,7 @@ _obj$1.updateMatrix(); - this.applyMatrix( _obj$1.matrix ); + this.applyMatrix4( _obj$1.matrix ); return this; @@ -11358,13 +11789,20 @@ var indices = geometry.index !== null ? geometry.index.array : undefined; var attributes = geometry.attributes; + if ( attributes.position === undefined ) { + + console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' ); + return this; + + } + var positions = attributes.position.array; var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; var colors = attributes.color !== undefined ? attributes.color.array : undefined; var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; - if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = []; + if ( uvs2 !== undefined ) { this.faceVertexUvs[ 1 ] = []; } for ( var i = 0; i < positions.length; i += 3 ) { @@ -11513,7 +11951,7 @@ 0, 0, 0, 1 ); - this.applyMatrix( matrix ); + this.applyMatrix4( matrix ); return this; @@ -11545,7 +11983,7 @@ computeVertexNormals: function ( areaWeighted ) { - if ( areaWeighted === undefined ) areaWeighted = true; + if ( areaWeighted === undefined ) { areaWeighted = true; } var v, vl, f, fl, face, vertices; @@ -11693,7 +12131,7 @@ } - if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; + if ( ! face.__originalVertexNormals ) { face.__originalVertexNormals = []; } for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { @@ -11830,7 +12268,7 @@ colors1 = this.colors, colors2 = geometry.colors; - if ( materialIndexOffset === undefined ) materialIndexOffset = 0; + if ( materialIndexOffset === undefined ) { materialIndexOffset = 0; } if ( matrix !== undefined ) { @@ -11846,7 +12284,7 @@ var vertexCopy = vertex.clone(); - if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); + if ( matrix !== undefined ) { vertexCopy.applyMatrix4( matrix ); } vertices1.push( vertexCopy ); @@ -11912,7 +12350,7 @@ var faceVertexUvs2 = geometry.faceVertexUvs[ i ]; - if ( this.faceVertexUvs[ i ] === undefined ) this.faceVertexUvs[ i ] = []; + if ( this.faceVertexUvs[ i ] === undefined ) { this.faceVertexUvs[ i ] = []; } for ( var j = 0, jl = faceVertexUvs2.length; j < jl; j ++ ) { @@ -11941,7 +12379,7 @@ } - if ( mesh.matrixAutoUpdate ) mesh.updateMatrix(); + if ( mesh.matrixAutoUpdate ) { mesh.updateMatrix(); } this.merge( mesh.geometry, mesh.matrix ); @@ -12081,20 +12519,20 @@ var newUvs1, newUvs2; - if ( uvs1 && uvs1.length === length ) newUvs1 = []; - if ( uvs2 && uvs2.length === length ) newUvs2 = []; + if ( uvs1 && uvs1.length === length ) { newUvs1 = []; } + if ( uvs2 && uvs2.length === length ) { newUvs2 = []; } for ( var i = 0; i < length; i ++ ) { var id = faces[ i ]._id; - if ( newUvs1 ) newUvs1.push( uvs1[ id ] ); - if ( newUvs2 ) newUvs2.push( uvs2[ id ] ); + if ( newUvs1 ) { newUvs1.push( uvs1[ id ] ); } + if ( newUvs2 ) { newUvs2.push( uvs2[ id ] ); } } - if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1; - if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2; + if ( newUvs1 ) { this.faceVertexUvs[ 0 ] = newUvs1; } + if ( newUvs2 ) { this.faceVertexUvs[ 1 ] = newUvs2; } }, @@ -12112,7 +12550,7 @@ data.uuid = this.uuid; data.type = this.type; - if ( this.name !== '' ) data.name = this.name; + if ( this.name !== '' ) { data.name = this.name; } if ( this.parameters !== undefined ) { @@ -12120,7 +12558,7 @@ for ( var key in parameters ) { - if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; } } @@ -12283,8 +12721,8 @@ data.data.vertices = vertices; data.data.normals = normals; - if ( colors.length > 0 ) data.data.colors = colors; - if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility + if ( colors.length > 0 ) { data.data.colors = colors; } + if ( uvs.length > 0 ) { data.data.uvs = [ uvs ]; } // temporal backward compatibility data.data.faces = faces; return data; @@ -12570,194 +13008,204 @@ // BoxGeometry - function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { + var BoxGeometry = /*@__PURE__*/(function (Geometry) { + function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { - Geometry.call( this ); + Geometry.call(this); - this.type = 'BoxGeometry'; + this.type = 'BoxGeometry'; - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; - this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); - this.mergeVertices(); + this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); + this.mergeVertices(); - } + } + + if ( Geometry ) BoxGeometry.__proto__ = Geometry; + BoxGeometry.prototype = Object.create( Geometry && Geometry.prototype ); + BoxGeometry.prototype.constructor = BoxGeometry; - BoxGeometry.prototype = Object.create( Geometry.prototype ); - BoxGeometry.prototype.constructor = BoxGeometry; + return BoxGeometry; + }(Geometry)); // BoxBufferGeometry - function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { + var BoxBufferGeometry = /*@__PURE__*/(function (BufferGeometry) { + function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { - BufferGeometry.call( this ); + BufferGeometry.call(this); - this.type = 'BoxBufferGeometry'; + this.type = 'BoxBufferGeometry'; - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; - var scope = this; + var scope = this; - width = width || 1; - height = height || 1; - depth = depth || 1; + width = width || 1; + height = height || 1; + depth = depth || 1; - // segments + // segments - widthSegments = Math.floor( widthSegments ) || 1; - heightSegments = Math.floor( heightSegments ) || 1; - depthSegments = Math.floor( depthSegments ) || 1; + widthSegments = Math.floor( widthSegments ) || 1; + heightSegments = Math.floor( heightSegments ) || 1; + depthSegments = Math.floor( depthSegments ) || 1; - // buffers + // buffers - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - // helper variables + // helper variables - var numberOfVertices = 0; - var groupStart = 0; + var numberOfVertices = 0; + var groupStart = 0; - // build each side of the box geometry + // build each side of the box geometry - buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px - buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx - buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py - buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny - buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz - buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px + buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx + buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py + buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny + buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz + buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz - // build geometry + // build geometry - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { - var segmentWidth = width / gridX; - var segmentHeight = height / gridY; + var segmentWidth = width / gridX; + var segmentHeight = height / gridY; - var widthHalf = width / 2; - var heightHalf = height / 2; - var depthHalf = depth / 2; + var widthHalf = width / 2; + var heightHalf = height / 2; + var depthHalf = depth / 2; - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; - var vertexCounter = 0; - var groupCount = 0; + var vertexCounter = 0; + var groupCount = 0; - var ix, iy; + var ix, iy; - var vector = new Vector3(); + var vector = new Vector3(); - // generate vertices, normals and uvs + // generate vertices, normals and uvs - for ( iy = 0; iy < gridY1; iy ++ ) { + for ( iy = 0; iy < gridY1; iy ++ ) { - var y = iy * segmentHeight - heightHalf; + var y = iy * segmentHeight - heightHalf; - for ( ix = 0; ix < gridX1; ix ++ ) { + for ( ix = 0; ix < gridX1; ix ++ ) { - var x = ix * segmentWidth - widthHalf; + var x = ix * segmentWidth - widthHalf; - // set values to correct vector component + // set values to correct vector component - vector[ u ] = x * udir; - vector[ v ] = y * vdir; - vector[ w ] = depthHalf; + vector[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; - // now apply vector to vertex buffer + // now apply vector to vertex buffer - vertices.push( vector.x, vector.y, vector.z ); + vertices.push( vector.x, vector.y, vector.z ); - // set values to correct vector component + // set values to correct vector component - vector[ u ] = 0; - vector[ v ] = 0; - vector[ w ] = depth > 0 ? 1 : - 1; + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : - 1; - // now apply vector to normal buffer + // now apply vector to normal buffer - normals.push( vector.x, vector.y, vector.z ); + normals.push( vector.x, vector.y, vector.z ); - // uvs + // uvs - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); - // counters + // counters - vertexCounter += 1; + vertexCounter += 1; + + } } - } + // indices - // indices + // 1. you need three indices to draw a single face + // 2. a single segment consists of two faces + // 3. so we need to generate six (2*3) indices per segment - // 1. you need three indices to draw a single face - // 2. a single segment consists of two faces - // 3. so we need to generate six (2*3) indices per segment + for ( iy = 0; iy < gridY; iy ++ ) { - for ( iy = 0; iy < gridY; iy ++ ) { + for ( ix = 0; ix < gridX; ix ++ ) { - for ( ix = 0; ix < gridX; ix ++ ) { + var a = numberOfVertices + ix + gridX1 * iy; + var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); + var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; - var a = numberOfVertices + ix + gridX1 * iy; - var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); - var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + // faces - // faces + indices.push( a, b, d ); + indices.push( b, c, d ); - indices.push( a, b, d ); - indices.push( b, c, d ); + // increase counter - // increase counter + groupCount += 6; - groupCount += 6; + } } - } + // add a group to the geometry. this will ensure multi material support - // add a group to the geometry. this will ensure multi material support + scope.addGroup( groupStart, groupCount, materialIndex ); - scope.addGroup( groupStart, groupCount, materialIndex ); + // calculate new start value for groups - // calculate new start value for groups + groupStart += groupCount; - groupStart += groupCount; + // update total number of vertices - // update total number of vertices + numberOfVertices += vertexCounter; - numberOfVertices += vertexCounter; + } } - } + if ( BufferGeometry ) BoxBufferGeometry.__proto__ = BufferGeometry; + BoxBufferGeometry.prototype = Object.create( BufferGeometry && BufferGeometry.prototype ); + BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; - BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; + return BoxBufferGeometry; + }(BufferGeometry)); /** * Uniform Utilities @@ -13011,7 +13459,7 @@ } - if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; + if ( Object.keys( this.defines ).length > 0 ) { data.defines = this.defines; } data.vertexShader = this.vertexShader; data.fragmentShader = this.fragmentShader; @@ -13020,11 +13468,11 @@ for ( var key in this.extensions ) { - if ( this.extensions[ key ] === true ) extensions[ key ] = true; + if ( this.extensions[ key ] === true ) { extensions[ key ] = true; } } - if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; + if ( Object.keys( extensions ).length > 0 ) { data.extensions = extensions; } return data; @@ -13093,6 +13541,14 @@ }, + updateWorldMatrix: function ( updateParents, updateChildren ) { + + Object3D.prototype.updateWorldMatrix.call( this, updateParents, updateChildren ); + + this.matrixWorldInverse.getInverse( this.matrixWorld ); + + }, + clone: function () { return new this.constructor().copy( this ); @@ -13171,7 +13627,7 @@ // see http://www.bobatkins.com/photography/technical/field_of_view.html var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope ); this.updateProjectionMatrix(); }, @@ -13181,7 +13637,7 @@ */ getFocalLength: function () { - var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov ); + var vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ); return 0.5 * this.getFilmHeight() / vExtentSlope; @@ -13189,8 +13645,8 @@ getEffectiveFOV: function () { - return _Math.RAD2DEG * 2 * Math.atan( - Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom ); + return MathUtils.RAD2DEG * 2 * Math.atan( + Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom ); }, @@ -13288,7 +13744,7 @@ updateProjectionMatrix: function () { var near = this.near, - top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, + top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom, height = 2 * top, width = this.aspect * height, left = - 0.5 * width, @@ -13307,7 +13763,7 @@ } var skew = this.filmOffset; - if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); + if ( skew !== 0 ) { left += near * skew / this.getFilmWidth(); } this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); @@ -13328,7 +13784,7 @@ data.object.aspect = this.aspect; - if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + if ( this.view !== null ) { data.object.view = Object.assign( {}, this.view ); } data.object.filmGauge = this.filmGauge; data.object.filmOffset = this.filmOffset; @@ -13386,12 +13842,12 @@ options = options || { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; - this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options ); + this.renderTarget = new WebGLCubeRenderTarget( cubeResolution, options ); this.renderTarget.texture.name = "CubeCamera"; this.update = function ( renderer, scene ) { - if ( this.parent === null ) this.updateMatrixWorld(); + if ( this.parent === null ) { this.updateMatrixWorld(); } var currentRenderTarget = renderer.getRenderTarget(); @@ -13452,18 +13908,26 @@ * @author WestLangley / http://github.com/WestLangley */ - function WebGLRenderTargetCube( width, height, options ) { + function WebGLCubeRenderTarget( size, options, dummy ) { - WebGLRenderTarget.call( this, width, height, options ); + if ( Number.isInteger( options ) ) { + + console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' ); + + options = dummy; + + } + + WebGLRenderTarget.call( this, size, size, options ); } - WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype ); - WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube; + WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype ); + WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget; - WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true; + WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true; - WebGLRenderTargetCube.prototype.fromEquirectangularTexture = function ( renderer, texture ) { + WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) { this.texture.type = texture.type; this.texture.format = texture.format; @@ -13564,7 +14028,7 @@ Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); - this.image = { data: data, width: width, height: height }; + this.image = { data: data || null, width: width || 1, height: height || 1 }; this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; @@ -13573,6 +14037,8 @@ this.flipY = false; this.unpackAlignment = 1; + this.needsUpdate = true; + } DataTexture.prototype = Object.create( Texture.prototype ); @@ -13580,232 +14046,6 @@ DataTexture.prototype.isDataTexture = true; - /** - * @author bhouston / http://clara.io - */ - - var _vector1 = new Vector3(); - var _vector2 = new Vector3(); - var _normalMatrix = new Matrix3(); - - function Plane( normal, constant ) { - - // normal is assumed to be normalized - - this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); - this.constant = ( constant !== undefined ) ? constant : 0; - - } - - Object.assign( Plane.prototype, { - - isPlane: true, - - set: function ( normal, constant ) { - - this.normal.copy( normal ); - this.constant = constant; - - return this; - - }, - - setComponents: function ( x, y, z, w ) { - - this.normal.set( x, y, z ); - this.constant = w; - - return this; - - }, - - setFromNormalAndCoplanarPoint: function ( normal, point ) { - - this.normal.copy( normal ); - this.constant = - point.dot( this.normal ); - - return this; - - }, - - setFromCoplanarPoints: function ( a, b, c ) { - - var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); - - // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? - - this.setFromNormalAndCoplanarPoint( normal, a ); - - return this; - - }, - - clone: function () { - - return new this.constructor().copy( this ); - - }, - - copy: function ( plane ) { - - this.normal.copy( plane.normal ); - this.constant = plane.constant; - - return this; - - }, - - normalize: function () { - - // Note: will lead to a divide by zero if the plane is invalid. - - var inverseNormalLength = 1.0 / this.normal.length(); - this.normal.multiplyScalar( inverseNormalLength ); - this.constant *= inverseNormalLength; - - return this; - - }, - - negate: function () { - - this.constant *= - 1; - this.normal.negate(); - - return this; - - }, - - distanceToPoint: function ( point ) { - - return this.normal.dot( point ) + this.constant; - - }, - - distanceToSphere: function ( sphere ) { - - return this.distanceToPoint( sphere.center ) - sphere.radius; - - }, - - projectPoint: function ( point, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Plane: .projectPoint() target is now required' ); - target = new Vector3(); - - } - - return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); - - }, - - intersectLine: function ( line, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Plane: .intersectLine() target is now required' ); - target = new Vector3(); - - } - - var direction = line.delta( _vector1 ); - - var denominator = this.normal.dot( direction ); - - if ( denominator === 0 ) { - - // line is coplanar, return origin - if ( this.distanceToPoint( line.start ) === 0 ) { - - return target.copy( line.start ); - - } - - // Unsure if this is the correct method to handle this case. - return undefined; - - } - - var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; - - if ( t < 0 || t > 1 ) { - - return undefined; - - } - - return target.copy( direction ).multiplyScalar( t ).add( line.start ); - - }, - - intersectsLine: function ( line ) { - - // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. - - var startSign = this.distanceToPoint( line.start ); - var endSign = this.distanceToPoint( line.end ); - - return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); - - }, - - intersectsBox: function ( box ) { - - return box.intersectsPlane( this ); - - }, - - intersectsSphere: function ( sphere ) { - - return sphere.intersectsPlane( this ); - - }, - - coplanarPoint: function ( target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); - target = new Vector3(); - - } - - return target.copy( this.normal ).multiplyScalar( - this.constant ); - - }, - - applyMatrix4: function ( matrix, optionalNormalMatrix ) { - - var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); - - var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); - - var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); - - this.constant = - referencePoint.dot( normal ); - - return this; - - }, - - translate: function ( offset ) { - - this.constant -= offset.dot( this.normal ); - - return this; - - }, - - equals: function ( plane ) { - - return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); - - } - - } ); - /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ @@ -13867,7 +14107,7 @@ }, - setFromMatrix: function ( m ) { + setFromProjectionMatrix: function ( m ) { var planes = this.planes; var me = m.elements; @@ -13891,7 +14131,7 @@ var geometry = object.geometry; - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); } _sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld ); @@ -13977,1179 +14217,1232 @@ } ); - var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; + /** + * Uniforms library for shared webgl shaders + */ - var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; + var UniformsLib = { - var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; + common: { - var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, - var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; + map: { value: null }, + uvTransform: { value: new Matrix3() }, + uv2Transform: { value: new Matrix3() }, - var begin_vertex = "vec3 transformed = vec3( position );"; + alphaMap: { value: null }, - var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; + }, - var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}"; + specularmap: { - var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; + specularMap: { value: null }, - var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; + }, - var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; + envmap: { - var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif"; + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + reflectivity: { value: 1.0 }, + refractionRatio: { value: 0.98 }, + maxMipLevel: { value: 0 } - var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; + }, - var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; + aomap: { - var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; + aoMap: { value: null }, + aoMapIntensity: { value: 1 } - var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; + }, - var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; + lightmap: { - var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n\tvec3 clearCoatNormal;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}"; + lightMap: { value: null }, + lightMapIntensity: { value: 1 } - var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif"; + }, - var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; + emissivemap: { - var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; + emissiveMap: { value: null } - var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif"; + }, - var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; + bumpmap: { - var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; + bumpMap: { value: null }, + bumpScale: { value: 1 } - var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; + }, - var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; + normalmap: { - var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; + normalMap: { value: null }, + normalScale: { value: new Vector2( 1, 1 ) } - var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; + }, - var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; + displacementmap: { - var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; + displacementMap: { value: null }, + displacementScale: { value: 1 }, + displacementBias: { value: 0 } - var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; + }, - var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; + roughnessmap: { - var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; + roughnessMap: { value: null } - var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; + }, - var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif"; + metalnessmap: { - var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif"; + metalnessMap: { value: null } - var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; + }, - var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif"; + gradientmap: { - var lights_pars_begin = "uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; + gradientMap: { value: null } - var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; + }, - var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; + fog: { - var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; + fogDensity: { value: 0.00025 }, + fogNear: { value: 1 }, + fogFar: { value: 2000 }, + fogColor: { value: new Color( 0xffffff ) } - var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif"; + }, - var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat ccDotNL = saturate( dot( geometry.clearCoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearCoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifndef STANDARD\n\t\tfloat ccDotNV = saturate( dot( geometry.clearCoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearCoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\tfloat clearCoatInv = 1.0 - clearCoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;\n\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; + lights: { - var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tgeometry.clearCoatNormal = clearCoatNormal;\n#else\n\tgeometry.clearCoatNormal = geometryNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif"; + ambientLightColor: { value: [] }, - var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearCoatNormal, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif"; + lightProbe: { value: [] }, - var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, irradiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif"; + directionalLights: { value: [], properties: { + direction: {}, + color: {} + } }, - var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; + directionalLightShadows: { value: [], properties: { + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, - var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif"; + directionalShadowMap: { value: [] }, + directionalShadowMatrix: { value: [] }, - var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; + spotLights: { value: [], properties: { + color: {}, + position: {}, + direction: {}, + distance: {}, + coneCos: {}, + penumbraCos: {}, + decay: {} + } }, - var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif"; + spotLightShadows: { value: [], properties: { + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, - var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; + spotShadowMap: { value: [] }, + spotShadowMatrix: { value: [] }, - var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; + pointLights: { value: [], properties: { + color: {}, + position: {}, + decay: {}, + distance: {} + } }, - var map_particle_fragment = "#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif"; + pointLightShadows: { value: [], properties: { + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {}, + shadowCameraNear: {}, + shadowCameraFar: {} + } }, - var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif"; + pointShadowMap: { value: [] }, + pointShadowMatrix: { value: [] }, - var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; + hemisphereLights: { value: [], properties: { + direction: {}, + skyColor: {}, + groundColor: {} + } }, - var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src + rectAreaLights: { value: [], properties: { + color: {}, + position: {}, + width: {}, + height: {} + } } - var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif"; + }, - var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; + points: { - var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + size: { value: 1.0 }, + scale: { value: 1.0 }, + map: { value: null }, + alphaMap: { value: null }, + uvTransform: { value: new Matrix3() } - var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; + }, - var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy = normalScale * mapN.xy;\n\t\t\tnormal = normalize( vTBN * mapN );\n\t\t#else\n\t\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t\t#endif\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; + sprite: { - var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#endif\n#endif\n#if ( defined ( USE_NORMALMAP ) && !defined ( OBJECTSPACE_NORMALMAP )) || defined ( USE_CLEARCOAT_NORMALMAP )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvec3 NfromST = cross( S, T );\n\t\t\tif( dot( NfromST, N ) > 0.0 ) {\n\t\t\t\tS *= -1.0;\n\t\t\t\tT *= -1.0;\n\t\t\t}\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif"; + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + center: { value: new Vector2( 0.5, 0.5 ) }, + rotation: { value: 0.0 }, + map: { value: null }, + alphaMap: { value: null }, + uvTransform: { value: new Matrix3() } - var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT_NORMALMAP\n vec3 clearCoatNormal = geometryNormal;\n#endif"; + } - var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearCoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearCoatNormalScale * mapN.xy;\n\t\tclearCoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearCoatNormal = perturbNormal2Arb( - vViewPosition, clearCoatNormal, clearCoatNormalScale, clearCoatNormalMap );\n\t#endif\n#endif"; + }; - var clearcoat_normalmap_pars_fragment = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearCoatNormalMap;\n\tuniform vec2 clearCoatNormalScale;\n#endif"; + /** + * @author mrdoob / http://mrdoob.com/ + */ - var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; + function WebGLAnimation() { - var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; + var context = null; + var isAnimating = false; + var animationLoop = null; - var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;"; + function onAnimationFrame( time, frame ) { - var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; + if ( isAnimating === false ) { return; } - var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; + animationLoop( time, frame ); - var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; + context.requestAnimationFrame( onAnimationFrame ); - var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; + } - var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; + return { - var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif"; + start: function () { - var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif"; + if ( isAnimating === true ) { return; } + if ( animationLoop === null ) { return; } - var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}"; + context.requestAnimationFrame( onAnimationFrame ); - var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; + isAnimating = true; - var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; + }, - var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; + stop: function () { - var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; + isAnimating = false; - var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; + }, - var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; + setAnimationLoop: function ( callback ) { - var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; + animationLoop = callback; - var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; + }, - var uv_pars_fragment = "#ifdef USE_UV\n\tvarying vec2 vUv;\n#endif"; + setContext: function ( value ) { - var uv_pars_vertex = "#ifdef USE_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif"; + context = value; - var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; + } - var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; + }; - var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif"; + } - var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif"; + /** + * @author mrdoob / http://mrdoob.com/ + */ - var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif"; + function WebGLAttributes( gl, capabilities ) { - var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + var isWebGL2 = capabilities.isWebGL2; - var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; + var buffers = new WeakMap(); - var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; + function createBuffer( attribute, bufferType ) { - var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}"; + var array = attribute.array; + var usage = attribute.usage; - var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}"; + var buffer = gl.createBuffer(); - var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + gl.bindBuffer( bufferType, buffer ); + gl.bufferData( bufferType, array, usage ); - var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; + attribute.onUploadCallback(); - var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}"; + var type = 5126; - var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + if ( array instanceof Float32Array ) { - var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; + type = 5126; - var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Float64Array ) { - var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; + console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); - var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Uint16Array ) { - var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + type = 5123; - var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Int16Array ) { - var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + type = 5122; - var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Uint32Array ) { - var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}"; + type = 5125; - var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Int32Array ) { - var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + type = 5124; - var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Int8Array ) { - var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; + type = 5120; - var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; + } else if ( array instanceof Uint8Array ) { - var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; + type = 5121; - var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } - var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + return { + buffer: buffer, + type: type, + bytesPerElement: array.BYTES_PER_ELEMENT, + version: attribute.version + }; - var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}"; + } - var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + function updateBuffer( buffer, attribute, bufferType ) { - var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}"; + var array = attribute.array; + var updateRange = attribute.updateRange; - var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; + gl.bindBuffer( bufferType, buffer ); - var ShaderChunk = { - alphamap_fragment: alphamap_fragment, - alphamap_pars_fragment: alphamap_pars_fragment, - alphatest_fragment: alphatest_fragment, - aomap_fragment: aomap_fragment, - aomap_pars_fragment: aomap_pars_fragment, - begin_vertex: begin_vertex, - beginnormal_vertex: beginnormal_vertex, - bsdfs: bsdfs, - bumpmap_pars_fragment: bumpmap_pars_fragment, - clipping_planes_fragment: clipping_planes_fragment, - clipping_planes_pars_fragment: clipping_planes_pars_fragment, - clipping_planes_pars_vertex: clipping_planes_pars_vertex, - clipping_planes_vertex: clipping_planes_vertex, - color_fragment: color_fragment, - color_pars_fragment: color_pars_fragment, - color_pars_vertex: color_pars_vertex, - color_vertex: color_vertex, - common: common, - cube_uv_reflection_fragment: cube_uv_reflection_fragment, - defaultnormal_vertex: defaultnormal_vertex, - displacementmap_pars_vertex: displacementmap_pars_vertex, - displacementmap_vertex: displacementmap_vertex, - emissivemap_fragment: emissivemap_fragment, - emissivemap_pars_fragment: emissivemap_pars_fragment, - encodings_fragment: encodings_fragment, - encodings_pars_fragment: encodings_pars_fragment, - envmap_fragment: envmap_fragment, - envmap_pars_fragment: envmap_pars_fragment, - envmap_pars_vertex: envmap_pars_vertex, - envmap_physical_pars_fragment: envmap_physical_pars_fragment, - envmap_vertex: envmap_vertex, - fog_vertex: fog_vertex, - fog_pars_vertex: fog_pars_vertex, - fog_fragment: fog_fragment, - fog_pars_fragment: fog_pars_fragment, - gradientmap_pars_fragment: gradientmap_pars_fragment, - lightmap_fragment: lightmap_fragment, - lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, - lights_pars_begin: lights_pars_begin, - lights_phong_fragment: lights_phong_fragment, - lights_phong_pars_fragment: lights_phong_pars_fragment, - lights_physical_fragment: lights_physical_fragment, - lights_physical_pars_fragment: lights_physical_pars_fragment, - lights_fragment_begin: lights_fragment_begin, - lights_fragment_maps: lights_fragment_maps, - lights_fragment_end: lights_fragment_end, - logdepthbuf_fragment: logdepthbuf_fragment, - logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, - logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, - logdepthbuf_vertex: logdepthbuf_vertex, - map_fragment: map_fragment, - map_pars_fragment: map_pars_fragment, - map_particle_fragment: map_particle_fragment, - map_particle_pars_fragment: map_particle_pars_fragment, - metalnessmap_fragment: metalnessmap_fragment, - metalnessmap_pars_fragment: metalnessmap_pars_fragment, - morphnormal_vertex: morphnormal_vertex, - morphtarget_pars_vertex: morphtarget_pars_vertex, - morphtarget_vertex: morphtarget_vertex, - normal_fragment_begin: normal_fragment_begin, - normal_fragment_maps: normal_fragment_maps, - normalmap_pars_fragment: normalmap_pars_fragment, - clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, - clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, - clearcoat_normalmap_pars_fragment: clearcoat_normalmap_pars_fragment, - packing: packing, - premultiplied_alpha_fragment: premultiplied_alpha_fragment, - project_vertex: project_vertex, - dithering_fragment: dithering_fragment, - dithering_pars_fragment: dithering_pars_fragment, - roughnessmap_fragment: roughnessmap_fragment, - roughnessmap_pars_fragment: roughnessmap_pars_fragment, - shadowmap_pars_fragment: shadowmap_pars_fragment, - shadowmap_pars_vertex: shadowmap_pars_vertex, - shadowmap_vertex: shadowmap_vertex, - shadowmask_pars_fragment: shadowmask_pars_fragment, - skinbase_vertex: skinbase_vertex, - skinning_pars_vertex: skinning_pars_vertex, - skinning_vertex: skinning_vertex, - skinnormal_vertex: skinnormal_vertex, - specularmap_fragment: specularmap_fragment, - specularmap_pars_fragment: specularmap_pars_fragment, - tonemapping_fragment: tonemapping_fragment, - tonemapping_pars_fragment: tonemapping_pars_fragment, - uv_pars_fragment: uv_pars_fragment, - uv_pars_vertex: uv_pars_vertex, - uv_vertex: uv_vertex, - uv2_pars_fragment: uv2_pars_fragment, - uv2_pars_vertex: uv2_pars_vertex, - uv2_vertex: uv2_vertex, - worldpos_vertex: worldpos_vertex, + if ( updateRange.count === - 1 ) { - background_frag: background_frag, - background_vert: background_vert, - cube_frag: cube_frag, - cube_vert: cube_vert, - depth_frag: depth_frag, - depth_vert: depth_vert, - distanceRGBA_frag: distanceRGBA_frag, - distanceRGBA_vert: distanceRGBA_vert, - equirect_frag: equirect_frag, - equirect_vert: equirect_vert, - linedashed_frag: linedashed_frag, - linedashed_vert: linedashed_vert, - meshbasic_frag: meshbasic_frag, - meshbasic_vert: meshbasic_vert, - meshlambert_frag: meshlambert_frag, - meshlambert_vert: meshlambert_vert, - meshmatcap_frag: meshmatcap_frag, - meshmatcap_vert: meshmatcap_vert, - meshphong_frag: meshphong_frag, - meshphong_vert: meshphong_vert, - meshphysical_frag: meshphysical_frag, - meshphysical_vert: meshphysical_vert, - normal_frag: normal_frag, - normal_vert: normal_vert, - points_frag: points_frag, - points_vert: points_vert, - shadow_frag: shadow_frag, - shadow_vert: shadow_vert, - sprite_frag: sprite_frag, - sprite_vert: sprite_vert - }; + // Not using update ranges - /** - * Uniforms library for shared webgl shaders - */ + gl.bufferSubData( bufferType, 0, array ); - var UniformsLib = { + } else { - common: { + if ( isWebGL2 ) { - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array, updateRange.offset, updateRange.count ); - map: { value: null }, - uvTransform: { value: new Matrix3() }, + } else { - alphaMap: { value: null }, + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); - }, + } - specularmap: { + updateRange.count = - 1; // reset range - specularMap: { value: null }, + } - }, + } - envmap: { + // - envMap: { value: null }, - flipEnvMap: { value: - 1 }, - reflectivity: { value: 1.0 }, - refractionRatio: { value: 0.98 }, - maxMipLevel: { value: 0 } + function get( attribute ) { - }, + if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; } - aomap: { + return buffers.get( attribute ); - aoMap: { value: null }, - aoMapIntensity: { value: 1 } + } - }, + function remove( attribute ) { - lightmap: { + if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; } - lightMap: { value: null }, - lightMapIntensity: { value: 1 } + var data = buffers.get( attribute ); - }, + if ( data ) { - emissivemap: { + gl.deleteBuffer( data.buffer ); - emissiveMap: { value: null } + buffers.delete( attribute ); - }, + } - bumpmap: { + } - bumpMap: { value: null }, - bumpScale: { value: 1 } + function update( attribute, bufferType ) { - }, + if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; } - normalmap: { + var data = buffers.get( attribute ); - normalMap: { value: null }, - normalScale: { value: new Vector2( 1, 1 ) } + if ( data === undefined ) { - }, + buffers.set( attribute, createBuffer( attribute, bufferType ) ); - displacementmap: { + } else if ( data.version < attribute.version ) { - displacementMap: { value: null }, - displacementScale: { value: 1 }, - displacementBias: { value: 0 } + updateBuffer( data.buffer, attribute, bufferType ); - }, + data.version = attribute.version; - roughnessmap: { + } - roughnessMap: { value: null } + } - }, + return { - metalnessmap: { + get: get, + remove: remove, + update: update - metalnessMap: { value: null } + }; - }, + } - gradientmap: { + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - gradientMap: { value: null } + // PlaneGeometry - }, + function PlaneGeometry( width, height, widthSegments, heightSegments ) { - fog: { + Geometry.call( this ); - fogDensity: { value: 0.00025 }, - fogNear: { value: 1 }, - fogFar: { value: 2000 }, - fogColor: { value: new Color( 0xffffff ) } + this.type = 'PlaneGeometry'; - }, + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - lights: { + this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); + this.mergeVertices(); - ambientLightColor: { value: [] }, + } - lightProbe: { value: [] }, + PlaneGeometry.prototype = Object.create( Geometry.prototype ); + PlaneGeometry.prototype.constructor = PlaneGeometry; - directionalLights: { value: [], properties: { - direction: {}, - color: {}, + // PlaneBufferGeometry - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, + function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { - directionalShadowMap: { value: [] }, - directionalShadowMatrix: { value: [] }, + BufferGeometry.call( this ); - spotLights: { value: [], properties: { - color: {}, - position: {}, - direction: {}, - distance: {}, - coneCos: {}, - penumbraCos: {}, - decay: {}, + this.type = 'PlaneBufferGeometry'; - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - spotShadowMap: { value: [] }, - spotShadowMatrix: { value: [] }, + width = width || 1; + height = height || 1; - pointLights: { value: [], properties: { - color: {}, - position: {}, - decay: {}, - distance: {}, + var width_half = width / 2; + var height_half = height / 2; - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {}, - shadowCameraNear: {}, - shadowCameraFar: {} - } }, + var gridX = Math.floor( widthSegments ) || 1; + var gridY = Math.floor( heightSegments ) || 1; - pointShadowMap: { value: [] }, - pointShadowMatrix: { value: [] }, + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; - hemisphereLights: { value: [], properties: { - direction: {}, - skyColor: {}, - groundColor: {} - } }, + var segment_width = width / gridX; + var segment_height = height / gridY; - // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src - rectAreaLights: { value: [], properties: { - color: {}, - position: {}, - width: {}, - height: {} - } } + var ix, iy; - }, + // buffers - points: { + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - size: { value: 1.0 }, - scale: { value: 1.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } + // generate vertices, normals and uvs - }, + for ( iy = 0; iy < gridY1; iy ++ ) { - sprite: { + var y = iy * segment_height - height_half; - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - center: { value: new Vector2( 0.5, 0.5 ) }, - rotation: { value: 0.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } + for ( ix = 0; ix < gridX1; ix ++ ) { + + var x = ix * segment_width - width_half; + + vertices.push( x, - y, 0 ); + + normals.push( 0, 0, 1 ); + + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); + + } } - }; + // indices - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - */ + for ( iy = 0; iy < gridY; iy ++ ) { - var ShaderLib = { + for ( ix = 0; ix < gridX; ix ++ ) { - basic: { + var a = ix + gridX1 * iy; + var b = ix + gridX1 * ( iy + 1 ); + var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = ( ix + 1 ) + gridX1 * iy; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.fog - ] ), + // faces - vertexShader: ShaderChunk.meshbasic_vert, - fragmentShader: ShaderChunk.meshbasic_frag + indices.push( a, b, d ); + indices.push( b, c, d ); - }, + } - lambert: { + } - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) } - } - ] ), + // build geometry - vertexShader: ShaderChunk.meshlambert_vert, - fragmentShader: ShaderChunk.meshlambert_frag + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - }, + } - phong: { + PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.gradientmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - specular: { value: new Color( 0x111111 ) }, - shininess: { value: 30 } - } - ] ), + var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; - vertexShader: ShaderChunk.meshphong_vert, - fragmentShader: ShaderChunk.meshphong_frag + var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - }, + var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; - standard: { + var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.roughnessmap, - UniformsLib.metalnessmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - roughness: { value: 0.5 }, - metalness: { value: 0.5 }, - envMapIntensity: { value: 1 } // temporary - } - ] ), + var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag + var begin_vertex = "vec3 transformed = vec3( position );"; - }, + var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; - matcap: { + var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.fog, - { - matcap: { value: null } - } - ] ), + var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; - vertexShader: ShaderChunk.meshmatcap_vert, - fragmentShader: ShaderChunk.meshmatcap_frag + var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; - }, + var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; - points: { + var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\tvarying vec3 vViewPosition;\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.points, - UniformsLib.fog - ] ), + var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; - vertexShader: ShaderChunk.points_vert, - fragmentShader: ShaderChunk.points_frag + var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; - }, + var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - dashed: { + var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.fog, - { - scale: { value: 1 }, - dashSize: { value: 1 }, - totalSize: { value: 2 } - } - ] ), + var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; - vertexShader: ShaderChunk.linedashed_vert, - fragmentShader: ShaderChunk.linedashed_frag + var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}"; - }, + var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_maxMipLevel 8.0\n#define cubeUV_minMipLevel 4.0\n#define cubeUV_maxTileSize 256.0\n#define cubeUV_minTileSize 16.0\nfloat getFace(vec3 direction) {\n vec3 absDirection = abs(direction);\n float face = -1.0;\n if (absDirection.x > absDirection.z) {\n if (absDirection.x > absDirection.y)\n face = direction.x > 0.0 ? 0.0 : 3.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n } else {\n if (absDirection.z > absDirection.y)\n face = direction.z > 0.0 ? 2.0 : 5.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n }\n return face;\n}\nvec2 getUV(vec3 direction, float face) {\n vec2 uv;\n if (face == 0.0) {\n uv = vec2(-direction.z, direction.y) / abs(direction.x);\n } else if (face == 1.0) {\n uv = vec2(direction.x, -direction.z) / abs(direction.y);\n } else if (face == 2.0) {\n uv = direction.xy / abs(direction.z);\n } else if (face == 3.0) {\n uv = vec2(direction.z, direction.y) / abs(direction.x);\n } else if (face == 4.0) {\n uv = direction.xz / abs(direction.y);\n } else {\n uv = vec2(-direction.x, direction.y) / abs(direction.z);\n }\n return 0.5 * (uv + 1.0);\n}\nvec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n float face = getFace(direction);\n float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n mipInt = max(mipInt, cubeUV_minMipLevel);\n float faceSize = exp2(mipInt);\n float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n vec2 uv = getUV(direction, face) * (faceSize - 1.0);\n vec2 f = fract(uv);\n uv += 0.5 - f;\n if (face > 2.0) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize;\n if(mipInt < cubeUV_maxMipLevel){\n uv.y += 2.0 * cubeUV_maxTileSize;\n }\n uv.y += filterInt * 2.0 * cubeUV_minTileSize;\n uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n uv *= texelSize;\n vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x += texelSize;\n vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.y += texelSize;\n vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x -= texelSize;\n vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n vec3 tm = mix(tl, tr, f.x);\n vec3 bm = mix(bl, br, f.x);\n return mix(tm, bm, f.y);\n}\n#define r0 1.0\n#define v0 0.339\n#define m0 -2.0\n#define r1 0.8\n#define v1 0.276\n#define m1 -1.0\n#define r4 0.4\n#define v4 0.046\n#define m4 2.0\n#define r5 0.305\n#define v5 0.016\n#define m5 3.0\n#define r6 0.21\n#define v6 0.0038\n#define m6 4.0\nfloat roughnessToMip(float roughness) {\n float mip = 0.0;\n if (roughness >= r1) {\n mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n } else if (roughness >= r4) {\n mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n } else if (roughness >= r5) {\n mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n } else if (roughness >= r6) {\n mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n } else {\n mip = -2.0 * log2(1.16 * roughness); }\n return mip;\n}\nvec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {\n float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);\n float mipF = fract(mip);\n float mipInt = floor(mip);\n vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);\n if (mipF == 0.0) {\n return vec4(color0, 1.0);\n } else {\n vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);\n return vec4(mix(color0, color1, mipF), 1.0);\n }\n}\n#endif"; - depth: { + var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.displacementmap - ] ), + var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; - vertexShader: ShaderChunk.depth_vert, - fragmentShader: ShaderChunk.depth_frag + var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; - }, + var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; - normal: { + var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - { - opacity: { value: 1.0 } - } - ] ), + var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; - vertexShader: ShaderChunk.normal_vert, - fragmentShader: ShaderChunk.normal_frag + var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; - }, + var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\t\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; - sprite: { + var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.sprite, - UniformsLib.fog - ] ), + var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; - vertexShader: ShaderChunk.sprite_vert, - fragmentShader: ShaderChunk.sprite_frag + var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; - }, + var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) { \n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; - background: { + var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; - uniforms: { - uvTransform: { value: new Matrix3() }, - t2D: { value: null }, - }, + var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; - vertexShader: ShaderChunk.background_vert, - fragmentShader: ShaderChunk.background_frag + var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; - }, - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ + var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; - cube: { + var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; - uniforms: { - tCube: { value: null }, - tFlip: { value: - 1 }, - opacity: { value: 1.0 } - }, + var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif"; - vertexShader: ShaderChunk.cube_vert, - fragmentShader: ShaderChunk.cube_frag + var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; - }, + var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif"; - equirect: { + var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; - uniforms: { - tEquirect: { value: null }, - }, + var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; - vertexShader: ShaderChunk.equirect_vert, - fragmentShader: ShaderChunk.equirect_frag + var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; - }, + var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)"; - distanceRGBA: { + var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.displacementmap, - { - referencePosition: { value: new Vector3() }, - nearDistance: { value: 1 }, - farDistance: { value: 1000 } - } - ] ), + var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; - vertexShader: ShaderChunk.distanceRGBA_vert, - fragmentShader: ShaderChunk.distanceRGBA_frag + var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif"; - }, + var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; - shadow: { + var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.lights, - UniformsLib.fog, - { - color: { value: new Color( 0x00000 ) }, - opacity: { value: 1.0 } - }, - ] ), + var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif"; - vertexShader: ShaderChunk.shadow_vert, - fragmentShader: ShaderChunk.shadow_frag + var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; - } + var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; - }; + var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif"; - ShaderLib.physical = { + var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; - uniforms: mergeUniforms( [ - ShaderLib.standard.uniforms, - { - clearCoat: { value: 0 }, - clearCoatRoughness: { value: 0 }, - clearCoatNormalScale: { value: new Vector2( 1, 1 ) }, - clearCoatNormalMap: { value: null }, - } - ] ), + var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif"; - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag + var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; - }; + var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; - /** - * @author mrdoob / http://mrdoob.com/ - */ + var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; - function WebGLAnimation() { + var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - var context = null; - var isAnimating = false; - var animationLoop = null; + var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; - function onAnimationFrame( time, frame ) { + var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; - if ( isAnimating === false ) return; + var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif"; - animationLoop( time, frame ); + var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; - context.requestAnimationFrame( onAnimationFrame ); + var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; - } + var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; - return { + var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; - start: function () { + var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif"; - if ( isAnimating === true ) return; - if ( animationLoop === null ) return; + var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; - context.requestAnimationFrame( onAnimationFrame ); + var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif"; - isAnimating = true; + var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; - }, + var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; - stop: function () { + var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; - isAnimating = false; + var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; - }, + var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; - setAnimationLoop: function ( callback ) { + var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; - animationLoop = callback; + var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; - }, + var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; - setContext: function ( value ) { + var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; - context = value; + var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif"; - } + var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif"; - }; + var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}"; - } + var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; - /** - * @author mrdoob / http://mrdoob.com/ - */ + var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; - function WebGLAttributes( gl ) { + var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; - var buffers = new WeakMap(); + var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; - function createBuffer( attribute, bufferType ) { + var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; - var array = attribute.array; - var usage = attribute.dynamic ? 35048 : 35044; + var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; - var buffer = gl.createBuffer(); + var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; - gl.bindBuffer( bufferType, buffer ); - gl.bufferData( bufferType, array, usage ); + var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; - attribute.onUploadCallback(); + var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; - var type = 5126; + var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif"; - if ( array instanceof Float32Array ) { + var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; - type = 5126; + var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; - } else if ( array instanceof Float64Array ) { + var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; - console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); + var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; - } else if ( array instanceof Uint16Array ) { + var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif"; - type = 5123; + var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; - } else if ( array instanceof Int16Array ) { + var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; - type = 5122; + var cube_frag = "#include \nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include \n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; - } else if ( array instanceof Uint32Array ) { + var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}"; - type = 5125; + var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}"; - } else if ( array instanceof Int32Array ) { + var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}"; - type = 5124; + var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; - } else if ( array instanceof Int8Array ) { + var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}"; - type = 5120; + var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; - } else if ( array instanceof Uint8Array ) { + var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; - type = 5121; + var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } + var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; - return { - buffer: buffer, - type: type, - bytesPerElement: array.BYTES_PER_ELEMENT, - version: attribute.version - }; + var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } + var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - function updateBuffer( buffer, attribute, bufferType ) { + var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - var array = attribute.array; - var updateRange = attribute.updateRange; + var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - gl.bindBuffer( bufferType, buffer ); + var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - if ( attribute.dynamic === false ) { + var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}"; - gl.bufferData( bufferType, array, 35044 ); + var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } else if ( updateRange.count === - 1 ) { + var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; - // Not using update ranges + var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - gl.bufferSubData( bufferType, 0, array ); + var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } else if ( updateRange.count === 0 ) { + var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' ); + var meshphysical_vert = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; - } else { + var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; - gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, - array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); + var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; - updateRange.count = - 1; // reset range + var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } + var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } + var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n\t#include \n\t#include \n}"; - // + var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - function get( attribute ) { + var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}"; - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; - return buffers.get( attribute ); + var ShaderChunk = { + alphamap_fragment: alphamap_fragment, + alphamap_pars_fragment: alphamap_pars_fragment, + alphatest_fragment: alphatest_fragment, + aomap_fragment: aomap_fragment, + aomap_pars_fragment: aomap_pars_fragment, + begin_vertex: begin_vertex, + beginnormal_vertex: beginnormal_vertex, + bsdfs: bsdfs, + bumpmap_pars_fragment: bumpmap_pars_fragment, + clipping_planes_fragment: clipping_planes_fragment, + clipping_planes_pars_fragment: clipping_planes_pars_fragment, + clipping_planes_pars_vertex: clipping_planes_pars_vertex, + clipping_planes_vertex: clipping_planes_vertex, + color_fragment: color_fragment, + color_pars_fragment: color_pars_fragment, + color_pars_vertex: color_pars_vertex, + color_vertex: color_vertex, + common: common, + cube_uv_reflection_fragment: cube_uv_reflection_fragment, + defaultnormal_vertex: defaultnormal_vertex, + displacementmap_pars_vertex: displacementmap_pars_vertex, + displacementmap_vertex: displacementmap_vertex, + emissivemap_fragment: emissivemap_fragment, + emissivemap_pars_fragment: emissivemap_pars_fragment, + encodings_fragment: encodings_fragment, + encodings_pars_fragment: encodings_pars_fragment, + envmap_fragment: envmap_fragment, + envmap_common_pars_fragment: envmap_common_pars_fragment, + envmap_pars_fragment: envmap_pars_fragment, + envmap_pars_vertex: envmap_pars_vertex, + envmap_physical_pars_fragment: envmap_physical_pars_fragment, + envmap_vertex: envmap_vertex, + fog_vertex: fog_vertex, + fog_pars_vertex: fog_pars_vertex, + fog_fragment: fog_fragment, + fog_pars_fragment: fog_pars_fragment, + gradientmap_pars_fragment: gradientmap_pars_fragment, + lightmap_fragment: lightmap_fragment, + lightmap_pars_fragment: lightmap_pars_fragment, + lights_lambert_vertex: lights_lambert_vertex, + lights_pars_begin: lights_pars_begin, + lights_toon_fragment: lights_toon_fragment, + lights_toon_pars_fragment: lights_toon_pars_fragment, + lights_phong_fragment: lights_phong_fragment, + lights_phong_pars_fragment: lights_phong_pars_fragment, + lights_physical_fragment: lights_physical_fragment, + lights_physical_pars_fragment: lights_physical_pars_fragment, + lights_fragment_begin: lights_fragment_begin, + lights_fragment_maps: lights_fragment_maps, + lights_fragment_end: lights_fragment_end, + logdepthbuf_fragment: logdepthbuf_fragment, + logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, + logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, + logdepthbuf_vertex: logdepthbuf_vertex, + map_fragment: map_fragment, + map_pars_fragment: map_pars_fragment, + map_particle_fragment: map_particle_fragment, + map_particle_pars_fragment: map_particle_pars_fragment, + metalnessmap_fragment: metalnessmap_fragment, + metalnessmap_pars_fragment: metalnessmap_pars_fragment, + morphnormal_vertex: morphnormal_vertex, + morphtarget_pars_vertex: morphtarget_pars_vertex, + morphtarget_vertex: morphtarget_vertex, + normal_fragment_begin: normal_fragment_begin, + normal_fragment_maps: normal_fragment_maps, + normalmap_pars_fragment: normalmap_pars_fragment, + clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, + clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, + clearcoat_pars_fragment: clearcoat_pars_fragment, + packing: packing, + premultiplied_alpha_fragment: premultiplied_alpha_fragment, + project_vertex: project_vertex, + dithering_fragment: dithering_fragment, + dithering_pars_fragment: dithering_pars_fragment, + roughnessmap_fragment: roughnessmap_fragment, + roughnessmap_pars_fragment: roughnessmap_pars_fragment, + shadowmap_pars_fragment: shadowmap_pars_fragment, + shadowmap_pars_vertex: shadowmap_pars_vertex, + shadowmap_vertex: shadowmap_vertex, + shadowmask_pars_fragment: shadowmask_pars_fragment, + skinbase_vertex: skinbase_vertex, + skinning_pars_vertex: skinning_pars_vertex, + skinning_vertex: skinning_vertex, + skinnormal_vertex: skinnormal_vertex, + specularmap_fragment: specularmap_fragment, + specularmap_pars_fragment: specularmap_pars_fragment, + tonemapping_fragment: tonemapping_fragment, + tonemapping_pars_fragment: tonemapping_pars_fragment, + uv_pars_fragment: uv_pars_fragment, + uv_pars_vertex: uv_pars_vertex, + uv_vertex: uv_vertex, + uv2_pars_fragment: uv2_pars_fragment, + uv2_pars_vertex: uv2_pars_vertex, + uv2_vertex: uv2_vertex, + worldpos_vertex: worldpos_vertex, - } + background_frag: background_frag, + background_vert: background_vert, + cube_frag: cube_frag, + cube_vert: cube_vert, + depth_frag: depth_frag, + depth_vert: depth_vert, + distanceRGBA_frag: distanceRGBA_frag, + distanceRGBA_vert: distanceRGBA_vert, + equirect_frag: equirect_frag, + equirect_vert: equirect_vert, + linedashed_frag: linedashed_frag, + linedashed_vert: linedashed_vert, + meshbasic_frag: meshbasic_frag, + meshbasic_vert: meshbasic_vert, + meshlambert_frag: meshlambert_frag, + meshlambert_vert: meshlambert_vert, + meshmatcap_frag: meshmatcap_frag, + meshmatcap_vert: meshmatcap_vert, + meshtoon_frag: meshtoon_frag, + meshtoon_vert: meshtoon_vert, + meshphong_frag: meshphong_frag, + meshphong_vert: meshphong_vert, + meshphysical_frag: meshphysical_frag, + meshphysical_vert: meshphysical_vert, + normal_frag: normal_frag, + normal_vert: normal_vert, + points_frag: points_frag, + points_vert: points_vert, + shadow_frag: shadow_frag, + shadow_vert: shadow_vert, + sprite_frag: sprite_frag, + sprite_vert: sprite_vert + }; + + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + * @author mikael emtinger / http://gomo.se/ + */ + + var ShaderLib = { + + basic: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.fog + ] ), + + vertexShader: ShaderChunk.meshbasic_vert, + fragmentShader: ShaderChunk.meshbasic_frag + + }, + + lambert: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) } + } + ] ), + + vertexShader: ShaderChunk.meshlambert_vert, + fragmentShader: ShaderChunk.meshlambert_frag + + }, + + phong: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + specular: { value: new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), - function remove( attribute ) { + vertexShader: ShaderChunk.meshphong_vert, + fragmentShader: ShaderChunk.meshphong_frag - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + }, - var data = buffers.get( attribute ); + standard: { - if ( data ) { + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.roughnessmap, + UniformsLib.metalnessmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + roughness: { value: 0.5 }, + metalness: { value: 0.5 }, + envMapIntensity: { value: 1 } // temporary + } + ] ), - gl.deleteBuffer( data.buffer ); + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag - buffers.delete( attribute ); + }, - } + toon: { - } + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.gradientmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + specular: { value: new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), - function update( attribute, bufferType ) { + vertexShader: ShaderChunk.meshtoon_vert, + fragmentShader: ShaderChunk.meshtoon_frag - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + }, - var data = buffers.get( attribute ); + matcap: { - if ( data === undefined ) { + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.fog, + { + matcap: { value: null } + } + ] ), - buffers.set( attribute, createBuffer( attribute, bufferType ) ); + vertexShader: ShaderChunk.meshmatcap_vert, + fragmentShader: ShaderChunk.meshmatcap_frag - } else if ( data.version < attribute.version ) { + }, - updateBuffer( data.buffer, attribute, bufferType ); + points: { - data.version = attribute.version; + uniforms: mergeUniforms( [ + UniformsLib.points, + UniformsLib.fog + ] ), - } + vertexShader: ShaderChunk.points_vert, + fragmentShader: ShaderChunk.points_frag - } + }, - return { + dashed: { - get: get, - remove: remove, - update: update + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.fog, + { + scale: { value: 1 }, + dashSize: { value: 1 }, + totalSize: { value: 2 } + } + ] ), - }; + vertexShader: ShaderChunk.linedashed_vert, + fragmentShader: ShaderChunk.linedashed_frag - } + }, - /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + depth: { - // PlaneGeometry + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap + ] ), - function PlaneGeometry( width, height, widthSegments, heightSegments ) { + vertexShader: ShaderChunk.depth_vert, + fragmentShader: ShaderChunk.depth_frag - Geometry.call( this ); + }, - this.type = 'PlaneGeometry'; + normal: { - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + { + opacity: { value: 1.0 } + } + ] ), - this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); - this.mergeVertices(); + vertexShader: ShaderChunk.normal_vert, + fragmentShader: ShaderChunk.normal_frag - } + }, - PlaneGeometry.prototype = Object.create( Geometry.prototype ); - PlaneGeometry.prototype.constructor = PlaneGeometry; + sprite: { - // PlaneBufferGeometry + uniforms: mergeUniforms( [ + UniformsLib.sprite, + UniformsLib.fog + ] ), - function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { + vertexShader: ShaderChunk.sprite_vert, + fragmentShader: ShaderChunk.sprite_frag - BufferGeometry.call( this ); + }, - this.type = 'PlaneBufferGeometry'; + background: { - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + uniforms: { + uvTransform: { value: new Matrix3() }, + t2D: { value: null }, + }, - width = width || 1; - height = height || 1; + vertexShader: ShaderChunk.background_vert, + fragmentShader: ShaderChunk.background_frag - var width_half = width / 2; - var height_half = height / 2; + }, + /* ------------------------------------------------------------------------- + // Cube map shader + ------------------------------------------------------------------------- */ - var gridX = Math.floor( widthSegments ) || 1; - var gridY = Math.floor( heightSegments ) || 1; + cube: { - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + uniforms: mergeUniforms( [ + UniformsLib.envmap, + { + opacity: { value: 1.0 } + } + ] ), - var segment_width = width / gridX; - var segment_height = height / gridY; + vertexShader: ShaderChunk.cube_vert, + fragmentShader: ShaderChunk.cube_frag - var ix, iy; + }, - // buffers + equirect: { - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + uniforms: { + tEquirect: { value: null }, + }, - // generate vertices, normals and uvs + vertexShader: ShaderChunk.equirect_vert, + fragmentShader: ShaderChunk.equirect_frag - for ( iy = 0; iy < gridY1; iy ++ ) { + }, - var y = iy * segment_height - height_half; + distanceRGBA: { - for ( ix = 0; ix < gridX1; ix ++ ) { + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + referencePosition: { value: new Vector3() }, + nearDistance: { value: 1 }, + farDistance: { value: 1000 } + } + ] ), - var x = ix * segment_width - width_half; + vertexShader: ShaderChunk.distanceRGBA_vert, + fragmentShader: ShaderChunk.distanceRGBA_frag - vertices.push( x, - y, 0 ); + }, - normals.push( 0, 0, 1 ); + shadow: { - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + uniforms: mergeUniforms( [ + UniformsLib.lights, + UniformsLib.fog, + { + color: { value: new Color( 0x00000 ) }, + opacity: { value: 1.0 } + } ] ), - } + vertexShader: ShaderChunk.shadow_vert, + fragmentShader: ShaderChunk.shadow_frag } - // indices - - for ( iy = 0; iy < gridY; iy ++ ) { - - for ( ix = 0; ix < gridX; ix ++ ) { - - var a = ix + gridX1 * iy; - var b = ix + gridX1 * ( iy + 1 ); - var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = ( ix + 1 ) + gridX1 * iy; - - // faces + }; - indices.push( a, b, d ); - indices.push( b, c, d ); + ShaderLib.physical = { + uniforms: mergeUniforms( [ + ShaderLib.standard.uniforms, + { + clearcoat: { value: 0 }, + clearcoatMap: { value: null }, + clearcoatRoughness: { value: 0 }, + clearcoatRoughnessMap: { value: null }, + clearcoatNormalScale: { value: new Vector2( 1, 1 ) }, + clearcoatNormalMap: { value: null }, + sheen: { value: new Color( 0x000000 ) }, + transparency: { value: 0 }, } + ] ), - } - - // build geometry - - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - - } + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag - PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; + }; /** * @author mrdoob / http://mrdoob.com/ @@ -15162,10 +15455,10 @@ var planeMesh; var boxMesh; - // Store the current background texture and its `version` - // so we can recompile the material accordingly. + var currentBackground = null; var currentBackgroundVersion = 0; + var currentTonemapping = null; function render( renderList, scene, camera, forceClear ) { @@ -15174,8 +15467,8 @@ // Ignore background in AR // TODO: Reconsider this. - var vr = renderer.vr; - var session = vr.getSession && vr.getSession(); + var xr = renderer.xr; + var session = xr.getSession && xr.getSession(); if ( session && session.environmentBlendMode === 'additive' ) { @@ -15186,15 +15479,11 @@ if ( background === null ) { setClear( clearColor, clearAlpha ); - currentBackground = null; - currentBackgroundVersion = 0; } else if ( background && background.isColor ) { setClear( background, 1 ); forceClear = true; - currentBackground = null; - currentBackgroundVersion = 0; } @@ -15204,7 +15493,7 @@ } - if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) { + if ( background && ( background.isCubeTexture || background.isWebGLCubeRenderTarget || background.mapping === CubeUVReflectionMapping ) ) { if ( boxMesh === undefined ) { @@ -15222,8 +15511,8 @@ } ) ); - boxMesh.geometry.removeAttribute( 'normal' ); - boxMesh.geometry.removeAttribute( 'uv' ); + boxMesh.geometry.deleteAttribute( 'normal' ); + boxMesh.geometry.deleteAttribute( 'uv' ); boxMesh.onBeforeRender = function ( renderer, scene, camera ) { @@ -15232,11 +15521,11 @@ }; // enable code injection for non-built-in material - Object.defineProperty( boxMesh.material, 'map', { + Object.defineProperty( boxMesh.material, 'envMap', { get: function () { - return this.uniforms.tCube.value; + return this.uniforms.envMap.value; } @@ -15246,17 +15535,20 @@ } - var texture = background.isWebGLRenderTargetCube ? background.texture : background; - boxMesh.material.uniforms.tCube.value = texture; - boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1; + var texture = background.isWebGLCubeRenderTarget ? background.texture : background; + + boxMesh.material.uniforms.envMap.value = texture; + boxMesh.material.uniforms.flipEnvMap.value = texture.isCubeTexture ? - 1 : 1; if ( currentBackground !== background || - currentBackgroundVersion !== texture.version ) { + currentBackgroundVersion !== texture.version || + currentTonemapping !== renderer.toneMapping ) { boxMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = texture.version; + currentTonemapping = renderer.toneMapping; } @@ -15281,7 +15573,7 @@ } ) ); - planeMesh.geometry.removeAttribute( 'normal' ); + planeMesh.geometry.deleteAttribute( 'normal' ); // enable code injection for non-built-in material Object.defineProperty( planeMesh.material, 'map', { @@ -15309,12 +15601,14 @@ planeMesh.material.uniforms.uvTransform.value.copy( background.matrix ); if ( currentBackground !== background || - currentBackgroundVersion !== background.version ) { + currentBackgroundVersion !== background.version || + currentTonemapping !== renderer.toneMapping ) { planeMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; + currentTonemapping = renderer.toneMapping; } @@ -15369,6 +15663,8 @@ function WebGLBufferRenderer( gl, extensions, info, capabilities ) { + var isWebGL2 = capabilities.isWebGL2; + var mode; function setMode( value ) { @@ -15385,17 +15681,21 @@ } - function renderInstances( geometry, start, count ) { + function renderInstances( geometry, start, count, primcount ) { - var extension; + if ( primcount === 0 ) { return; } - if ( capabilities.isWebGL2 ) { + var extension, methodName; + + if ( isWebGL2 ) { extension = gl; + methodName = 'drawArraysInstanced'; } else { extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawArraysInstancedANGLE'; if ( extension === null ) { @@ -15406,9 +15706,9 @@ } - extension[ capabilities.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount ); + extension[ methodName ]( mode, start, count, primcount ); - info.update( count, mode, geometry.maxInstancedCount ); + info.update( count, mode, primcount ); } @@ -15430,7 +15730,7 @@ function getMaxAnisotropy() { - if ( maxAnisotropy !== undefined ) return maxAnisotropy; + if ( maxAnisotropy !== undefined ) { return maxAnisotropy; } var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); @@ -15453,7 +15753,7 @@ if ( precision === 'highp' ) { if ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 && - gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) { + gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) { return 'highp'; @@ -15466,7 +15766,7 @@ if ( precision === 'mediump' ) { if ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 && - gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) { + gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) { return 'mediump'; @@ -15478,7 +15778,10 @@ } - var isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext; + /* eslint-disable no-undef */ + var isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) || + ( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext ); + /* eslint-enable no-undef */ var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; var maxPrecision = getMaxPrecision( precision ); @@ -15690,6 +15993,7 @@ } scope.numPlanes = nPlanes; + scope.numIntersection = 0; return dstArray; @@ -15762,13 +16066,13 @@ function WebGLGeometries( gl, attributes, info ) { - var geometries = {}; - var wireframeAttributes = {}; + var geometries = new WeakMap(); + var wireframeAttributes = new WeakMap(); function onGeometryDispose( event ) { var geometry = event.target; - var buffergeometry = geometries[ geometry.id ]; + var buffergeometry = geometries.get( geometry ); if ( buffergeometry.index !== null ) { @@ -15784,14 +16088,14 @@ geometry.removeEventListener( 'dispose', onGeometryDispose ); - delete geometries[ geometry.id ]; + geometries.delete( geometry ); - var attribute = wireframeAttributes[ buffergeometry.id ]; + var attribute = wireframeAttributes.get( buffergeometry ); if ( attribute ) { attributes.remove( attribute ); - delete wireframeAttributes[ buffergeometry.id ]; + wireframeAttributes.delete( buffergeometry ); } @@ -15803,9 +16107,9 @@ function get( object, geometry ) { - var buffergeometry = geometries[ geometry.id ]; + var buffergeometry = geometries.get( geometry ); - if ( buffergeometry ) return buffergeometry; + if ( buffergeometry ) { return buffergeometry; } geometry.addEventListener( 'dispose', onGeometryDispose ); @@ -15825,7 +16129,7 @@ } - geometries[ geometry.id ] = buffergeometry; + geometries.set( geometry, buffergeometry ); info.memory.geometries ++; @@ -15915,19 +16219,19 @@ // - var previousAttribute = wireframeAttributes[ geometry.id ]; + var previousAttribute = wireframeAttributes.get( geometry ); - if ( previousAttribute ) attributes.remove( previousAttribute ); + if ( previousAttribute ) { attributes.remove( previousAttribute ); } // - wireframeAttributes[ geometry.id ] = attribute; + wireframeAttributes.set( geometry, attribute ); } function getWireframeAttribute( geometry ) { - var currentAttribute = wireframeAttributes[ geometry.id ]; + var currentAttribute = wireframeAttributes.get( geometry ); if ( currentAttribute ) { @@ -15951,7 +16255,7 @@ } - return wireframeAttributes[ geometry.id ]; + return wireframeAttributes.get( geometry ); } @@ -15972,6 +16276,8 @@ function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { + var isWebGL2 = capabilities.isWebGL2; + var mode; function setMode( value ) { @@ -15997,17 +16303,21 @@ } - function renderInstances( geometry, start, count ) { + function renderInstances( geometry, start, count, primcount ) { - var extension; + if ( primcount === 0 ) { return; } - if ( capabilities.isWebGL2 ) { + var extension, methodName; + + if ( isWebGL2 ) { extension = gl; + methodName = 'drawElementsInstanced'; } else { - var extension = extensions.get( 'ANGLE_instanced_arrays' ); + extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawElementsInstancedANGLE'; if ( extension === null ) { @@ -16018,9 +16328,9 @@ } - extension[ capabilities.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount ); + extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount ); - info.update( count, mode, geometry.maxInstancedCount ); + info.update( count, mode, primcount ); } @@ -16064,11 +16374,6 @@ render.triangles += instanceCount * ( count / 3 ); break; - case 5: - case 6: - render.triangles += instanceCount * ( count - 2 ); - break; - case 1: render.lines += instanceCount * ( count / 2 ); break; @@ -16133,7 +16438,10 @@ var objectInfluences = object.morphTargetInfluences; - var length = objectInfluences.length; + // When object doesn't have morph target influences defined, we treat it as a 0-length array + // This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences + + var length = objectInfluences === undefined ? 0 : objectInfluences.length; var influences = influencesList[ geometry.id ]; @@ -16164,8 +16472,8 @@ if ( influence[ 1 ] !== 0 ) { - if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i ); - if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i ); + if ( morphTargets ) { geometry.deleteAttribute( 'morphTarget' + i ); } + if ( morphNormals ) { geometry.deleteAttribute( 'morphNormal' + i ); } } @@ -16186,6 +16494,8 @@ // Add morphAttributes + var morphInfluencesSum = 0; + for ( var i = 0; i < 8; i ++ ) { var influence = influences[ i ]; @@ -16197,10 +16507,11 @@ if ( value ) { - if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] ); - if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] ); + if ( morphTargets ) { geometry.setAttribute( 'morphTarget' + i, morphTargets[ index ] ); } + if ( morphNormals ) { geometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] ); } morphInfluences[ i ] = value; + morphInfluencesSum += value; continue; } @@ -16211,6 +16522,12 @@ } + // GLSL shader uses formula baseinfluence * base + sum(target * influence) + // This allows us to switch between absolute morphs and relative morphs without changing shader code + // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence) + var morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; + + program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence ); program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); } @@ -16227,9 +16544,9 @@ * @author mrdoob / http://mrdoob.com/ */ - function WebGLObjects( geometries, info ) { + function WebGLObjects( gl, geometries, attributes, info ) { - var updateList = {}; + var updateMap = new WeakMap(); function update( object ) { @@ -16240,7 +16557,7 @@ // Update once per frame - if ( updateList[ buffergeometry.id ] !== frame ) { + if ( updateMap.get( buffergeometry ) !== frame ) { if ( geometry.isGeometry ) { @@ -16250,7 +16567,13 @@ geometries.update( buffergeometry ); - updateList[ buffergeometry.id ] = frame; + updateMap.set( buffergeometry, frame ); + + } + + if ( object.isInstancedMesh ) { + + attributes.update( object.instanceMatrix, 34962 ); } @@ -16260,7 +16583,7 @@ function dispose() { - updateList = {}; + updateMap = new WeakMap(); } @@ -16318,7 +16641,7 @@ Texture.call( this, null ); - this.image = { data: data, width: width, height: height, depth: depth }; + this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; @@ -16328,6 +16651,8 @@ this.generateMipmaps = false; this.flipY = false; + this.needsUpdate = true; + } DataTexture2DArray.prototype = Object.create( Texture.prototype ); @@ -16350,7 +16675,7 @@ Texture.call( this, null ); - this.image = { data: data, width: width, height: height, depth: depth }; + this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; @@ -16360,6 +16685,9 @@ this.generateMipmaps = false; this.flipY = false; + this.needsUpdate = true; + + } DataTexture3D.prototype = Object.create( Texture.prototype ); @@ -16437,7 +16765,7 @@ var firstElem = array[ 0 ]; - if ( firstElem <= 0 || firstElem > 0 ) return array; + if ( firstElem <= 0 || firstElem > 0 ) { return array; } // unoptimized: ! isNaN( firstElem ) // see http://jacksondunstan.com/articles/983 @@ -16470,11 +16798,11 @@ function arraysEqual( a, b ) { - if ( a.length !== b.length ) return false; + if ( a.length !== b.length ) { return false; } for ( var i = 0, l = a.length; i < l; i ++ ) { - if ( a[ i ] !== b[ i ] ) return false; + if ( a[ i ] !== b[ i ] ) { return false; } } @@ -16506,7 +16834,7 @@ } for ( var i = 0; i !== n; ++ i ) - r[ i ] = textures.allocateTextureUnit(); + { r[ i ] = textures.allocateTextureUnit(); } return r; @@ -16523,7 +16851,7 @@ var cache = this.cache; - if ( cache[ 0 ] === v ) return; + if ( cache[ 0 ] === v ) { return; } gl.uniform1f( this.addr, v ); @@ -16550,7 +16878,7 @@ } else { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniform2fv( this.addr, v ); @@ -16590,7 +16918,7 @@ } else { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniform3fv( this.addr, v ); @@ -16619,7 +16947,7 @@ } else { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniform4fv( this.addr, v ); @@ -16638,7 +16966,7 @@ if ( elements === undefined ) { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniformMatrix2fv( this.addr, false, v ); @@ -16646,7 +16974,7 @@ } else { - if ( arraysEqual( cache, elements ) ) return; + if ( arraysEqual( cache, elements ) ) { return; } mat2array.set( elements ); @@ -16665,7 +16993,7 @@ if ( elements === undefined ) { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniformMatrix3fv( this.addr, false, v ); @@ -16673,7 +17001,7 @@ } else { - if ( arraysEqual( cache, elements ) ) return; + if ( arraysEqual( cache, elements ) ) { return; } mat3array.set( elements ); @@ -16692,7 +17020,7 @@ if ( elements === undefined ) { - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniformMatrix4fv( this.addr, false, v ); @@ -16700,7 +17028,7 @@ } else { - if ( arraysEqual( cache, elements ) ) return; + if ( arraysEqual( cache, elements ) ) { return; } mat4array.set( elements ); @@ -16784,7 +17112,7 @@ var cache = this.cache; - if ( cache[ 0 ] === v ) return; + if ( cache[ 0 ] === v ) { return; } gl.uniform1i( this.addr, v ); @@ -16796,7 +17124,7 @@ var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniform2iv( this.addr, v ); @@ -16808,7 +17136,7 @@ var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniform3iv( this.addr, v ); @@ -16820,7 +17148,7 @@ var cache = this.cache; - if ( arraysEqual( cache, v ) ) return; + if ( arraysEqual( cache, v ) ) { return; } gl.uniform4iv( this.addr, v ); @@ -16828,6 +17156,20 @@ } + // uint + + function setValueV1ui( gl, v ) { + + var cache = this.cache; + + if ( cache[ 0 ] === v ) { return; } + + gl.uniform1ui( this.addr, v ); + + cache[ 0 ] = v; + + } + // Helper to pick the right setter for the singular case function getSingularSetter( type ) { @@ -16843,16 +17185,37 @@ case 0x8b5b: return setValueM3; // _MAT3 case 0x8b5c: return setValueM4; // _MAT4 - case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES - case 0x8b5f: return setValueT3D1; // SAMPLER_3D - case 0x8b60: return setValueT6; // SAMPLER_CUBE - case 0x8DC1: return setValueT2DArray1; // SAMPLER_2D_ARRAY - case 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2 case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3 case 0x8b55: case 0x8b59: return setValueV4i; // _VEC4 + case 0x1405: return setValueV1ui; // UINT + + case 0x8b5e: // SAMPLER_2D + case 0x8d66: // SAMPLER_EXTERNAL_OES + case 0x8dca: // INT_SAMPLER_2D + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + case 0x8b62: // SAMPLER_2D_SHADOW + return setValueT1; + + case 0x8b5f: // SAMPLER_3D + case 0x8dcb: // INT_SAMPLER_3D + case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D + return setValueT3D1; + + case 0x8b60: // SAMPLER_CUBE + case 0x8dcc: // INT_SAMPLER_CUBE + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + case 0x8dc5: // SAMPLER_CUBE_SHADOW + return setValueT6; + + case 0x8dc1: // SAMPLER_2D_ARRAY + case 0x8dcf: // INT_SAMPLER_2D_ARRAY + case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW + return setValueT2DArray1; + } } @@ -16991,14 +17354,24 @@ case 0x8b5b: return setValueM3Array; // _MAT3 case 0x8b5c: return setValueM4Array; // _MAT4 - case 0x8b5e: return setValueT1Array; // SAMPLER_2D - case 0x8b60: return setValueT6Array; // SAMPLER_CUBE - case 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2 case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3 case 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4 + case 0x8b5e: // SAMPLER_2D + case 0x8d66: // SAMPLER_EXTERNAL_OES + case 0x8dca: // INT_SAMPLER_2D + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + case 0x8b62: // SAMPLER_2D_SHADOW + return setValueT1Array; + + case 0x8b60: // SAMPLER_CUBE + case 0x8dcc: // INT_SAMPLER_CUBE + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + case 0x8dc5: // SAMPLER_CUBE_SHADOW + return setValueT6Array; + } } @@ -17103,7 +17476,7 @@ idIsIndex = match[ 2 ] === ']', subscript = match[ 3 ]; - if ( idIsIndex ) id = id | 0; // convert to integer + if ( idIsIndex ) { id = id | 0; } // convert to integer if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) { @@ -17160,7 +17533,7 @@ var u = this.map[ name ]; - if ( u !== undefined ) u.setValue( gl, value, textures ); + if ( u !== undefined ) { u.setValue( gl, value, textures ); } }; @@ -17168,7 +17541,7 @@ var v = object[ name ]; - if ( v !== undefined ) this.setValue( gl, name, v ); + if ( v !== undefined ) { this.setValue( gl, name, v ); } }; @@ -17200,7 +17573,7 @@ for ( var i = 0, n = seq.length; i !== n; ++ i ) { var u = seq[ i ]; - if ( u.id in values ) r.push( u ); + if ( u.id in values ) { r.push( u ); } } @@ -17275,7 +17648,7 @@ var status = gl.getShaderParameter( shader, 35713 ); var log = gl.getShaderInfoLog( shader ).trim(); - if ( status && log === '' ) return ''; + if ( status && log === '' ) { return ''; } // --enable-privileged-webgl-extension // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); @@ -17335,15 +17708,13 @@ } - function generateExtensions( extensions, parameters, rendererExtensions ) { - - extensions = extensions || {}; + function generateExtensions( parameters ) { var chunks = [ - ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || ( parameters.normalMap && ! parameters.objectSpaceNormalMap ) || parameters.clearCoatNormalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', - ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '', - ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '', - ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '' + ( parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '', + ( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', + ( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '', + ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '' ]; return chunks.filter( filterEmptyLine ).join( '\n' ); @@ -17358,7 +17729,7 @@ var value = defines[ name ]; - if ( value === false ) continue; + if ( value === false ) { continue; } chunks.push( '#define ' + name + ' ' + value ); @@ -17417,60 +17788,91 @@ } - function parseIncludes( string ) { + // Resolve Includes - var pattern = /^[ \t]*#include +<([\w\d./]+)>/gm; + var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; - function replace( match, include ) { + function resolveIncludes( string ) { - var replace = ShaderChunk[ include ]; + return string.replace( includePattern, includeReplacer ); - if ( replace === undefined ) { + } - throw new Error( 'Can not resolve #include <' + include + '>' ); + function includeReplacer( match, include ) { - } + var string = ShaderChunk[ include ]; - return parseIncludes( replace ); + if ( string === undefined ) { + + throw new Error( 'Can not resolve #include <' + include + '>' ); } - return string.replace( pattern, replace ); + return resolveIncludes( string ); } + // Unroll Loops + + var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; + var unrollLoopPattern = /#pragma unroll_loop_start[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g; + function unrollLoops( string ) { - var pattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; + return string + .replace( unrollLoopPattern, loopReplacer ) + .replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer ); + + } - function replace( match, start, end, snippet ) { + function deprecatedLoopReplacer( match, start, end, snippet ) { - var unroll = ''; + console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' ); + return loopReplacer( match, start, end, snippet ); - for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { + } - unroll += snippet - .replace( /\[ i \]/g, '[ ' + i + ' ]' ) - .replace( /UNROLLED_LOOP_INDEX/g, i ); + function loopReplacer( match, start, end, snippet ) { - } + var string = ''; - return unroll; + for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { + + string += snippet + .replace( /\[ i \]/g, '[ ' + i + ' ]' ) + .replace( /UNROLLED_LOOP_INDEX/g, i ); } - return string.replace( pattern, replace ); + return string; } - function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) { + // + + function generatePrecision( parameters ) { - var gl = renderer.getContext(); + var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;"; + + if ( parameters.precision === "highp" ) { + + precisionstring += "\n#define HIGH_PRECISION"; + + } else if ( parameters.precision === "mediump" ) { + + precisionstring += "\n#define MEDIUM_PRECISION"; + + } else if ( parameters.precision === "lowp" ) { + + precisionstring += "\n#define LOW_PRECISION"; + + } - var defines = material.defines; + return precisionstring; - var vertexShader = shader.vertexShader; - var fragmentShader = shader.fragmentShader; + } + + function generateShadowMapTypeDefine( parameters ) { var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; @@ -17482,15 +17884,23 @@ shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; + } else if ( parameters.shadowMapType === VSMShadowMap ) { + + shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; + } + return shadowMapTypeDefine; + + } + + function generateEnvMapTypeDefine( parameters ) { + var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; - var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; if ( parameters.envMap ) { - switch ( material.envMap.mapping ) { + switch ( parameters.envMapMode ) { case CubeReflectionMapping: case CubeRefractionMapping: @@ -17513,7 +17923,19 @@ } - switch ( material.envMap.mapping ) { + } + + return envMapTypeDefine; + + } + + function generateEnvMapModeDefine( parameters ) { + + var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; + + if ( parameters.envMap ) { + + switch ( parameters.envMapMode ) { case CubeRefractionMapping: case EquirectangularRefractionMapping: @@ -17522,7 +17944,19 @@ } - switch ( material.combine ) { + } + + return envMapModeDefine; + + } + + function generateEnvMapBlendingDefine( parameters ) { + + var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; + + if ( parameters.envMap ) { + + switch ( parameters.combine ) { case MultiplyOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; @@ -17540,23 +17974,35 @@ } - var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; + return envMapBlendingDefine; + + } - // console.log( 'building new program ' ); + function WebGLProgram( renderer, cacheKey, parameters ) { - // + var gl = renderer.getContext(); - var customExtensions = capabilities.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions ); + var defines = parameters.defines; - var customDefines = generateDefines( defines ); + var vertexShader = parameters.vertexShader; + var fragmentShader = parameters.fragmentShader; + var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters ); + var envMapTypeDefine = generateEnvMapTypeDefine( parameters ); + var envMapModeDefine = generateEnvMapModeDefine( parameters ); + var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters ); - // + + var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; + + var customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters ); + + var customDefines = generateDefines( defines ); var program = gl.createProgram(); var prefixVertex, prefixFragment; - if ( material.isRawShaderMaterial ) { + if ( parameters.isRawShaderMaterial ) { prefixVertex = [ @@ -17587,20 +18033,20 @@ prefixVertex = [ - 'precision ' + parameters.precision + ' float;', - 'precision ' + parameters.precision + ' int;', + generatePrecision( parameters ), - '#define SHADER_NAME ' + shader.name, + '#define SHADER_NAME ' + parameters.shaderName, customDefines, + parameters.instancing ? '#define USE_INSTANCING' : '', parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', '#define GAMMA_FACTOR ' + gammaFactorDefine, '#define MAX_BONES ' + parameters.maxBones, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', @@ -17611,7 +18057,11 @@ parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', - parameters.clearCoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', + ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', + + parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', + parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', @@ -17621,6 +18071,7 @@ parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexUvs ? '#define USE_UV' : '', + parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', @@ -17638,7 +18089,7 @@ parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', - parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', + ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', @@ -17646,6 +18097,13 @@ 'uniform mat4 viewMatrix;', 'uniform mat3 normalMatrix;', 'uniform vec3 cameraPosition;', + 'uniform bool isOrthographic;', + + '#ifdef USE_INSTANCING', + + ' attribute mat4 instanceMatrix;', + + '#endif', 'attribute vec3 position;', 'attribute vec3 normal;', @@ -17703,10 +18161,9 @@ customExtensions, - 'precision ' + parameters.precision + ' float;', - 'precision ' + parameters.precision + ' int;', + generatePrecision( parameters ), - '#define SHADER_NAME ' + shader.name, + '#define SHADER_NAME ' + parameters.shaderName, customDefines, @@ -17715,7 +18172,7 @@ '#define GAMMA_FACTOR ' + gammaFactorDefine, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.matcap ? '#define USE_MATCAP' : '', @@ -17729,15 +18186,21 @@ parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', - parameters.clearCoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', + ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', + parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', + parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.sheen ? '#define USE_SHEEN' : '', + parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexUvs ? '#define USE_UV' : '', + parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', @@ -17754,12 +18217,13 @@ parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', - parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', + ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', - ( ( material.extensions ? material.extensions.shaderTextureLOD : false ) || parameters.envMap ) && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '', + ( ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ) ? '#define TEXTURE_LOD_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', + 'uniform bool isOrthographic;', ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '', ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below @@ -17767,15 +18231,16 @@ parameters.dithering ? '#define DITHERING' : '', - ( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? + ( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding || parameters.lightMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '', parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', + parameters.lightMapEncoding ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '', parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '', - parameters.depthPacking ? '#define DEPTH_PACKING ' + material.depthPacking : '', + parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n' @@ -17783,24 +18248,24 @@ } - vertexShader = parseIncludes( vertexShader ); + vertexShader = resolveIncludes( vertexShader ); vertexShader = replaceLightNums( vertexShader, parameters ); vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); - fragmentShader = parseIncludes( fragmentShader ); + fragmentShader = resolveIncludes( fragmentShader ); fragmentShader = replaceLightNums( fragmentShader, parameters ); fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); vertexShader = unrollLoops( vertexShader ); fragmentShader = unrollLoops( fragmentShader ); - if ( capabilities.isWebGL2 && ! material.isRawShaderMaterial ) { + if ( parameters.isWebGL2 && ! parameters.isRawShaderMaterial ) { var isGLSL3ShaderMaterial = false; var versionRegex = /^\s*#version\s+300\s+es\s*\n/; - if ( material.isShaderMaterial && + if ( parameters.isShaderMaterial && vertexShader.match( versionRegex ) !== null && fragmentShader.match( versionRegex ) !== null ) { @@ -17812,6 +18277,7 @@ } // GLSL 3.0 conversion + prefixVertex = [ '#version 300 es\n', '#define attribute in', @@ -17852,9 +18318,9 @@ // Force a particular attribute to index 0. - if ( material.index0AttributeName !== undefined ) { + if ( parameters.index0AttributeName !== undefined ) { - gl.bindAttribLocation( program, 0, material.index0AttributeName ); + gl.bindAttribLocation( program, 0, parameters.index0AttributeName ); } else if ( parameters.morphTargets === true ) { @@ -17899,7 +18365,6 @@ this.diagnostics = { runnable: runnable, - material: material, programLog: programLog, @@ -17925,6 +18390,9 @@ // clean up + gl.detachShader( program, glVertexShader ); + gl.detachShader( program, glFragmentShader ); + gl.deleteShader( glVertexShader ); gl.deleteShader( glFragmentShader ); @@ -17971,9 +18439,9 @@ // - this.name = shader.name; + this.name = parameters.shaderName; this.id = programIdCount ++; - this.code = code; + this.cacheKey = cacheKey; this.usedTimes = 1; this.program = program; this.vertexShader = glVertexShader; @@ -17991,6 +18459,13 @@ var programs = []; + var isWebGL2 = capabilities.isWebGL2; + var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; + var floatVertexTextures = capabilities.floatVertexTextures; + var precision = capabilities.precision; + var maxVertexUniforms = capabilities.maxVertexUniforms; + var vertexTextures = capabilities.vertexTextures; + var shaderIDs = { MeshDepthMaterial: 'depth', MeshDistanceMaterial: 'distanceRGBA', @@ -17998,7 +18473,7 @@ MeshBasicMaterial: 'basic', MeshLambertMaterial: 'lambert', MeshPhongMaterial: 'phong', - MeshToonMaterial: 'phong', + MeshToonMaterial: 'toon', MeshStandardMaterial: 'physical', MeshPhysicalMaterial: 'physical', MeshMatcapMaterial: 'matcap', @@ -18010,25 +18485,57 @@ }; var parameterNames = [ - "precision", "supportsVertexTextures", "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", - "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "clearCoatNormalMap", "displacementMap", "specularMap", + "precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", + "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV", + "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap", "roughnessMap", "metalnessMap", "gradientMap", - "alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp", + "alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2", "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", "maxBones", "useVertexTexture", "morphTargets", "morphNormals", "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", + "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows", "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', - "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering" + "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering", + "sheen" ]; + function getShaderObject( material, shaderID ) { + + var shaderobject; + + if ( shaderID ) { + + var shader = ShaderLib[ shaderID ]; + + shaderobject = { + name: material.type, + uniforms: UniformsUtils.clone( shader.uniforms ), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader + }; + + } else { + + shaderobject = { + name: material.type, + uniforms: material.uniforms, + vertexShader: material.vertexShader, + fragmentShader: material.fragmentShader + }; + + } + + return shaderobject; + + } function allocateBones( object ) { var skeleton = object.skeleton; var bones = skeleton.bones; - if ( capabilities.floatVertexTextures ) { + if ( floatVertexTextures ) { return 1024; @@ -18041,7 +18548,7 @@ // - limit here is ANGLE's 254 max uniform vectors // (up to 54 should be safe) - var nVertexUniforms = capabilities.maxVertexUniforms; + var nVertexUniforms = maxVertexUniforms; var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); var maxBones = Math.min( nVertexMatrices, bones.length ); @@ -18059,7 +18566,7 @@ } - function getTextureEncodingFromMap( map, gammaOverrideLinear ) { + function getTextureEncodingFromMap( map ) { var encoding; @@ -18078,18 +18585,16 @@ } - // add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point. - if ( encoding === LinearEncoding && gammaOverrideLinear ) { - - encoding = GammaEncoding; - - } - return encoding; } - this.getParameters = function ( material, lights, shadows, fog, nClipPlanes, nClipIntersection, object ) { + this.getParameters = function ( material, lights, shadows, scene, nClipPlanes, nClipIntersection, object ) { + + var fog = scene.fog; + var environment = material.isMeshStandardMaterial ? scene.environment : null; + + var envMap = material.envMap || environment; var shaderID = shaderIDs[ material.type ]; @@ -18097,7 +18602,6 @@ // (not to blow over maxLights budget) var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0; - var precision = capabilities.precision; if ( material.precision !== null ) { @@ -18111,31 +18615,52 @@ } + var shaderobject = getShaderObject( material, shaderID ); + material.onBeforeCompile( shaderobject, renderer ); + var currentRenderTarget = renderer.getRenderTarget(); var parameters = { + isWebGL2: isWebGL2, + shaderID: shaderID, + shaderName: shaderobject.name, + + uniforms: shaderobject.uniforms, + vertexShader: shaderobject.vertexShader, + fragmentShader: shaderobject.fragmentShader, + defines: material.defines, + + isRawShaderMaterial: material.isRawShaderMaterial, + isShaderMaterial: material.isShaderMaterial, precision: precision, - supportsVertexTextures: capabilities.vertexTextures, - outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ), + + instancing: object.isInstancedMesh === true, + + supportsVertexTextures: vertexTextures, + outputEncoding: ( currentRenderTarget !== null ) ? getTextureEncodingFromMap( currentRenderTarget.texture ) : renderer.outputEncoding, map: !! material.map, - mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ), + mapEncoding: getTextureEncodingFromMap( material.map ), matcap: !! material.matcap, - matcapEncoding: getTextureEncodingFromMap( material.matcap, renderer.gammaInput ), - envMap: !! material.envMap, - envMapMode: material.envMap && material.envMap.mapping, - envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ), - envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ), + matcapEncoding: getTextureEncodingFromMap( material.matcap ), + envMap: !! envMap, + envMapMode: envMap && envMap.mapping, + envMapEncoding: getTextureEncodingFromMap( envMap ), + envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ), lightMap: !! material.lightMap, + lightMapEncoding: getTextureEncodingFromMap( material.lightMap ), aoMap: !! material.aoMap, emissiveMap: !! material.emissiveMap, - emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ), + emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ), bumpMap: !! material.bumpMap, normalMap: !! material.normalMap, objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, - clearCoatNormalMap: !! material.clearCoatNormalMap, + tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, + clearcoatMap: !! material.clearcoatMap, + clearcoatRoughnessMap: !! material.clearcoatRoughnessMap, + clearcoatNormalMap: !! material.clearcoatNormalMap, displacementMap: !! material.displacementMap, roughnessMap: !! material.roughnessMap, metalnessMap: !! material.metalnessMap, @@ -18144,24 +18669,27 @@ gradientMap: !! material.gradientMap, + sheen: !! material.sheen, + combine: material.combine, vertexTangents: ( material.normalMap && material.vertexTangents ), vertexColors: material.vertexColors, - vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearCoatNormalMap, + vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap, + uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap ) && !! material.displacementMap, fog: !! fog, useFog: material.fog, - fogExp: ( fog && fog.isFogExp2 ), + fogExp2: ( fog && fog.isFogExp2 ), flatShading: material.flatShading, sizeAttenuation: material.sizeAttenuation, - logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer, + logarithmicDepthBuffer: logarithmicDepthBuffer, skinning: material.skinning && maxBones > 0, maxBones: maxBones, - useVertexTexture: capabilities.floatVertexTextures, + useVertexTexture: floatVertexTextures, morphTargets: material.morphTargets, morphNormals: material.morphNormals, @@ -18183,10 +18711,10 @@ dithering: material.dithering, - shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && shadows.length > 0, + shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, shadowMapType: renderer.shadowMap.type, - toneMapping: renderer.toneMapping, + toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, physicallyCorrectLights: renderer.physicallyCorrectLights, premultipliedAlpha: material.premultipliedAlpha, @@ -18195,7 +18723,20 @@ doubleSided: material.side === DoubleSide, flipSided: material.side === BackSide, - depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false + depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false, + + index0AttributeName: material.index0AttributeName, + + extensionDerivatives: material.extensions && material.extensions.derivatives, + extensionFragDepth: material.extensions && material.extensions.fragDepth, + extensionDrawbuffers: material.extensions && material.extensions.drawBuffers, + extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, + + rendererExtensionFragDepth: isWebGL2 || extensions.get( 'EXT_frag_depth' ) !== null, + rendererExtensionDrawBuffers: isWebGL2 || extensions.get( 'WEBGL_draw_buffers' ) !== null, + rendererExtensionShaderTextureLod: isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) !== null, + + onBeforeCompile: material.onBeforeCompile }; @@ -18203,7 +18744,7 @@ }; - this.getProgramCode = function ( material, parameters ) { + this.getProgramCacheKey = function ( parameters ) { var array = []; @@ -18213,50 +18754,53 @@ } else { - array.push( material.fragmentShader ); - array.push( material.vertexShader ); + array.push( parameters.fragmentShader ); + array.push( parameters.vertexShader ); } - if ( material.defines !== undefined ) { + if ( parameters.defines !== undefined ) { - for ( var name in material.defines ) { + for ( var name in parameters.defines ) { array.push( name ); - array.push( material.defines[ name ] ); + array.push( parameters.defines[ name ] ); } } - for ( var i = 0; i < parameterNames.length; i ++ ) { + if ( parameters.isRawShaderMaterial === undefined ) { - array.push( parameters[ parameterNames[ i ] ] ); + for ( var i = 0; i < parameterNames.length; i ++ ) { - } + array.push( parameters[ parameterNames[ i ] ] ); + + } - array.push( material.onBeforeCompile.toString() ); + array.push( renderer.outputEncoding ); + array.push( renderer.gammaFactor ); - array.push( renderer.gammaOutput ); + } - array.push( renderer.gammaFactor ); + array.push( parameters.onBeforeCompile.toString() ); return array.join(); }; - this.acquireProgram = function ( material, shader, parameters, code ) { + this.acquireProgram = function ( parameters, cacheKey ) { var program; // Check if code has been already compiled for ( var p = 0, pl = programs.length; p < pl; p ++ ) { - var programInfo = programs[ p ]; + var preexistingProgram = programs[ p ]; - if ( programInfo.code === code ) { + if ( preexistingProgram.cacheKey === cacheKey ) { - program = programInfo; + program = preexistingProgram; ++ program.usedTimes; break; @@ -18267,7 +18811,7 @@ if ( program === undefined ) { - program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ); + program = new WebGLProgram( renderer, cacheKey, parameters ); programs.push( program ); } @@ -18479,10 +19023,31 @@ } - function sort() { + function sort( customOpaqueSort, customTransparentSort ) { + + if ( opaque.length > 1 ) { opaque.sort( customOpaqueSort || painterSortStable ); } + if ( transparent.length > 1 ) { transparent.sort( customTransparentSort || reversePainterSortStable ); } + + } + + function finish() { + + // Clear references from inactive renderItems in the list + + for ( var i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) { + + var renderItem = renderItems[ i ]; - if ( opaque.length > 1 ) opaque.sort( painterSortStable ); - if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable ); + if ( renderItem.id === null ) { break; } + + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.program = null; + renderItem.group = null; + + } } @@ -18493,6 +19058,7 @@ init: init, push: push, unshift: unshift, + finish: finish, sort: sort }; @@ -18501,7 +19067,7 @@ function WebGLRenderLists() { - var lists = {}; + var lists = new WeakMap(); function onSceneDispose( event ) { @@ -18509,29 +19075,29 @@ scene.removeEventListener( 'dispose', onSceneDispose ); - delete lists[ scene.id ]; + lists.delete( scene ); } function get( scene, camera ) { - var cameras = lists[ scene.id ]; + var cameras = lists.get( scene ); var list; if ( cameras === undefined ) { list = new WebGLRenderList(); - lists[ scene.id ] = {}; - lists[ scene.id ][ camera.id ] = list; + lists.set( scene, new WeakMap() ); + lists.get( scene ).set( camera, list ); scene.addEventListener( 'dispose', onSceneDispose ); } else { - list = cameras[ camera.id ]; + list = cameras.get( camera ); if ( list === undefined ) { list = new WebGLRenderList(); - cameras[ camera.id ] = list; + cameras.set( camera, list ); } @@ -18543,7 +19109,7 @@ function dispose() { - lists = {}; + lists = new WeakMap(); } @@ -18579,12 +19145,7 @@ case 'DirectionalLight': uniforms = { direction: new Vector3(), - color: new Color(), - - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() + color: new Color() }; break; @@ -18596,12 +19157,7 @@ distance: 0, coneCos: 0, penumbraCos: 0, - decay: 0, - - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() + decay: 0 }; break; @@ -18610,14 +19166,7 @@ position: new Vector3(), color: new Color(), distance: 0, - decay: 0, - - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2(), - shadowCameraNear: 1, - shadowCameraFar: 1000 + decay: 0 }; break; @@ -18635,7 +19184,6 @@ position: new Vector3(), halfWidth: new Vector3(), halfHeight: new Vector3() - // TODO (abelnation): set RectAreaLight shadow uniforms }; break; @@ -18651,6 +19199,66 @@ } + function ShadowUniformsCache() { + + var lights = {}; + + return { + + get: function ( light ) { + + if ( lights[ light.id ] !== undefined ) { + + return lights[ light.id ]; + + } + + var uniforms; + + switch ( light.type ) { + + case 'DirectionalLight': + uniforms = { + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; + + case 'SpotLight': + uniforms = { + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; + + case 'PointLight': + uniforms = { + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2(), + shadowCameraNear: 1, + shadowCameraFar: 1000 + }; + break; + + // TODO (abelnation): set RectAreaLight shadow uniforms + + } + + lights[ light.id ] = uniforms; + + return uniforms; + + } + + }; + + } + + + var nextVersion = 0; function shadowCastingLightsFirst( lightA, lightB ) { @@ -18663,6 +19271,8 @@ var cache = new UniformsCache(); + var shadowCache = ShadowUniformsCache(); + var state = { version: 0, @@ -18676,30 +19286,29 @@ numDirectionalShadows: - 1, numPointShadows: - 1, - numSpotShadows: - 1, + numSpotShadows: - 1 }, ambient: [ 0, 0, 0 ], probe: [], directional: [], + directionalShadow: [], directionalShadowMap: [], directionalShadowMatrix: [], spot: [], + spotShadow: [], spotShadowMap: [], spotShadowMatrix: [], rectArea: [], point: [], + pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [], - - numDirectionalShadows: - 1, - numPointShadows: - 1, - numSpotShadows: - 1 + hemi: [] }; - for ( var i = 0; i < 9; i ++ ) state.probe.push( new Vector3() ); + for ( var i = 0; i < 9; i ++ ) { state.probe.push( new Vector3() ); } var vector3 = new Vector3(); var matrix4 = new Matrix4(); @@ -18709,7 +19318,7 @@ var r = 0, g = 0, b = 0; - for ( var i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 ); + for ( var i = 0; i < 9; i ++ ) { state.probe[ i ].set( 0, 0, 0 ); } var directionalLength = 0; var pointLength = 0; @@ -18759,16 +19368,17 @@ uniforms.direction.sub( vector3 ); uniforms.direction.transformDirection( viewMatrix ); - uniforms.shadow = light.castShadow; - if ( light.castShadow ) { var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; + var shadowUniforms = shadowCache.get( light ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + state.directionalShadow[ directionalLength ] = shadowUniforms; state.directionalShadowMap[ directionalLength ] = shadowMap; state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; @@ -18799,16 +19409,17 @@ uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); uniforms.decay = light.decay; - uniforms.shadow = light.castShadow; - if ( light.castShadow ) { var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; + var shadowUniforms = shadowCache.get( light ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + state.spotShadow[ spotLength ] = shadowUniforms; state.spotShadowMap[ spotLength ] = shadowMap; state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; @@ -18863,18 +19474,19 @@ uniforms.distance = light.distance; uniforms.decay = light.decay; - uniforms.shadow = light.castShadow; - if ( light.castShadow ) { var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; - uniforms.shadowCameraNear = shadow.camera.near; - uniforms.shadowCameraFar = shadow.camera.far; + var shadowUniforms = shadowCache.get( light ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + shadowUniforms.shadowCameraNear = shadow.camera.near; + shadowUniforms.shadowCameraFar = shadow.camera.far; + state.pointShadow[ pointLength ] = shadowUniforms; state.pointShadowMap[ pointLength ] = shadowMap; state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; @@ -18926,8 +19538,11 @@ state.point.length = pointLength; state.hemi.length = hemiLength; + state.directionalShadow.length = numDirectionalShadows; state.directionalShadowMap.length = numDirectionalShadows; + state.pointShadow.length = numPointShadows; state.pointShadowMap.length = numPointShadows; + state.spotShadow.length = numSpotShadows; state.spotShadowMap.length = numSpotShadows; state.directionalShadowMatrix.length = numDirectionalShadows; state.pointShadowMatrix.length = numPointShadows; @@ -19012,7 +19627,7 @@ function WebGLRenderStates() { - var renderStates = {}; + var renderStates = new WeakMap(); function onSceneDispose( event ) { @@ -19020,7 +19635,7 @@ scene.removeEventListener( 'dispose', onSceneDispose ); - delete renderStates[ scene.id ]; + renderStates.delete( scene ); } @@ -19028,24 +19643,24 @@ var renderState; - if ( renderStates[ scene.id ] === undefined ) { + if ( renderStates.has( scene ) === false ) { renderState = new WebGLRenderState(); - renderStates[ scene.id ] = {}; - renderStates[ scene.id ][ camera.id ] = renderState; + renderStates.set( scene, new WeakMap() ); + renderStates.get( scene ).set( camera, renderState ); scene.addEventListener( 'dispose', onSceneDispose ); } else { - if ( renderStates[ scene.id ][ camera.id ] === undefined ) { + if ( renderStates.get( scene ).has( camera ) === false ) { renderState = new WebGLRenderState(); - renderStates[ scene.id ][ camera.id ] = renderState; + renderStates.get( scene ).set( camera, renderState ); } else { - renderState = renderStates[ scene.id ][ camera.id ]; + renderState = renderStates.get( scene ).get( camera ); } @@ -19057,7 +19672,7 @@ function dispose() { - renderStates = {}; + renderStates = new WeakMap(); } @@ -19114,7 +19729,6 @@ this.wireframeLinewidth = 1; this.fog = false; - this.lights = false; this.setValues( parameters ); @@ -19194,7 +19808,6 @@ this.displacementBias = 0; this.fog = false; - this.lights = false; this.setValues( parameters ); @@ -19228,6 +19841,10 @@ }; + var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include \nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = sqrt( squared_mean - mean * mean );\n gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"; + + var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; + /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ @@ -19236,73 +19853,51 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { var _frustum = new Frustum(), - _projScreenMatrix = new Matrix4(), _shadowMapSize = new Vector2(), - _maxShadowMapSize = new Vector2( maxTextureSize, maxTextureSize ), - - _lookTarget = new Vector3(), - _lightPositionWorld = new Vector3(), - - _MorphingFlag = 1, - _SkinningFlag = 2, + _viewportSize = new Vector2(), - _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1, + _viewport = new Vector4(), - _depthMaterials = new Array( _NumberOfMaterialVariants ), - _distanceMaterials = new Array( _NumberOfMaterialVariants ), + _depthMaterials = [], + _distanceMaterials = [], _materialCache = {}; var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; - var cubeDirections = [ - new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), - new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) - ]; - - var cubeUps = [ - new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), - new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) - ]; - - var cube2DViewPorts = [ - new Vector4(), new Vector4(), new Vector4(), - new Vector4(), new Vector4(), new Vector4() - ]; - - // init - - for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) { - - var useMorphing = ( i & _MorphingFlag ) !== 0; - var useSkinning = ( i & _SkinningFlag ) !== 0; + var shadowMaterialVertical = new ShaderMaterial( { - var depthMaterial = new MeshDepthMaterial( { - - depthPacking: RGBADepthPacking, - - morphTargets: useMorphing, - skinning: useSkinning - - } ); - - _depthMaterials[ i ] = depthMaterial; + defines: { + SAMPLE_RATE: 2.0 / 8.0, + HALF_SAMPLE_RATE: 1.0 / 8.0 + }, - // + uniforms: { + shadow_pass: { value: null }, + resolution: { value: new Vector2() }, + radius: { value: 4.0 } + }, - var distanceMaterial = new MeshDistanceMaterial( { + vertexShader: vsm_vert, - morphTargets: useMorphing, - skinning: useSkinning + fragmentShader: vsm_frag - } ); + } ); - _distanceMaterials[ i ] = distanceMaterial; + var shadowMaterialHorizonal = shadowMaterialVertical.clone(); + shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1; - } + var fullScreenTri = new BufferGeometry(); + fullScreenTri.setAttribute( + "position", + new BufferAttribute( + new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ), + 3 + ) + ); - // + var fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical ); var scope = this; @@ -19315,10 +19910,10 @@ this.render = function ( lights, scene, camera ) { - if ( scope.enabled === false ) return; - if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; + if ( scope.enabled === false ) { return; } + if ( scope.autoUpdate === false && scope.needsUpdate === false ) { return; } - if ( lights.length === 0 ) return; + if ( lights.length === 0 ) { return; } var currentRenderTarget = _renderer.getRenderTarget(); var activeCubeFace = _renderer.getActiveCubeFace(); @@ -19334,13 +19929,10 @@ // render depth map - var faceCount; - for ( var i = 0, il = lights.length; i < il; i ++ ) { var light = lights[ i ]; var shadow = light.shadow; - var isPointLight = light && light.isPointLight; if ( shadow === undefined ) { @@ -19349,168 +19941,201 @@ } - var shadowCamera = shadow.camera; - _shadowMapSize.copy( shadow.mapSize ); - _shadowMapSize.min( _maxShadowMapSize ); - if ( isPointLight ) { + var shadowFrameExtents = shadow.getFrameExtents(); - var vpWidth = _shadowMapSize.x; - var vpHeight = _shadowMapSize.y; + _shadowMapSize.multiply( shadowFrameExtents ); - // These viewports map a cube-map onto a 2D texture with the - // following orientation: - // - // xzXZ - // y Y - // - // X - Positive x direction - // x - Negative x direction - // Y - Positive y direction - // y - Negative y direction - // Z - Positive z direction - // z - Negative z direction - - // positive X - cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight ); - // negative X - cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight ); - // positive Z - cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight ); - // negative Z - cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight ); - // positive Y - cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight ); - // negative Y - cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight ); - - _shadowMapSize.x *= 4.0; - _shadowMapSize.y *= 2.0; + _viewportSize.copy( shadow.mapSize ); + + if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) { + + console.warn( 'THREE.WebGLShadowMap:', light, 'has shadow exceeding max texture size, reducing' ); + + if ( _shadowMapSize.x > maxTextureSize ) { + + _viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x ); + _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; + shadow.mapSize.x = _viewportSize.x; + + } + + if ( _shadowMapSize.y > maxTextureSize ) { + + _viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y ); + _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; + shadow.mapSize.y = _viewportSize.y; + + } } - if ( shadow.map === null ) { + if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { - var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat }; shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); shadow.map.texture.name = light.name + ".shadowMap"; - shadowCamera.updateProjectionMatrix(); + shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + + shadow.camera.updateProjectionMatrix(); } - if ( shadow.isSpotLightShadow ) { + if ( shadow.map === null ) { - shadow.update( light ); + var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + shadow.map.texture.name = light.name + ".shadowMap"; + + shadow.camera.updateProjectionMatrix(); } - var shadowMap = shadow.map; - var shadowMatrix = shadow.matrix; + _renderer.setRenderTarget( shadow.map ); + _renderer.clear(); - _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); - shadowCamera.position.copy( _lightPositionWorld ); + var viewportCount = shadow.getViewportCount(); - if ( isPointLight ) { + for ( var vp = 0; vp < viewportCount; vp ++ ) { - faceCount = 6; + var viewport = shadow.getViewport( vp ); - // for point lights we set the shadow matrix to be a translation-only matrix - // equal to inverse of the light's position + _viewport.set( + _viewportSize.x * viewport.x, + _viewportSize.y * viewport.y, + _viewportSize.x * viewport.z, + _viewportSize.y * viewport.w + ); - shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z ); + _state.viewport( _viewport ); - } else { + shadow.updateMatrices( light, vp ); - faceCount = 1; + _frustum = shadow.getFrustum(); - _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + renderObject( scene, camera, shadow.camera, light, this.type ); - // compute shadow matrix + } - shadowMatrix.set( - 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 0.5, 0.5, - 0.0, 0.0, 0.0, 1.0 - ); + // do blur pass for VSM - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { + + VSMPass( shadow, camera ); } - _renderer.setRenderTarget( shadowMap ); - _renderer.clear(); + } + + scope.needsUpdate = false; - // render shadow map for each cube face (if omni-directional) or - // run a single pass if not + _renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel ); - for ( var face = 0; face < faceCount; face ++ ) { + }; - if ( isPointLight ) { + function VSMPass( shadow, camera ) { - _lookTarget.copy( shadowCamera.position ); - _lookTarget.add( cubeDirections[ face ] ); - shadowCamera.up.copy( cubeUps[ face ] ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + var geometry = _objects.update( fullScreenMesh ); - var vpDimensions = cube2DViewPorts[ face ]; - _state.viewport( vpDimensions ); + // vertical pass - } + shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; + shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; + shadowMaterialVertical.uniforms.radius.value = shadow.radius; + _renderer.setRenderTarget( shadow.mapPass ); + _renderer.clear(); + _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null ); - // update camera matrices and frustum + // horizonal pass - _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); + shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture; + shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize; + shadowMaterialHorizonal.uniforms.radius.value = shadow.radius; + _renderer.setRenderTarget( shadow.map ); + _renderer.clear(); + _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null ); - // set object matrices & frustum culling + } - renderObject( scene, camera, shadowCamera, isPointLight ); + function getDepthMaterialVariant( useMorphing, useSkinning, useInstancing ) { - } + var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; + + var material = _depthMaterials[ index ]; + + if ( material === undefined ) { + + material = new MeshDepthMaterial( { + + depthPacking: RGBADepthPacking, + + morphTargets: useMorphing, + skinning: useSkinning + + } ); + + _depthMaterials[ index ] = material; } - scope.needsUpdate = false; + return material; - _renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel ); + } - }; + function getDistanceMaterialVariant( useMorphing, useSkinning, useInstancing ) { + + var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; - function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) { + var material = _distanceMaterials[ index ]; + + if ( material === undefined ) { + + material = new MeshDistanceMaterial( { + + morphTargets: useMorphing, + skinning: useSkinning + + } ); + + _distanceMaterials[ index ] = material; + + } + + return material; + + } + + function getDepthMaterial( object, material, light, shadowCameraNear, shadowCameraFar, type ) { var geometry = object.geometry; var result = null; - var materialVariants = _depthMaterials; + var getMaterialVariant = getDepthMaterialVariant; var customMaterial = object.customDepthMaterial; - if ( isPointLight ) { + if ( light.isPointLight === true ) { - materialVariants = _distanceMaterials; + getMaterialVariant = getDistanceMaterialVariant; customMaterial = object.customDistanceMaterial; } - if ( ! customMaterial ) { + if ( customMaterial === undefined ) { var useMorphing = false; - if ( material.morphTargets ) { + if ( material.morphTargets === true ) { - if ( geometry && geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry === true ) { useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; - } else if ( geometry && geometry.isGeometry ) { + } else if ( geometry.isGeometry === true ) { useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0; @@ -19518,20 +20143,25 @@ } - if ( object.isSkinnedMesh && material.skinning === false ) { + var useSkinning = false; - console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); + if ( object.isSkinnedMesh === true ) { - } + if ( material.skinning === true ) { + + useSkinning = true; + + } else { - var useSkinning = object.isSkinnedMesh && material.skinning; + console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); - var variantIndex = 0; + } + + } - if ( useMorphing ) variantIndex |= _MorphingFlag; - if ( useSkinning ) variantIndex |= _SkinningFlag; + var useInstancing = object.isInstancedMesh === true; - result = materialVariants[ variantIndex ]; + result = getMaterialVariant( useMorphing, useSkinning, useInstancing ); } else { @@ -19573,7 +20203,15 @@ result.visible = material.visible; result.wireframe = material.wireframe; - result.side = ( material.shadowSide != null ) ? material.shadowSide : shadowSide[ material.side ]; + if ( type === VSMShadowMap ) { + + result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side; + + } else { + + result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ]; + + } result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; @@ -19582,9 +20220,9 @@ result.wireframeLinewidth = material.wireframeLinewidth; result.linewidth = material.linewidth; - if ( isPointLight && result.isMeshDistanceMaterial ) { + if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) { - result.referencePosition.copy( lightPositionWorld ); + result.referencePosition.setFromMatrixPosition( light.matrixWorld ); result.nearDistance = shadowCameraNear; result.farDistance = shadowCameraFar; @@ -19594,15 +20232,15 @@ } - function renderObject( object, camera, shadowCamera, isPointLight ) { + function renderObject( object, camera, shadowCamera, light, type ) { - if ( object.visible === false ) return; + if ( object.visible === false ) { return; } var visible = object.layers.test( camera.layers ); if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { - if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { + if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); @@ -19620,7 +20258,8 @@ if ( groupMaterial && groupMaterial.visible ) { - var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + var depthMaterial = getDepthMaterial( object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); } @@ -19629,7 +20268,8 @@ } else if ( material.visible ) { - var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + var depthMaterial = getDepthMaterial( object, material, light, shadowCamera.near, shadowCamera.far, type ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); } @@ -19642,7 +20282,7 @@ for ( var i = 0, l = children.length; i < l; i ++ ) { - renderObject( children[ i ], camera, shadowCamera, isPointLight ); + renderObject( children[ i ], camera, shadowCamera, light, type ); } @@ -19654,7 +20294,9 @@ * @author mrdoob / http://mrdoob.com/ */ - function WebGLState( gl, extensions, utils, capabilities ) { + function WebGLState( gl, extensions, capabilities ) { + + var isWebGL2 = capabilities.isWebGL2; function ColorBuffer() { @@ -19972,8 +20614,6 @@ var enabledCapabilities = {}; - var compressedTextureFormats = null; - var currentProgram = null; var currentBlendingEnabled = null; @@ -20087,9 +20727,9 @@ if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { - var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); + var extension = isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); - extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); + extension[ isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); attributeDivisors[ attribute ] = meshPerAttribute; } @@ -20133,49 +20773,58 @@ } - function getCompressedTextureFormats() { - - if ( compressedTextureFormats === null ) { - - compressedTextureFormats = []; - - if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || - extensions.get( 'WEBGL_compressed_texture_s3tc' ) || - extensions.get( 'WEBGL_compressed_texture_etc1' ) || - extensions.get( 'WEBGL_compressed_texture_astc' ) ) { - - var formats = gl.getParameter( 34467 ); + function useProgram( program ) { - for ( var i = 0; i < formats.length; i ++ ) { + if ( currentProgram !== program ) { - compressedTextureFormats.push( formats[ i ] ); + gl.useProgram( program ); - } + currentProgram = program; - } + return true; } - return compressedTextureFormats; + return false; } - function useProgram( program ) { + var equationToGL = {}; + equationToGL[ AddEquation ] = 32774; + equationToGL[ SubtractEquation ] = 32778; + equationToGL[ ReverseSubtractEquation ] = 32779; - if ( currentProgram !== program ) { + if ( isWebGL2 ) { - gl.useProgram( program ); + equationToGL[ MinEquation ] = 32775; + equationToGL[ MaxEquation ] = 32776; - currentProgram = program; + } else { - return true; + var extension = extensions.get( 'EXT_blend_minmax' ); - } + if ( extension !== null ) { - return false; + equationToGL[ MinEquation ] = extension.MIN_EXT; + equationToGL[ MaxEquation ] = extension.MAX_EXT; + + } } + var factorToGL = {}; + factorToGL[ ZeroFactor ] = 0; + factorToGL[ OneFactor ] = 1; + factorToGL[ SrcColorFactor ] = 768; + factorToGL[ SrcAlphaFactor ] = 770; + factorToGL[ SrcAlphaSaturateFactor ] = 776; + factorToGL[ DstColorFactor ] = 774; + factorToGL[ DstAlphaFactor ] = 772; + factorToGL[ OneMinusSrcColorFactor ] = 769; + factorToGL[ OneMinusSrcAlphaFactor ] = 771; + factorToGL[ OneMinusDstColorFactor ] = 775; + factorToGL[ OneMinusDstAlphaFactor ] = 773; + function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { if ( blending === NoBlending ) { @@ -20287,7 +20936,7 @@ if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { - gl.blendEquationSeparate( utils.convert( blendEquation ), utils.convert( blendEquationAlpha ) ); + gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] ); currentBlendEquation = blendEquation; currentBlendEquationAlpha = blendEquationAlpha; @@ -20296,7 +20945,7 @@ if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { - gl.blendFuncSeparate( utils.convert( blendSrc ), utils.convert( blendDst ), utils.convert( blendSrcAlpha ), utils.convert( blendDstAlpha ) ); + gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] ); currentBlendSrc = blendSrc; currentBlendDst = blendDst; @@ -20317,7 +20966,7 @@ : enable( 2884 ); var flipSided = ( material.side === BackSide ); - if ( frontFaceCW ) flipSided = ! flipSided; + if ( frontFaceCW ) { flipSided = ! flipSided; } setFlipSided( flipSided ); @@ -20334,7 +20983,8 @@ stencilBuffer.setTest( stencilWrite ); if ( stencilWrite ) { - stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilMask ); + stencilBuffer.setMask( material.stencilWriteMask ); + stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask ); stencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass ); } @@ -20403,7 +21053,7 @@ if ( width !== currentLineWidth ) { - if ( lineWidthAvailable ) gl.lineWidth( width ); + if ( lineWidthAvailable ) { gl.lineWidth( width ); } currentLineWidth = width; @@ -20452,7 +21102,7 @@ function activeTexture( webglSlot ) { - if ( webglSlot === undefined ) webglSlot = 33984 + maxTextures - 1; + if ( webglSlot === undefined ) { webglSlot = 33984 + maxTextures - 1; } if ( currentTextureSlot !== webglSlot ) { @@ -20491,6 +21141,21 @@ } + function unbindTexture() { + + var boundTexture = currentBoundTextures[ currentTextureSlot ]; + + if ( boundTexture !== undefined && boundTexture.type !== undefined ) { + + gl.bindTexture( boundTexture.type, null ); + + boundTexture.type = undefined; + boundTexture.texture = undefined; + + } + + } + function compressedTexImage2D() { try { @@ -20574,8 +21239,6 @@ enabledCapabilities = {}; - compressedTextureFormats = null; - currentTextureSlot = null; currentBoundTextures = {}; @@ -20606,7 +21269,6 @@ disableUnusedAttributes: disableUnusedAttributes, enable: enable, disable: disable, - getCompressedTextureFormats: getCompressedTextureFormats, useProgram: useProgram, @@ -20623,6 +21285,7 @@ activeTexture: activeTexture, bindTexture: bindTexture, + unbindTexture: unbindTexture, compressedTexImage2D: compressedTexImage2D, texImage2D: texImage2D, texImage3D: texImage3D, @@ -20642,12 +21305,31 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { - var _videoTextures = {}; + var isWebGL2 = capabilities.isWebGL2; + var maxTextures = capabilities.maxTextures; + var maxCubemapSize = capabilities.maxCubemapSize; + var maxTextureSize = capabilities.maxTextureSize; + var maxSamples = capabilities.maxSamples; + + var _videoTextures = new WeakMap(); var _canvas; - // + // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas, + // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")! + // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d). - var useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'; + var useOffscreenCanvas = false; + + try { + + useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' + && ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null; + + } catch ( err ) { + + // Ignore any errors + + } function createCanvas( width, height ) { @@ -20681,12 +21363,12 @@ ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) || ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) { - var floor = needsPowerOfTwo ? _Math.floorPowerOfTwo : Math.floor; + var floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor; var width = floor( scale * image.width ); var height = floor( scale * image.height ); - if ( _canvas === undefined ) _canvas = createCanvas( width, height ); + if ( _canvas === undefined ) { _canvas = createCanvas( width, height ); } // cube textures can't reuse the same canvas @@ -20722,13 +21404,13 @@ function isPowerOfTwo( image ) { - return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height ); + return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height ); } function textureNeedsPowerOfTwo( texture ) { - if ( capabilities.isWebGL2 ) return false; + if ( isWebGL2 ) { return false; } return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); @@ -20753,33 +21435,41 @@ } - function getInternalFormat( glFormat, glType ) { + function getInternalFormat( internalFormatName, glFormat, glType ) { + + if ( isWebGL2 === false ) { return glFormat; } + + if ( internalFormatName !== null ) { - if ( ! capabilities.isWebGL2 ) return glFormat; + if ( _gl[ internalFormatName ] !== undefined ) { return _gl[ internalFormatName ]; } + + console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' ); + + } var internalFormat = glFormat; if ( glFormat === 6403 ) { - if ( glType === 5126 ) internalFormat = 33326; - if ( glType === 5131 ) internalFormat = 33325; - if ( glType === 5121 ) internalFormat = 33321; + if ( glType === 5126 ) { internalFormat = 33326; } + if ( glType === 5131 ) { internalFormat = 33325; } + if ( glType === 5121 ) { internalFormat = 33321; } } if ( glFormat === 6407 ) { - if ( glType === 5126 ) internalFormat = 34837; - if ( glType === 5131 ) internalFormat = 34843; - if ( glType === 5121 ) internalFormat = 32849; + if ( glType === 5126 ) { internalFormat = 34837; } + if ( glType === 5131 ) { internalFormat = 34843; } + if ( glType === 5121 ) { internalFormat = 32849; } } if ( glFormat === 6408 ) { - if ( glType === 5126 ) internalFormat = 34836; - if ( glType === 5131 ) internalFormat = 34842; - if ( glType === 5121 ) internalFormat = 32856; + if ( glType === 5126 ) { internalFormat = 34836; } + if ( glType === 5131 ) { internalFormat = 34842; } + if ( glType === 5121 ) { internalFormat = 32856; } } @@ -20824,7 +21514,7 @@ if ( texture.isVideoTexture ) { - delete _videoTextures[ texture.id ]; + _videoTextures.delete( texture ); } @@ -20850,7 +21540,7 @@ var textureProperties = properties.get( texture ); - if ( textureProperties.__webglInit === undefined ) return; + if ( textureProperties.__webglInit === undefined ) { return; } _gl.deleteTexture( textureProperties.__webglTexture ); @@ -20863,7 +21553,7 @@ var renderTargetProperties = properties.get( renderTarget ); var textureProperties = properties.get( renderTarget.texture ); - if ( ! renderTarget ) return; + if ( ! renderTarget ) { return; } if ( textureProperties.__webglTexture !== undefined ) { @@ -20877,19 +21567,19 @@ } - if ( renderTarget.isWebGLRenderTargetCube ) { + if ( renderTarget.isWebGLCubeRenderTarget ) { for ( var i = 0; i < 6; i ++ ) { _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] ); - if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); + if ( renderTargetProperties.__webglDepthbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); } } } else { _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); - if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); + if ( renderTargetProperties.__webglDepthbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); } } @@ -20912,9 +21602,9 @@ var textureUnit = textureUnits; - if ( textureUnit >= capabilities.maxTextures ) { + if ( textureUnit >= maxTextures ) { - console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); + console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures ); } @@ -20930,7 +21620,7 @@ var textureProperties = properties.get( texture ); - if ( texture.isVideoTexture ) updateVideoTexture( texture ); + if ( texture.isVideoTexture ) { updateVideoTexture( texture ); } if ( texture.version > 0 && textureProperties.__version !== texture.version ) { @@ -20992,104 +21682,110 @@ function setTextureCube( texture, slot ) { + if ( texture.image.length !== 6 ) { return; } + var textureProperties = properties.get( texture ); - if ( texture.image.length === 6 ) { + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - if ( texture.version > 0 && textureProperties.__version !== texture.version ) { + initTexture( textureProperties, texture ); - initTexture( textureProperties, texture ); + state.activeTexture( 33984 + slot ); + state.bindTexture( 34067, textureProperties.__webglTexture ); - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + _gl.pixelStorei( 37440, texture.flipY ); - _gl.pixelStorei( 37440, texture.flipY ); + var isCompressed = ( texture && ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ) ); + var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); - var isCompressed = ( texture && texture.isCompressedTexture ); - var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); + var cubeImage = []; - var cubeImage = []; + for ( var i = 0; i < 6; i ++ ) { - for ( var i = 0; i < 6; i ++ ) { + if ( ! isCompressed && ! isDataTexture ) { - if ( ! isCompressed && ! isDataTexture ) { + cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize ); - cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, capabilities.maxCubemapSize ); + } else { - } else { + cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; - cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; + } - } + } - } + var image = cubeImage[ 0 ], + supportsMips = isPowerOfTwo( image ) || isWebGL2, + glFormat = utils.convert( texture.format ), + glType = utils.convert( texture.type ), + glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType ); - var image = cubeImage[ 0 ], - supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2, - glFormat = utils.convert( texture.format ), - glType = utils.convert( texture.type ), - glInternalFormat = getInternalFormat( glFormat, glType ); + setTextureParameters( 34067, texture, supportsMips ); - setTextureParameters( 34067, texture, supportsMips ); + var mipmaps; - var mipmaps = texture.mipmaps; + if ( isCompressed ) { for ( var i = 0; i < 6; i ++ ) { - if ( ! isCompressed ) { + mipmaps = cubeImage[ i ].mipmaps; - if ( isDataTexture ) { + for ( var j = 0; j < mipmaps.length; j ++ ) { - state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); + var mipmap = mipmaps[ j ]; - for ( var j = 0; j < mipmaps.length; ++ j ) { + if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { - var mipmap = mipmaps[ j ]; - var image = mipmap.image[ i ].image; + if ( glFormat !== null ) { - state.texImage2D( 34069 + i, j + 1, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); + state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); } } else { - state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); + state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - for ( var j = 0; j < mipmaps.length; ++ j ) { + } - var mipmap = mipmaps[ j ]; + } - state.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); + } - } + textureProperties.__maxMipLevel = mipmaps.length - 1; - } + } else { - } else { + mipmaps = texture.mipmaps; - var mipmaps = cubeImage[ i ].mipmaps; + for ( var i = 0; i < 6; i ++ ) { - for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) { + if ( isDataTexture ) { - var mipmap = mipmaps[ j ]; + state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); - if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { + for ( var j = 0; j < mipmaps.length; j ++ ) { - if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { + var mipmap = mipmaps[ j ]; + var mipmapImage = mipmap.image[ i ].image; - state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + state.texImage2D( 34069 + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); - } else { + } - console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); + } else { - } + state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); - } else { + for ( var j = 0; j < mipmaps.length; j ++ ) { - state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + var mipmap = mipmaps[ j ]; - } + state.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); } @@ -21097,25 +21793,25 @@ } - textureProperties.__maxMipLevel = isCompressed ? mipmaps.length - 1 : mipmaps.length; + textureProperties.__maxMipLevel = mipmaps.length; - if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { + } - // We assume images for cube map have the same size. - generateMipmap( 34067, texture, image.width, image.height ); + if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - } + // We assume images for cube map have the same size. + generateMipmap( 34067, texture, image.width, image.height ); - textureProperties.__version = texture.version; + } - if ( texture.onUpdate ) texture.onUpdate( texture ); + textureProperties.__version = texture.version; - } else { + if ( texture.onUpdate ) { texture.onUpdate( texture ); } - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + } else { - } + state.activeTexture( 33984 + slot ); + state.bindTexture( 34067, textureProperties.__webglTexture ); } @@ -21128,23 +21824,34 @@ } - function setTextureParameters( textureType, texture, supportsMips ) { + var wrappingToGL = {}; + wrappingToGL[ RepeatWrapping ] = 10497; + wrappingToGL[ ClampToEdgeWrapping ] = 33071; + wrappingToGL[ MirroredRepeatWrapping ] = 33648; - var extension; + var filterToGL = {}; + filterToGL[ NearestFilter ] = 9728; + filterToGL[ NearestMipmapNearestFilter ] = 9984; + filterToGL[ NearestMipmapLinearFilter ] = 9986; + filterToGL[ LinearFilter ] = 9729; + filterToGL[ LinearMipmapNearestFilter ] = 9985; + filterToGL[ LinearMipmapLinearFilter ] = 9987; + + function setTextureParameters( textureType, texture, supportsMips ) { if ( supportsMips ) { - _gl.texParameteri( textureType, 10242, utils.convert( texture.wrapS ) ); - _gl.texParameteri( textureType, 10243, utils.convert( texture.wrapT ) ); + _gl.texParameteri( textureType, 10242, wrappingToGL[ texture.wrapS ] ); + _gl.texParameteri( textureType, 10243, wrappingToGL[ texture.wrapT ] ); if ( textureType === 32879 || textureType === 35866 ) { - _gl.texParameteri( textureType, 32882, utils.convert( texture.wrapR ) ); + _gl.texParameteri( textureType, 32882, wrappingToGL[ texture.wrapR ] ); } - _gl.texParameteri( textureType, 10240, utils.convert( texture.magFilter ) ); - _gl.texParameteri( textureType, 10241, utils.convert( texture.minFilter ) ); + _gl.texParameteri( textureType, 10240, filterToGL[ texture.magFilter ] ); + _gl.texParameteri( textureType, 10241, filterToGL[ texture.minFilter ] ); } else { @@ -21174,12 +21881,12 @@ } - extension = extensions.get( 'EXT_texture_filter_anisotropic' ); + var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); if ( extension ) { - if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; - if ( texture.type === HalfFloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return; + if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) { return; } + if ( texture.type === HalfFloatType && ( isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) { return; } if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { @@ -21212,8 +21919,8 @@ var textureType = 3553; - if ( texture.isDataTexture2DArray ) textureType = 35866; - if ( texture.isDataTexture3D ) textureType = 32879; + if ( texture.isDataTexture2DArray ) { textureType = 35866; } + if ( texture.isDataTexture3D ) { textureType = 32879; } initTexture( textureProperties, texture ); @@ -21225,12 +21932,12 @@ _gl.pixelStorei( 3317, texture.unpackAlignment ); var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false; - var image = resizeImage( texture.image, needsPowerOfTwo, false, capabilities.maxTextureSize ); + var image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize ); - var supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2, + var supportsMips = isPowerOfTwo( image ) || isWebGL2, glFormat = utils.convert( texture.format ), glType = utils.convert( texture.type ), - glInternalFormat = getInternalFormat( glFormat, glType ); + glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType ); setTextureParameters( textureType, texture, supportsMips ); @@ -21244,10 +21951,10 @@ if ( texture.type === FloatType ) { - if ( ! capabilities.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' ); + if ( isWebGL2 === false ) { throw new Error( 'Float Depth Texture only supported in WebGL2.0' ); } glInternalFormat = 36012; - } else if ( capabilities.isWebGL2 ) { + } else if ( isWebGL2 ) { // WebGL 2.0 requires signed internalformat for glTexImage2D glInternalFormat = 33189; @@ -21325,7 +22032,7 @@ if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { - if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { + if ( glFormat !== null ) { state.compressedTexImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); @@ -21386,13 +22093,13 @@ if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - generateMipmap( 3553, texture, image.width, image.height ); + generateMipmap( textureType, texture, image.width, image.height ); } textureProperties.__version = texture.version; - if ( texture.onUpdate ) texture.onUpdate( texture ); + if ( texture.onUpdate ) { texture.onUpdate( texture ); } } @@ -21403,7 +22110,7 @@ var glFormat = utils.convert( renderTarget.texture.format ); var glType = utils.convert( renderTarget.texture.type ); - var glInternalFormat = getInternalFormat( glFormat, glType ); + var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); _gl.bindFramebuffer( 36160, framebuffer ); _gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); @@ -21453,7 +22160,7 @@ var glFormat = utils.convert( renderTarget.texture.format ); var glType = utils.convert( renderTarget.texture.type ); - var glInternalFormat = getInternalFormat( glFormat, glType ); + var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); if ( isMultisample ) { @@ -21476,8 +22183,8 @@ // Setup resources for a Depth Texture for a FBO (needs an extension) function setupDepthTexture( framebuffer, renderTarget ) { - var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube ); - if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' ); + var isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget ); + if ( isCube ) { throw new Error( 'Depth Texture with cube render targets is not supported' ); } _gl.bindFramebuffer( 36160, framebuffer ); @@ -21523,11 +22230,11 @@ var renderTargetProperties = properties.get( renderTarget ); - var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); + var isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); if ( renderTarget.depthTexture ) { - if ( isCube ) throw new Error( 'target.depthTexture not supported in Cube render targets' ); + if ( isCube ) { throw new Error( 'target.depthTexture not supported in Cube render targets' ); } setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget ); @@ -21571,9 +22278,9 @@ info.memory.textures ++; - var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); + var isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true ); - var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2; + var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2; // Setup framebuffer @@ -21593,15 +22300,16 @@ if ( isMultisample ) { - if ( capabilities.isWebGL2 ) { + if ( isWebGL2 ) { renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer(); _gl.bindRenderbuffer( 36161, renderTargetProperties.__webglColorRenderbuffer ); + var glFormat = utils.convert( renderTarget.texture.format ); var glType = utils.convert( renderTarget.texture.type ); - var glInternalFormat = getInternalFormat( glFormat, glType ); + var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); var samples = getRenderTargetSamples( renderTarget ); _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height ); @@ -21679,11 +22387,11 @@ function updateRenderTargetMipmap( renderTarget ) { var texture = renderTarget.texture; - var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2; + var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2; if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - var target = renderTarget.isWebGLRenderTargetCube ? 34067 : 3553; + var target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553; var webglTexture = properties.get( texture ).__webglTexture; state.bindTexture( target, webglTexture ); @@ -21698,7 +22406,7 @@ if ( renderTarget.isWebGLMultisampleRenderTarget ) { - if ( capabilities.isWebGL2 ) { + if ( isWebGL2 ) { var renderTargetProperties = properties.get( renderTarget ); @@ -21709,8 +22417,8 @@ var height = renderTarget.height; var mask = 16384; - if ( renderTarget.depthBuffer ) mask |= 256; - if ( renderTarget.stencilBuffer ) mask |= 1024; + if ( renderTarget.depthBuffer ) { mask |= 256; } + if ( renderTarget.stencilBuffer ) { mask |= 1024; } _gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, 9728 ); @@ -21726,21 +22434,20 @@ function getRenderTargetSamples( renderTarget ) { - return ( capabilities.isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ? - Math.min( capabilities.maxSamples, renderTarget.samples ) : 0; + return ( isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ? + Math.min( maxSamples, renderTarget.samples ) : 0; } function updateVideoTexture( texture ) { - var id = texture.id; var frame = info.render.frame; // Check the last frame we updated the VideoTexture - if ( _videoTextures[ id ] !== frame ) { + if ( _videoTextures.get( texture ) !== frame ) { - _videoTextures[ id ] = frame; + _videoTextures.set( texture, frame ); texture.update(); } @@ -21773,7 +22480,7 @@ function safeSetTextureCube( texture, slot ) { - if ( texture && texture.isWebGLRenderTargetCube ) { + if ( texture && texture.isWebGLCubeRenderTarget ) { if ( warnedTextureCube === false ) { @@ -21786,7 +22493,7 @@ } - // currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture + // currently relying on the fact that WebGLCubeRenderTarget.texture is a Texture and NOT a CubeTexture // TODO: unify these code paths if ( ( texture && texture.isCubeTexture ) || ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { @@ -21798,7 +22505,7 @@ } else { - // assumed: texture property of THREE.WebGLRenderTargetCube + // assumed: texture property of THREE.WebGLCubeRenderTarget setTextureCubeDynamic( texture, slot ); } @@ -21830,69 +22537,58 @@ function WebGLUtils( gl, extensions, capabilities ) { + var isWebGL2 = capabilities.isWebGL2; + function convert( p ) { var extension; - if ( p === RepeatWrapping ) return 10497; - if ( p === ClampToEdgeWrapping ) return 33071; - if ( p === MirroredRepeatWrapping ) return 33648; + if ( p === UnsignedByteType ) { return 5121; } + if ( p === UnsignedShort4444Type ) { return 32819; } + if ( p === UnsignedShort5551Type ) { return 32820; } + if ( p === UnsignedShort565Type ) { return 33635; } + + if ( p === ByteType ) { return 5120; } + if ( p === ShortType ) { return 5122; } + if ( p === UnsignedShortType ) { return 5123; } + if ( p === IntType ) { return 5124; } + if ( p === UnsignedIntType ) { return 5125; } + if ( p === FloatType ) { return 5126; } - if ( p === NearestFilter ) return 9728; - if ( p === NearestMipmapNearestFilter ) return 9984; - if ( p === NearestMipmapLinearFilter ) return 9986; + if ( p === HalfFloatType ) { - if ( p === LinearFilter ) return 9729; - if ( p === LinearMipmapNearestFilter ) return 9985; - if ( p === LinearMipmapLinearFilter ) return 9987; + if ( isWebGL2 ) { return 5131; } - if ( p === UnsignedByteType ) return 5121; - if ( p === UnsignedShort4444Type ) return 32819; - if ( p === UnsignedShort5551Type ) return 32820; - if ( p === UnsignedShort565Type ) return 33635; + extension = extensions.get( 'OES_texture_half_float' ); - if ( p === ByteType ) return 5120; - if ( p === ShortType ) return 5122; - if ( p === UnsignedShortType ) return 5123; - if ( p === IntType ) return 5124; - if ( p === UnsignedIntType ) return 5125; - if ( p === FloatType ) return 5126; + if ( extension !== null ) { - if ( p === HalfFloatType ) { + return extension.HALF_FLOAT_OES; - if ( capabilities.isWebGL2 ) return 5131; + } else { - extension = extensions.get( 'OES_texture_half_float' ); + return null; - if ( extension !== null ) return extension.HALF_FLOAT_OES; + } } - if ( p === AlphaFormat ) return 6406; - if ( p === RGBFormat ) return 6407; - if ( p === RGBAFormat ) return 6408; - if ( p === LuminanceFormat ) return 6409; - if ( p === LuminanceAlphaFormat ) return 6410; - if ( p === DepthFormat ) return 6402; - if ( p === DepthStencilFormat ) return 34041; - if ( p === RedFormat ) return 6403; - - if ( p === AddEquation ) return 32774; - if ( p === SubtractEquation ) return 32778; - if ( p === ReverseSubtractEquation ) return 32779; + if ( p === AlphaFormat ) { return 6406; } + if ( p === RGBFormat ) { return 6407; } + if ( p === RGBAFormat ) { return 6408; } + if ( p === LuminanceFormat ) { return 6409; } + if ( p === LuminanceAlphaFormat ) { return 6410; } + if ( p === DepthFormat ) { return 6402; } + if ( p === DepthStencilFormat ) { return 34041; } + if ( p === RedFormat ) { return 6403; } - if ( p === ZeroFactor ) return 0; - if ( p === OneFactor ) return 1; - if ( p === SrcColorFactor ) return 768; - if ( p === OneMinusSrcColorFactor ) return 769; - if ( p === SrcAlphaFactor ) return 770; - if ( p === OneMinusSrcAlphaFactor ) return 771; - if ( p === DstAlphaFactor ) return 772; - if ( p === OneMinusDstAlphaFactor ) return 773; + // WebGL2 formats. - if ( p === DstColorFactor ) return 774; - if ( p === OneMinusDstColorFactor ) return 775; - if ( p === SrcAlphaSaturateFactor ) return 776; + if ( p === RedIntegerFormat ) { return 36244; } + if ( p === RGFormat ) { return 33319; } + if ( p === RGIntegerFormat ) { return 33320; } + if ( p === RGBIntegerFormat ) { return 36248; } + if ( p === RGBAIntegerFormat ) { return 36249; } if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) { @@ -21901,10 +22597,14 @@ if ( extension !== null ) { - if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; - if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; - if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; - if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; + if ( p === RGB_S3TC_DXT1_Format ) { return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; } + if ( p === RGBA_S3TC_DXT1_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; } + if ( p === RGBA_S3TC_DXT3_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; } + if ( p === RGBA_S3TC_DXT5_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; } + + } else { + + return null; } @@ -21917,10 +22617,14 @@ if ( extension !== null ) { - if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; - if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; - if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; - if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + if ( p === RGB_PVRTC_4BPPV1_Format ) { return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; } + if ( p === RGB_PVRTC_2BPPV1_Format ) { return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; } + if ( p === RGBA_PVRTC_4BPPV1_Format ) { return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; } + if ( p === RGBA_PVRTC_2BPPV1_Format ) { return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; } + + } else { + + return null; } @@ -21930,41 +22634,53 @@ extension = extensions.get( 'WEBGL_compressed_texture_etc1' ); - if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL; + if ( extension !== null ) { + + return extension.COMPRESSED_RGB_ETC1_WEBGL; + + } else { + + return null; + + } } - if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || - p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || - p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || - p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || - p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) { + if ( p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) { - extension = extensions.get( 'WEBGL_compressed_texture_astc' ); + extension = extensions.get( 'WEBGL_compressed_texture_etc' ); if ( extension !== null ) { - return p; + if ( p === RGB_ETC2_Format ) { return extension.COMPRESSED_RGB8_ETC2; } + if ( p === RGBA_ETC2_EAC_Format ) { return extension.COMPRESSED_RGBA8_ETC2_EAC; } } } - if ( p === MinEquation || p === MaxEquation ) { + if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || + p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || + p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || + p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || + p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format || + p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format || + p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format || + p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format || + p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format || + p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format ) { - if ( capabilities.isWebGL2 ) { + extension = extensions.get( 'WEBGL_compressed_texture_astc' ); - if ( p === MinEquation ) return 32775; - if ( p === MaxEquation ) return 32776; + if ( extension !== null ) { - } + // TODO Complete? - extension = extensions.get( 'EXT_blend_minmax' ); + return p; - if ( extension !== null ) { + } else { - if ( p === MinEquation ) return extension.MIN_EXT; - if ( p === MaxEquation ) return extension.MAX_EXT; + return null; } @@ -21972,42 +22688,28 @@ if ( p === UnsignedInt248Type ) { - if ( capabilities.isWebGL2 ) return 34042; + if ( isWebGL2 ) { return 34042; } extension = extensions.get( 'WEBGL_depth_texture' ); - if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL; - - } - - return 0; + if ( extension !== null ) { - } + return extension.UNSIGNED_INT_24_8_WEBGL; - return { convert: convert }; + } else { - } + return null; - /** - * @author mrdoob / http://mrdoob.com/ - */ + } - function Group() { + } - Object3D.call( this ); + } - this.type = 'Group'; + return { convert: convert }; } - Group.prototype = Object.assign( Object.create( Object3D.prototype ), { - - constructor: Group, - - isGroup: true - - } ); - /** * @author mrdoob / http://mrdoob.com/ */ @@ -22029,631 +22731,382 @@ } ); /** - * @author jsantell / https://www.jsantell.com/ * @author mrdoob / http://mrdoob.com/ */ - var cameraLPos = new Vector3(); - var cameraRPos = new Vector3(); - - /** - * Assumes 2 cameras that are parallel and share an X-axis, and that - * the cameras' projection and world matrices have already been set. - * And that near and far planes are identical for both cameras. - * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765 - */ - function setProjectionFromUnion( camera, cameraL, cameraR ) { - - cameraLPos.setFromMatrixPosition( cameraL.matrixWorld ); - cameraRPos.setFromMatrixPosition( cameraR.matrixWorld ); - - var ipd = cameraLPos.distanceTo( cameraRPos ); - - var projL = cameraL.projectionMatrix.elements; - var projR = cameraR.projectionMatrix.elements; + function Group() { - // VR systems will have identical far and near planes, and - // most likely identical top and bottom frustum extents. - // Use the left camera for these values. - var near = projL[ 14 ] / ( projL[ 10 ] - 1 ); - var far = projL[ 14 ] / ( projL[ 10 ] + 1 ); - var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ]; - var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ]; + Object3D.call( this ); - var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ]; - var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ]; - var left = near * leftFov; - var right = near * rightFov; + this.type = 'Group'; - // Calculate the new camera's position offset from the - // left camera. xOffset should be roughly half `ipd`. - var zOffset = ipd / ( - leftFov + rightFov ); - var xOffset = zOffset * - leftFov; + } - // TODO: Better way to apply this offset? - cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale ); - camera.translateX( xOffset ); - camera.translateZ( zOffset ); - camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale ); - camera.matrixWorldInverse.getInverse( camera.matrixWorld ); + Group.prototype = Object.assign( Object.create( Object3D.prototype ), { - // Find the union of the frustum values of the cameras and scale - // the values so that the near plane's position does not change in world space, - // although must now be relative to the new union camera. - var near2 = near + zOffset; - var far2 = far + zOffset; - var left2 = left - xOffset; - var right2 = right + ( ipd - xOffset ); - var top2 = topFov * far / far2 * near2; - var bottom2 = bottomFov * far / far2 * near2; + constructor: Group, - camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 ); + isGroup: true - } + } ); /** * @author mrdoob / http://mrdoob.com/ */ - function WebVRManager( renderer ) { + function WebXRManager( renderer, gl ) { - var renderWidth, renderHeight; var scope = this; - var device = null; - var frameData = null; - - var poseTarget = null; - - var controllers = []; - var standingMatrix = new Matrix4(); - var standingMatrixInverse = new Matrix4(); + var session = null; var framebufferScaleFactor = 1.0; + var referenceSpace = null; var referenceSpaceType = 'local-floor'; - if ( typeof window !== 'undefined' && 'VRFrameData' in window ) { - - frameData = new window.VRFrameData(); - window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false ); + var pose = null; - } + var controllers = []; + var inputSourcesMap = new Map(); - var matrixWorldInverse = new Matrix4(); - var tempQuaternion = new Quaternion(); - var tempPosition = new Vector3(); + // var cameraL = new PerspectiveCamera(); - cameraL.viewport = new Vector4(); cameraL.layers.enable( 1 ); + cameraL.viewport = new Vector4(); var cameraR = new PerspectiveCamera(); - cameraR.viewport = new Vector4(); cameraR.layers.enable( 2 ); + cameraR.viewport = new Vector4(); var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); cameraVR.layers.enable( 1 ); cameraVR.layers.enable( 2 ); - // - - function isPresenting() { - - return device !== null && device.isPresenting === true; - - } - - var currentSize = new Vector2(), currentPixelRatio; - - function onVRDisplayPresentChange() { - - if ( isPresenting() ) { - - var eyeParameters = device.getEyeParameters( 'left' ); - renderWidth = 2 * eyeParameters.renderWidth * framebufferScaleFactor; - renderHeight = eyeParameters.renderHeight * framebufferScaleFactor; - - currentPixelRatio = renderer.getPixelRatio(); - renderer.getSize( currentSize ); - - renderer.setDrawingBufferSize( renderWidth, renderHeight, 1 ); - - cameraL.viewport.set( 0, 0, renderWidth / 2, renderHeight ); - cameraR.viewport.set( renderWidth / 2, 0, renderWidth / 2, renderHeight ); - - animation.start(); - - scope.dispatchEvent( { type: 'sessionstart' } ); - - } else { - - if ( scope.enabled ) { - - renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio ); - - } - - animation.stop(); - - scope.dispatchEvent( { type: 'sessionend' } ); - - } - - } + var _currentDepthNear = null; + var _currentDepthFar = null; // - var triggers = []; - - function findGamepad( id ) { - - var gamepads = navigator.getGamepads && navigator.getGamepads(); - - for ( var i = 0, j = 0, l = gamepads.length; i < l; i ++ ) { - - var gamepad = gamepads[ i ]; - - if ( gamepad && ( gamepad.id === 'Daydream Controller' || - gamepad.id === 'Gear VR Controller' || gamepad.id === 'Oculus Go Controller' || - gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || - gamepad.id.startsWith( 'HTC Vive Focus' ) || - gamepad.id.startsWith( 'Spatial Controller' ) ) ) { - - if ( j === id ) return gamepad; - - j ++; - - } - - } - - } - - function updateControllers() { - - for ( var i = 0; i < controllers.length; i ++ ) { - - var controller = controllers[ i ]; - - var gamepad = findGamepad( i ); - - if ( gamepad !== undefined && gamepad.pose !== undefined ) { - - if ( gamepad.pose === null ) return; - - // Pose - - var pose = gamepad.pose; - - if ( pose.hasPosition === false ) controller.position.set( 0.2, - 0.6, - 0.05 ); - - if ( pose.position !== null ) controller.position.fromArray( pose.position ); - if ( pose.orientation !== null ) controller.quaternion.fromArray( pose.orientation ); - controller.matrix.compose( controller.position, controller.quaternion, controller.scale ); - controller.matrix.premultiply( standingMatrix ); - controller.matrix.decompose( controller.position, controller.quaternion, controller.scale ); - controller.matrixWorldNeedsUpdate = true; - controller.visible = true; - - // Trigger - - var buttonId = gamepad.id === 'Daydream Controller' ? 0 : 1; - - if ( triggers[ i ] === undefined ) triggers[ i ] = false; - - if ( triggers[ i ] !== gamepad.buttons[ buttonId ].pressed ) { - - triggers[ i ] = gamepad.buttons[ buttonId ].pressed; - - if ( triggers[ i ] === true ) { - - controller.dispatchEvent( { type: 'selectstart' } ); - - } else { - - controller.dispatchEvent( { type: 'selectend' } ); - controller.dispatchEvent( { type: 'select' } ); + this.enabled = false; - } + this.isPresenting = false; - } + this.getController = function ( id ) { - } else { + var controller = controllers[ id ]; - controller.visible = false; + if ( controller === undefined ) { - } + controller = {}; + controllers[ id ] = controller; } - } - - function updateViewportFromBounds( viewport, bounds ) { - - if ( bounds !== null && bounds.length === 4 ) { + if ( controller.targetRay === undefined ) { - viewport.set( bounds[ 0 ] * renderWidth, bounds[ 1 ] * renderHeight, bounds[ 2 ] * renderWidth, bounds[ 3 ] * renderHeight ); + controller.targetRay = new Group(); + controller.targetRay.matrixAutoUpdate = false; + controller.targetRay.visible = false; } - } + return controller.targetRay; - // + }; - this.enabled = false; - - this.getController = function ( id ) { + this.getControllerGrip = function ( id ) { var controller = controllers[ id ]; if ( controller === undefined ) { - controller = new Group(); - controller.matrixAutoUpdate = false; - controller.visible = false; - + controller = {}; controllers[ id ] = controller; } - return controller; - - }; - - this.getDevice = function () { - - return device; + if ( controller.grip === undefined ) { - }; - - this.setDevice = function ( value ) { - - if ( value !== undefined ) device = value; - - animation.setContext( value ); + controller.grip = new Group(); + controller.grip.matrixAutoUpdate = false; + controller.grip.visible = false; - }; - - this.setFramebufferScaleFactor = function ( value ) { + } - framebufferScaleFactor = value; + return controller.grip; }; - this.setReferenceSpaceType = function ( value ) { - - referenceSpaceType = value; + // - }; + function onSessionEvent( event ) { - this.setPoseTarget = function ( object ) { + var controller = inputSourcesMap.get( event.inputSource ); - if ( object !== undefined ) poseTarget = object; + if ( controller ) { - }; + if ( controller.targetRay ) { - this.getCamera = function ( camera ) { + controller.targetRay.dispatchEvent( { type: event.type } ); - var userHeight = referenceSpaceType === 'local-floor' ? 1.6 : 0; + } - if ( isPresenting() === false ) { + if ( controller.grip ) { - camera.position.set( 0, userHeight, 0 ); - camera.rotation.set( 0, 0, 0 ); + controller.grip.dispatchEvent( { type: event.type } ); - return camera; + } } - device.depthNear = camera.near; - device.depthFar = camera.far; - - device.getFrameData( frameData ); - - // - - if ( referenceSpaceType === 'local-floor' ) { + } - var stageParameters = device.stageParameters; + function onSessionEnd() { - if ( stageParameters ) { + inputSourcesMap.forEach( function ( controller, inputSource ) { - standingMatrix.fromArray( stageParameters.sittingToStandingTransform ); + if ( controller.targetRay ) { - } else { - - standingMatrix.makeTranslation( 0, userHeight, 0 ); + controller.targetRay.dispatchEvent( { type: 'disconnected', data: inputSource } ); + controller.targetRay.visible = false; } - } - - - var pose = frameData.pose; - var poseObject = poseTarget !== null ? poseTarget : camera; - - // We want to manipulate poseObject by its position and quaternion components since users may rely on them. - poseObject.matrix.copy( standingMatrix ); - poseObject.matrix.decompose( poseObject.position, poseObject.quaternion, poseObject.scale ); - - if ( pose.orientation !== null ) { + if ( controller.grip ) { - tempQuaternion.fromArray( pose.orientation ); - poseObject.quaternion.multiply( tempQuaternion ); + controller.grip.dispatchEvent( { type: 'disconnected', data: inputSource } ); + controller.grip.visible = false; - } - - if ( pose.position !== null ) { - - tempQuaternion.setFromRotationMatrix( standingMatrix ); - tempPosition.fromArray( pose.position ); - tempPosition.applyQuaternion( tempQuaternion ); - poseObject.position.add( tempPosition ); + } - } + } ); - poseObject.updateMatrixWorld(); + inputSourcesMap.clear(); // - cameraL.near = camera.near; - cameraR.near = camera.near; - - cameraL.far = camera.far; - cameraR.far = camera.far; - - cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix ); - cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix ); - - // TODO (mrdoob) Double check this code - - standingMatrixInverse.getInverse( standingMatrix ); - - if ( referenceSpaceType === 'local-floor' ) { - - cameraL.matrixWorldInverse.multiply( standingMatrixInverse ); - cameraR.matrixWorldInverse.multiply( standingMatrixInverse ); - - } - - var parent = poseObject.parent; + renderer.setFramebuffer( null ); + renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830 + animation.stop(); - if ( parent !== null ) { + scope.isPresenting = false; - matrixWorldInverse.getInverse( parent.matrixWorld ); + scope.dispatchEvent( { type: 'sessionend' } ); - cameraL.matrixWorldInverse.multiply( matrixWorldInverse ); - cameraR.matrixWorldInverse.multiply( matrixWorldInverse ); + } - } + function onRequestReferenceSpace( value ) { - // envMap and Mirror needs camera.matrixWorld + referenceSpace = value; - cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse ); - cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse ); + animation.setContext( session ); + animation.start(); - cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix ); - cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix ); + scope.isPresenting = true; - setProjectionFromUnion( cameraVR, cameraL, cameraR ); + scope.dispatchEvent( { type: 'sessionstart' } ); - // + } - var layers = device.getLayers(); + this.setFramebufferScaleFactor = function ( value ) { - if ( layers.length ) { + framebufferScaleFactor = value; - var layer = layers[ 0 ]; + // Warn if function is used while presenting + if ( scope.isPresenting == true ) { - updateViewportFromBounds( cameraL.viewport, layer.leftBounds ); - updateViewportFromBounds( cameraR.viewport, layer.rightBounds ); + console.warn( "WebXRManager: Cannot change framebuffer scale while presenting VR content" ); } - updateControllers(); - - return cameraVR; - }; - this.getStandingMatrix = function () { - - return standingMatrix; - - }; - - this.isPresenting = isPresenting; - - // Animation Loop - - var animation = new WebGLAnimation(); - - this.setAnimationLoop = function ( callback ) { - - animation.setAnimationLoop( callback ); - - if ( isPresenting() ) animation.start(); - - }; - - this.submitFrame = function () { + this.setReferenceSpaceType = function ( value ) { - if ( isPresenting() ) device.submitFrame(); + referenceSpaceType = value; }; - this.dispose = function () { - - if ( typeof window !== 'undefined' ) { - - window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange ); + this.getReferenceSpace = function () { - } + return referenceSpace; }; - // DEPRECATED - - this.setFrameOfReferenceType = function () { + this.getSession = function () { - console.warn( 'THREE.WebVRManager: setFrameOfReferenceType() has been deprecated.' ); + return session; }; - } - - Object.assign( WebVRManager.prototype, EventDispatcher.prototype ); - - /** - * @author mrdoob / http://mrdoob.com/ - */ - - function WebXRManager( renderer, gl ) { - - var scope = this; - - var session = null; - - var referenceSpace = null; - var referenceSpaceType = 'local-floor'; - - var pose = null; - - var controllers = []; - var inputSources = []; - - function isPresenting() { - - return session !== null && referenceSpace !== null; - - } - - // + this.setSession = function ( value ) { - var cameraL = new PerspectiveCamera(); - cameraL.layers.enable( 1 ); - cameraL.viewport = new Vector4(); + session = value; - var cameraR = new PerspectiveCamera(); - cameraR.layers.enable( 2 ); - cameraR.viewport = new Vector4(); + if ( session !== null ) { - var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); - cameraVR.layers.enable( 1 ); - cameraVR.layers.enable( 2 ); + session.addEventListener( 'select', onSessionEvent ); + session.addEventListener( 'selectstart', onSessionEvent ); + session.addEventListener( 'selectend', onSessionEvent ); + session.addEventListener( 'squeeze', onSessionEvent ); + session.addEventListener( 'squeezestart', onSessionEvent ); + session.addEventListener( 'squeezeend', onSessionEvent ); + session.addEventListener( 'end', onSessionEnd ); - // + var attributes = gl.getContextAttributes(); - this.enabled = false; + var layerInit = { + antialias: attributes.antialias, + alpha: attributes.alpha, + depth: attributes.depth, + stencil: attributes.stencil, + framebufferScaleFactor: framebufferScaleFactor + }; - this.getController = function ( id ) { + // eslint-disable-next-line no-undef + var baseLayer = new XRWebGLLayer( session, gl, layerInit ); - var controller = controllers[ id ]; + session.updateRenderState( { baseLayer: baseLayer } ); - if ( controller === undefined ) { + session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace ); - controller = new Group(); - controller.matrixAutoUpdate = false; - controller.visible = false; + // - controllers[ id ] = controller; + session.addEventListener( 'inputsourceschange', updateInputSources ); } - return controller; - }; - // + function updateInputSources( event ) { - function onSessionEvent( event ) { - - for ( var i = 0; i < controllers.length; i ++ ) { + var inputSources = session.inputSources; - if ( inputSources[ i ] === event.inputSource ) { + // Assign inputSources to available controllers - controllers[ i ].dispatchEvent( { type: event.type } ); + for ( var i = 0; i < controllers.length; i ++ ) { - } + inputSourcesMap.set( inputSources[ i ], controllers[ i ] ); } - } + // Notify disconnected - function onSessionEnd() { + for ( var i = 0; i < event.removed.length; i ++ ) { - renderer.setFramebuffer( null ); - renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830 - animation.stop(); - - scope.dispatchEvent( { type: 'sessionend' } ); + var inputSource = event.removed[ i ]; + var controller = inputSourcesMap.get( inputSource ); - } - - function onRequestReferenceSpace( value ) { + if ( controller ) { - referenceSpace = value; + if ( controller.targetRay ) { - animation.setContext( session ); - animation.start(); + controller.targetRay.dispatchEvent( { type: 'disconnected', data: inputSource } ); - scope.dispatchEvent( { type: 'sessionstart' } ); + } - } + if ( controller.grip ) { - this.setFramebufferScaleFactor = function ( value ) { + controller.grip.dispatchEvent( { type: 'disconnected', data: inputSource } ); - }; + } - this.setReferenceSpaceType = function ( value ) { + inputSourcesMap.delete( inputSource ); - referenceSpaceType = value; + } - }; + } - this.getSession = function () { + // Notify connected - return session; + for ( var i = 0; i < event.added.length; i ++ ) { - }; + var inputSource = event.added[ i ]; + var controller = inputSourcesMap.get( inputSource ); - this.setSession = function ( value ) { + if ( controller ) { - session = value; + if ( controller.targetRay ) { - if ( session !== null ) { + controller.targetRay.dispatchEvent( { type: 'connected', data: inputSource } ); - session.addEventListener( 'select', onSessionEvent ); - session.addEventListener( 'selectstart', onSessionEvent ); - session.addEventListener( 'selectend', onSessionEvent ); - session.addEventListener( 'end', onSessionEnd ); + } - session.updateRenderState( { baseLayer: new XRWebGLLayer( session, gl ) } ); + if ( controller.grip ) { - session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace ); + controller.grip.dispatchEvent( { type: 'connected', data: inputSource } ); - // + } - inputSources = session.inputSources; + } - session.addEventListener( 'inputsourceschange', function () { + } - inputSources = session.inputSources; - console.log( inputSources ); + } - for ( var i = 0; i < controllers.length; i ++ ) { + // - var controller = controllers[ i ]; - controller.userData.inputSource = inputSources[ i ]; + var cameraLPos = new Vector3(); + var cameraRPos = new Vector3(); - } + /** + * @author jsantell / https://www.jsantell.com/ + * + * Assumes 2 cameras that are parallel and share an X-axis, and that + * the cameras' projection and world matrices have already been set. + * And that near and far planes are identical for both cameras. + * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765 + */ + function setProjectionFromUnion( camera, cameraL, cameraR ) { + + cameraLPos.setFromMatrixPosition( cameraL.matrixWorld ); + cameraRPos.setFromMatrixPosition( cameraR.matrixWorld ); + + var ipd = cameraLPos.distanceTo( cameraRPos ); + + var projL = cameraL.projectionMatrix.elements; + var projR = cameraR.projectionMatrix.elements; + + // VR systems will have identical far and near planes, and + // most likely identical top and bottom frustum extents. + // Use the left camera for these values. + var near = projL[ 14 ] / ( projL[ 10 ] - 1 ); + var far = projL[ 14 ] / ( projL[ 10 ] + 1 ); + var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ]; + var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ]; + + var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ]; + var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ]; + var left = near * leftFov; + var right = near * rightFov; + + // Calculate the new camera's position offset from the + // left camera. xOffset should be roughly half `ipd`. + var zOffset = ipd / ( - leftFov + rightFov ); + var xOffset = zOffset * - leftFov; + + // TODO: Better way to apply this offset? + cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale ); + camera.translateX( xOffset ); + camera.translateZ( zOffset ); + camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale ); + camera.matrixWorldInverse.getInverse( camera.matrixWorld ); - } ); + // Find the union of the frustum values of the cameras and scale + // the values so that the near plane's position does not change in world space, + // although must now be relative to the new union camera. + var near2 = near + zOffset; + var far2 = far + zOffset; + var left2 = left - xOffset; + var right2 = right + ( ipd - xOffset ); + var top2 = topFov * far / far2 * near2; + var bottom2 = bottomFov * far / far2 * near2; - } + camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 ); - }; + } function updateCamera( camera, parent ) { @@ -22673,42 +23126,51 @@ this.getCamera = function ( camera ) { - if ( isPresenting() ) { + cameraVR.near = cameraR.near = cameraL.near = camera.near; + cameraVR.far = cameraR.far = cameraL.far = camera.far; - var parent = camera.parent; - var cameras = cameraVR.cameras; + if ( _currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far ) { - updateCamera( cameraVR, parent ); + // Note that the new renderState won't apply until the next frame. See #18320 - for ( var i = 0; i < cameras.length; i ++ ) { + session.updateRenderState( { + depthNear: cameraVR.near, + depthFar: cameraVR.far + } ); - updateCamera( cameras[ i ], parent ); + _currentDepthNear = cameraVR.near; + _currentDepthFar = cameraVR.far; - } + } - // update camera and its children + var parent = camera.parent; + var cameras = cameraVR.cameras; - camera.matrixWorld.copy( cameraVR.matrixWorld ); + updateCamera( cameraVR, parent ); - var children = camera.children; + for ( var i = 0; i < cameras.length; i ++ ) { - for ( var i = 0, l = children.length; i < l; i ++ ) { + updateCamera( cameras[ i ], parent ); - children[ i ].updateMatrixWorld( true ); + } - } + // update camera and its children - setProjectionFromUnion( cameraVR, cameraL, cameraR ); + camera.matrixWorld.copy( cameraVR.matrixWorld ); - return cameraVR; + var children = camera.children; + + for ( var i = 0, l = children.length; i < l; i ++ ) { + + children[ i ].updateMatrixWorld( true ); } - return camera; + setProjectionFromUnion( cameraVR, cameraL, cameraR ); - }; + return cameraVR; - this.isPresenting = isPresenting; + }; // Animation Loop @@ -22729,10 +23191,9 @@ var view = views[ i ]; var viewport = baseLayer.getViewport( view ); - var viewMatrix = view.transform.inverse.matrix; var camera = cameraVR.cameras[ i ]; - camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix ); + camera.matrix.fromArray( view.transform.matrix ); camera.projectionMatrix.fromArray( view.projectionMatrix ); camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); @@ -22748,75 +23209,75 @@ // + var inputSources = session.inputSources; + for ( var i = 0; i < controllers.length; i ++ ) { var controller = controllers[ i ]; var inputSource = inputSources[ i ]; - if ( inputSource ) { - - var inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); + var inputPose = null; + var gripPose = null; - if ( inputPose !== null ) { + if ( inputSource ) { - controller.matrix.fromArray( inputPose.transform.matrix ); - controller.matrix.decompose( controller.position, controller.rotation, controller.scale ); - controller.visible = true; + if ( controller.targetRay ) { - continue; + inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); - } + if ( inputPose !== null ) { - } + controller.targetRay.matrix.fromArray( inputPose.transform.matrix ); + controller.targetRay.matrix.decompose( controller.targetRay.position, controller.targetRay.rotation, controller.targetRay.scale ); - controller.visible = false; + } - } + } - if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); + if ( controller.grip && inputSource.gripSpace ) { - } + gripPose = frame.getPose( inputSource.gripSpace, referenceSpace ); - var animation = new WebGLAnimation(); - animation.setAnimationLoop( onAnimationFrame ); + if ( gripPose !== null ) { - this.setAnimationLoop = function ( callback ) { + controller.grip.matrix.fromArray( gripPose.transform.matrix ); + controller.grip.matrix.decompose( controller.grip.position, controller.grip.rotation, controller.grip.scale ); - onAnimationFrameCallback = callback; + } - }; + } - this.dispose = function () {}; + } - // DEPRECATED + if ( controller.targetRay ) { - this.getStandingMatrix = function () { + controller.targetRay.visible = inputPose !== null; - console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' ); - return new Matrix4(); + } - }; + if ( controller.grip ) { - this.getDevice = function () { + controller.grip.visible = gripPose !== null; - console.warn( 'THREE.WebXRManager: getDevice() has been deprecated.' ); + } - }; + } - this.setDevice = function () { + if ( onAnimationFrameCallback ) { onAnimationFrameCallback( time, frame ); } - console.warn( 'THREE.WebXRManager: setDevice() has been deprecated.' ); + } - }; + var animation = new WebGLAnimation(); + animation.setAnimationLoop( onAnimationFrame ); - this.setFrameOfReferenceType = function () { + this.setAnimationLoop = function ( callback ) { - console.warn( 'THREE.WebXRManager: setFrameOfReferenceType() has been deprecated.' ); + onAnimationFrameCallback = callback; }; - this.submitFrame = function () {}; + this.dispose = function () {}; } @@ -22882,8 +23343,7 @@ // physically based shading this.gammaFactor = 2.0; // for backwards compatibility - this.gammaInput = false; - this.gammaOutput = false; + this.outputEncoding = LinearEncoding; // physical lights @@ -22937,6 +23397,8 @@ _height = _canvas.height, _pixelRatio = 1, + _opaqueSort = null, + _transparentSort = null, _viewport = new Vector4( 0, 0, _width, _height ), _scissor = new Vector4( 0, 0, _width, _height ), @@ -23036,7 +23498,7 @@ capabilities = new WebGLCapabilities( _gl, extensions, parameters ); - if ( ! capabilities.isWebGL2 ) { + if ( capabilities.isWebGL2 === false ) { extensions.get( 'WEBGL_depth_texture' ); extensions.get( 'OES_texture_float' ); @@ -23052,16 +23514,16 @@ utils = new WebGLUtils( _gl, extensions, capabilities ); - state = new WebGLState( _gl, extensions, utils, capabilities ); + state = new WebGLState( _gl, extensions, capabilities ); state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() ); state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() ); info = new WebGLInfo( _gl ); properties = new WebGLProperties(); textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); - attributes = new WebGLAttributes( _gl ); + attributes = new WebGLAttributes( _gl, capabilities ); geometries = new WebGLGeometries( _gl, attributes, info ); - objects = new WebGLObjects( geometries, info ); + objects = new WebGLObjects( _gl, geometries, attributes, info ); morphtargets = new WebGLMorphtargets( _gl ); programCache = new WebGLPrograms( _this, extensions, capabilities ); renderLists = new WebGLRenderLists(); @@ -23085,11 +23547,11 @@ initGLContext(); - // vr + // xr - var vr = ( typeof navigator !== 'undefined' && 'xr' in navigator && 'supportsSession' in navigator.xr ) ? new WebXRManager( _this, _gl ) : new WebVRManager( _this ); + var xr = new WebXRManager( _this, _gl ); - this.vr = vr; + this.xr = xr; // shadow map @@ -23114,14 +23576,14 @@ this.forceContextLoss = function () { var extension = extensions.get( 'WEBGL_lose_context' ); - if ( extension ) extension.loseContext(); + if ( extension ) { extension.loseContext(); } }; this.forceContextRestore = function () { var extension = extensions.get( 'WEBGL_lose_context' ); - if ( extension ) extension.restoreContext(); + if ( extension ) { extension.restoreContext(); } }; @@ -23133,7 +23595,7 @@ this.setPixelRatio = function ( value ) { - if ( value === undefined ) return; + if ( value === undefined ) { return; } _pixelRatio = value; @@ -23157,7 +23619,7 @@ this.setSize = function ( width, height, updateStyle ) { - if ( vr.isPresenting() ) { + if ( xr.isPresenting ) { console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' ); return; @@ -23279,6 +23741,18 @@ }; + this.setOpaqueSort = function ( method ) { + + _opaqueSort = method; + + }; + + this.setTransparentSort = function ( method ) { + + _transparentSort = method; + + }; + // Clearing this.getClearColor = function () { @@ -23309,9 +23783,9 @@ var bits = 0; - if ( color === undefined || color ) bits |= 16384; - if ( depth === undefined || depth ) bits |= 256; - if ( stencil === undefined || stencil ) bits |= 1024; + if ( color === undefined || color ) { bits |= 16384; } + if ( depth === undefined || depth ) { bits |= 256; } + if ( stencil === undefined || stencil ) { bits |= 1024; } _gl.clear( bits ); @@ -23347,10 +23821,12 @@ properties.dispose(); objects.dispose(); - vr.dispose(); + xr.dispose(); animation.stop(); + this.forceContextLoss(); + }; // Events @@ -23428,10 +23904,10 @@ var buffers = properties.get( object ); - if ( object.hasPositions && ! buffers.position ) buffers.position = _gl.createBuffer(); - if ( object.hasNormals && ! buffers.normal ) buffers.normal = _gl.createBuffer(); - if ( object.hasUvs && ! buffers.uv ) buffers.uv = _gl.createBuffer(); - if ( object.hasColors && ! buffers.color ) buffers.color = _gl.createBuffer(); + if ( object.hasPositions && ! buffers.position ) { buffers.position = _gl.createBuffer(); } + if ( object.hasNormals && ! buffers.normal ) { buffers.normal = _gl.createBuffer(); } + if ( object.hasUvs && ! buffers.uv ) { buffers.uv = _gl.createBuffer(); } + if ( object.hasColors && ! buffers.color ) { buffers.color = _gl.createBuffer(); } var programAttributes = program.getAttributes(); @@ -23483,13 +23959,17 @@ }; - this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { + var tempScene = new Scene(); + + this.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) { + + if ( scene === null ) { scene = tempScene; } // renderBufferDirect second parameter used to be fog (could be null) var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 ); - state.setMaterial( material, frontFaceCW ); + var program = setProgram( camera, scene, material, object ); - var program = setProgram( camera, fog, material, object ); + state.setMaterial( material, frontFaceCW ); var updateBuffers = false; @@ -23504,7 +23984,7 @@ } - if ( object.morphTargetInfluences ) { + if ( material.morphTargets || material.morphNormals ) { morphtargets.update( object, geometry, material, program ); @@ -23516,6 +23996,21 @@ var index = geometry.index; var position = geometry.attributes.position; + + // + + if ( index === null ) { + + if ( position === undefined || position.count === 0 ) { return; } + + } else if ( index.count === 0 ) { + + return; + + } + + // + var rangeFactor = 1; if ( material.wireframe === true ) { @@ -23539,7 +24034,7 @@ if ( updateBuffers ) { - setupVertexAttributes( material, program, geometry ); + setupVertexAttributes( object, geometry, material, program ); if ( index !== null ) { @@ -23551,17 +24046,7 @@ // - var dataCount = Infinity; - - if ( index !== null ) { - - dataCount = index.count; - - } else if ( position !== undefined ) { - - dataCount = position.count; - - } + var dataCount = ( index !== null ) ? index.count : position.count; var rangeStart = geometry.drawRange.start * rangeFactor; var rangeCount = geometry.drawRange.count * rangeFactor; @@ -23574,7 +24059,7 @@ var drawCount = Math.max( 0, drawEnd - drawStart + 1 ); - if ( drawCount === 0 ) return; + if ( drawCount === 0 ) { return; } // @@ -23587,30 +24072,15 @@ } else { - switch ( object.drawMode ) { - - case TrianglesDrawMode: - renderer.setMode( 4 ); - break; - - case TriangleStripDrawMode: - renderer.setMode( 5 ); - break; - - case TriangleFanDrawMode: - renderer.setMode( 6 ); - break; - - } + renderer.setMode( 4 ); } - } else if ( object.isLine ) { var lineWidth = material.linewidth; - if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material + if ( lineWidth === undefined ) { lineWidth = 1; } // Not using Line*Material state.setLineWidth( lineWidth * getTargetPixelRatio() ); @@ -23638,13 +24108,13 @@ } - if ( geometry && geometry.isInstancedBufferGeometry ) { + if ( object.isInstancedMesh ) { - if ( geometry.maxInstancedCount > 0 ) { + renderer.renderInstances( geometry, drawStart, drawCount, object.count ); - renderer.renderInstances( geometry, drawStart, drawCount ); + } else if ( geometry.isInstancedBufferGeometry ) { - } + renderer.renderInstances( geometry, drawStart, drawCount, geometry.maxInstancedCount ); } else { @@ -23654,16 +24124,11 @@ }; - function setupVertexAttributes( material, program, geometry ) { - - if ( geometry && geometry.isInstancedBufferGeometry && ! capabilities.isWebGL2 ) { + function setupVertexAttributes( object, geometry, material, program ) { - if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { + if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) { - console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); - return; - - } + if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { return; } } @@ -23692,7 +24157,7 @@ // TODO Attribute may not be available on context restore - if ( attribute === undefined ) continue; + if ( attribute === undefined ) { continue; } var buffer = attribute.buffer; var type = attribute.type; @@ -23746,6 +24211,29 @@ } + } else if ( name === 'instanceMatrix' ) { + + var attribute = attributes.get( object.instanceMatrix ); + + // TODO Attribute may not be available on context restore + + if ( attribute === undefined ) { continue; } + + var buffer = attribute.buffer; + var type = attribute.type; + + state.enableAttributeAndDivisor( programAttribute + 0, 1 ); + state.enableAttributeAndDivisor( programAttribute + 1, 1 ); + state.enableAttributeAndDivisor( programAttribute + 2, 1 ); + state.enableAttributeAndDivisor( programAttribute + 3, 1 ); + + _gl.bindBuffer( 34962, buffer ); + + _gl.vertexAttribPointer( programAttribute + 0, 4, type, false, 64, 0 ); + _gl.vertexAttribPointer( programAttribute + 1, 4, type, false, 64, 16 ); + _gl.vertexAttribPointer( programAttribute + 2, 4, type, false, 64, 32 ); + _gl.vertexAttribPointer( programAttribute + 3, 4, type, false, 64, 48 ); + } else if ( materialDefaultAttributeValues !== undefined ) { var value = materialDefaultAttributeValues[ name ]; @@ -23808,6 +24296,8 @@ currentRenderState.setupLights( camera ); + var compiled = {}; + scene.traverse( function ( object ) { if ( object.material ) { @@ -23816,13 +24306,19 @@ for ( var i = 0; i < object.material.length; i ++ ) { - initMaterial( object.material[ i ], scene.fog, object ); + if ( object.material[ i ].uuid in compiled === false ) { + + initMaterial( object.material[ i ], scene, object ); + compiled[ object.material[ i ].uuid ] = true; + + } } - } else { + } else if ( object.material.uuid in compiled === false ) { - initMaterial( object.material, scene.fog, object ); + initMaterial( object.material, scene, object ); + compiled[ object.material.uuid ] = true; } @@ -23838,20 +24334,20 @@ function onAnimationFrame( time ) { - if ( vr.isPresenting() ) return; - if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); + if ( xr.isPresenting ) { return; } + if ( onAnimationFrameCallback ) { onAnimationFrameCallback( time ); } } var animation = new WebGLAnimation(); animation.setAnimationLoop( onAnimationFrame ); - if ( typeof window !== 'undefined' ) animation.setContext( window ); + if ( typeof window !== 'undefined' ) { animation.setContext( window ); } this.setAnimationLoop = function ( callback ) { onAnimationFrameCallback = callback; - vr.setAnimationLoop( callback ); + xr.setAnimationLoop( callback ); animation.start(); @@ -23884,7 +24380,7 @@ } - if ( _isContextLost ) return; + if ( _isContextLost ) { return; } // reset caching for this frame @@ -23896,15 +24392,15 @@ // update scene graph - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); + if ( scene.autoUpdate === true ) { scene.updateMatrixWorld(); } // update camera matrices and frustum - if ( camera.parent === null ) camera.updateMatrixWorld(); + if ( camera.parent === null ) { camera.updateMatrixWorld(); } - if ( vr.enabled ) { + if ( xr.enabled && xr.isPresenting ) { - camera = vr.getCamera( camera ); + camera = xr.getCamera( camera ); } @@ -23916,7 +24412,7 @@ scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget ); _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); + _frustum.setFromProjectionMatrix( _projScreenMatrix ); _localClippingEnabled = this.localClippingEnabled; _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); @@ -23926,15 +24422,17 @@ projectObject( scene, camera, 0, _this.sortObjects ); + currentRenderList.finish(); + if ( _this.sortObjects === true ) { - currentRenderList.sort(); + currentRenderList.sort( _opaqueSort, _transparentSort ); } // - if ( _clippingEnabled ) _clipping.beginShadows(); + if ( _clippingEnabled ) { _clipping.beginShadows(); } var shadowsArray = currentRenderState.state.shadowsArray; @@ -23942,11 +24440,11 @@ currentRenderState.setupLights( camera ); - if ( _clippingEnabled ) _clipping.endShadows(); + if ( _clippingEnabled ) { _clipping.endShadows(); } // - if ( this.info.autoReset ) this.info.reset(); + if ( this.info.autoReset ) { this.info.reset(); } if ( renderTarget !== undefined ) { @@ -23967,18 +24465,18 @@ var overrideMaterial = scene.overrideMaterial; - if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera, overrideMaterial ); - if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera, overrideMaterial ); + if ( opaqueObjects.length ) { renderObjects( opaqueObjects, scene, camera, overrideMaterial ); } + if ( transparentObjects.length ) { renderObjects( transparentObjects, scene, camera, overrideMaterial ); } } else { // opaque pass (front-to-back order) - if ( opaqueObjects.length ) renderObjects( opaqueObjects, scene, camera ); + if ( opaqueObjects.length ) { renderObjects( opaqueObjects, scene, camera ); } // transparent pass (back-to-front order) - if ( transparentObjects.length ) renderObjects( transparentObjects, scene, camera ); + if ( transparentObjects.length ) { renderObjects( transparentObjects, scene, camera ); } } @@ -24008,12 +24506,6 @@ state.setPolygonOffset( false ); - if ( vr.enabled ) { - - vr.submitFrame(); - - } - // _gl.finish(); currentRenderList = null; @@ -24023,7 +24515,7 @@ function projectObject( object, camera, groupOrder, sortObjects ) { - if ( object.visible === false ) return; + if ( object.visible === false ) { return; } var visible = object.layers.test( camera.layers ); @@ -24035,7 +24527,7 @@ } else if ( object.isLOD ) { - if ( object.autoUpdate === true ) object.update( camera ); + if ( object.autoUpdate === true ) { object.update( camera ); } } else if ( object.isLight ) { @@ -24084,7 +24576,14 @@ if ( object.isSkinnedMesh ) { - object.skeleton.update(); + // update skeleton only once in a frame + + if ( object.skeleton.frame !== info.render.frame ) { + + object.skeleton.update(); + object.skeleton.frame = info.render.frame; + + } } @@ -24194,9 +24693,9 @@ if ( object.isImmediateRenderObject ) { - state.setMaterial( material ); + var program = setProgram( camera, scene, material, object ); - var program = setProgram( camera, scene.fog, material, object ); + state.setMaterial( material ); _currentGeometryProgram.geometry = null; _currentGeometryProgram.program = null; @@ -24206,7 +24705,7 @@ } else { - _this.renderBufferDirect( camera, scene.fog, geometry, material, object, group ); + _this.renderBufferDirect( camera, scene, geometry, material, object, group ); } @@ -24215,7 +24714,7 @@ } - function initMaterial( material, fog, object ) { + function initMaterial( material, scene, object ) { var materialProperties = properties.get( material ); @@ -24224,10 +24723,8 @@ var lightsStateVersion = lights.state.version; - var parameters = programCache.getParameters( - material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object ); - - var code = programCache.getProgramCode( material, parameters ); + var parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, _clipping.numPlanes, _clipping.numIntersection, object ); + var programCacheKey = programCache.getProgramCacheKey( parameters ); var program = materialProperties.program; var programChange = true; @@ -24237,7 +24734,7 @@ // new material material.addEventListener( 'dispose', onMaterialDispose ); - } else if ( program.code !== code ) { + } else if ( program.cacheKey !== programCacheKey ) { // changed glsl or parameters releaseMaterialProgramReference( material ); @@ -24262,36 +24759,12 @@ if ( programChange ) { - if ( parameters.shaderID ) { - - var shader = ShaderLib[ parameters.shaderID ]; - - materialProperties.shader = { - name: material.type, - uniforms: cloneUniforms( shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader - }; - - } else { - - materialProperties.shader = { - name: material.type, - uniforms: material.uniforms, - vertexShader: material.vertexShader, - fragmentShader: material.fragmentShader - }; - - } - - material.onBeforeCompile( materialProperties.shader, _this ); - - // Computing code again as onBeforeCompile may have changed the shaders - code = programCache.getProgramCode( material, parameters ); - - program = programCache.acquireProgram( material, materialProperties.shader, parameters, code ); + program = programCache.acquireProgram( parameters, programCacheKey ); materialProperties.program = program; + materialProperties.uniforms = parameters.uniforms; + materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; + materialProperties.outputEncoding = _this.outputEncoding; material.program = program; } @@ -24330,7 +24803,7 @@ } - var uniforms = materialProperties.shader.uniforms; + var uniforms = materialProperties.uniforms; if ( ! material.isShaderMaterial && ! material.isRawShaderMaterial || @@ -24342,22 +24815,26 @@ } - materialProperties.fog = fog; + materialProperties.fog = scene.fog; // store the light setup it was created for + materialProperties.needsLights = materialNeedsLights( material ); materialProperties.lightsStateVersion = lightsStateVersion; - if ( material.lights ) { + if ( materialProperties.needsLights ) { // wire up the material to this renderer's lighting state uniforms.ambientLightColor.value = lights.state.ambient; uniforms.lightProbe.value = lights.state.probe; uniforms.directionalLights.value = lights.state.directional; + uniforms.directionalLightShadows.value = lights.state.directionalShadow; uniforms.spotLights.value = lights.state.spot; + uniforms.spotLightShadows.value = lights.state.spotShadow; uniforms.rectAreaLights.value = lights.state.rectArea; uniforms.pointLights.value = lights.state.point; + uniforms.pointLightShadows.value = lights.state.pointShadow; uniforms.hemisphereLights.value = lights.state.hemi; uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; @@ -24378,10 +24855,13 @@ } - function setProgram( camera, fog, material, object ) { + function setProgram( camera, scene, material, object ) { textures.resetTextureUnits(); + var fog = scene.fog; + var environment = material.isMeshStandardMaterial ? scene.environment : null; + var materialProperties = properties.get( material ); var lights = currentRenderState.state.lights; @@ -24404,34 +24884,40 @@ } - if ( material.needsUpdate === false ) { + if ( material.version === materialProperties.__version ) { if ( materialProperties.program === undefined ) { - material.needsUpdate = true; + initMaterial( material, scene, object ); } else if ( material.fog && materialProperties.fog !== fog ) { - material.needsUpdate = true; + initMaterial( material, scene, object ); + + } else if ( materialProperties.environment !== environment ) { - } else if ( material.lights && materialProperties.lightsStateVersion !== lights.state.version ) { + initMaterial( material, scene, object ); - material.needsUpdate = true; + } else if ( materialProperties.needsLights && ( materialProperties.lightsStateVersion !== lights.state.version ) ) { + + initMaterial( material, scene, object ); } else if ( materialProperties.numClippingPlanes !== undefined && ( materialProperties.numClippingPlanes !== _clipping.numPlanes || materialProperties.numIntersection !== _clipping.numIntersection ) ) { - material.needsUpdate = true; + initMaterial( material, scene, object ); - } + } else if ( materialProperties.outputEncoding !== _this.outputEncoding ) { - } + initMaterial( material, scene, object ); + + } - if ( material.needsUpdate ) { + } else { - initMaterial( material, fog, object ); - material.needsUpdate = false; + initMaterial( material, scene, object ); + materialProperties.__version = material.version; } @@ -24441,7 +24927,7 @@ var program = materialProperties.program, p_uniforms = program.getUniforms(), - m_uniforms = materialProperties.shader.uniforms; + m_uniforms = materialProperties.uniforms; if ( state.useProgram( program.program ) ) { @@ -24488,6 +24974,7 @@ if ( material.isShaderMaterial || material.isMeshPhongMaterial || + material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap ) { @@ -24503,6 +24990,18 @@ } if ( material.isMeshPhongMaterial || + material.isMeshToonMaterial || + material.isMeshLambertMaterial || + material.isMeshBasicMaterial || + material.isMeshStandardMaterial || + material.isShaderMaterial ) { + + p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true ); + + } + + if ( material.isMeshPhongMaterial || + material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || @@ -24517,7 +25016,7 @@ // skinning uniforms must be set even if material didn't change // auto-setting of texture unit for bone texture must go before other textures - // not sure why, but otherwise weird things happen + // otherwise textures used for skinning can take over texture units reserved for other material textures if ( material.skinning ) { @@ -24543,14 +25042,13 @@ var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix - size = _Math.ceilPowerOfTwo( size ); + size = MathUtils.ceilPowerOfTwo( size ); size = Math.max( size, 4 ); var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel boneMatrices.set( skeleton.boneMatrices ); // copy current values var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType ); - boneTexture.needsUpdate = true; skeleton.boneMatrices = boneMatrices; skeleton.boneTexture = boneTexture; @@ -24571,12 +25069,19 @@ } + if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) { + + materialProperties.receiveShadow = object.receiveShadow; + p_uniforms.setValue( _gl, 'receiveShadow', object.receiveShadow ); + + } + if ( refreshMaterial ) { p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint ); - if ( material.lights ) { + if ( materialProperties.needsLights ) { // the current material requires lighting info @@ -24608,38 +25113,33 @@ refreshUniformsCommon( m_uniforms, material ); refreshUniformsLambert( m_uniforms, material ); - } else if ( material.isMeshPhongMaterial ) { + } else if ( material.isMeshToonMaterial ) { refreshUniformsCommon( m_uniforms, material ); + refreshUniformsToon( m_uniforms, material ); - if ( material.isMeshToonMaterial ) { - - refreshUniformsToon( m_uniforms, material ); - - } else { - - refreshUniformsPhong( m_uniforms, material ); + } else if ( material.isMeshPhongMaterial ) { - } + refreshUniformsCommon( m_uniforms, material ); + refreshUniformsPhong( m_uniforms, material ); } else if ( material.isMeshStandardMaterial ) { - refreshUniformsCommon( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material, environment ); if ( material.isMeshPhysicalMaterial ) { - refreshUniformsPhysical( m_uniforms, material ); + refreshUniformsPhysical( m_uniforms, material, environment ); } else { - refreshUniformsStandard( m_uniforms, material ); + refreshUniformsStandard( m_uniforms, material, environment ); } } else if ( material.isMeshMatcapMaterial ) { refreshUniformsCommon( m_uniforms, material ); - refreshUniformsMatcap( m_uniforms, material ); } else if ( material.isMeshDepthMaterial ) { @@ -24685,11 +25185,17 @@ // RectAreaLight Texture // TODO (mrdoob): Find a nicer implementation - if ( m_uniforms.ltc_1 !== undefined ) m_uniforms.ltc_1.value = UniformsLib.LTC_1; - if ( m_uniforms.ltc_2 !== undefined ) m_uniforms.ltc_2.value = UniformsLib.LTC_2; + if ( m_uniforms.ltc_1 !== undefined ) { m_uniforms.ltc_1.value = UniformsLib.LTC_1; } + if ( m_uniforms.ltc_2 !== undefined ) { m_uniforms.ltc_2.value = UniformsLib.LTC_2; } WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures ); + if ( material.isShaderMaterial ) { + + material.uniformsNeedUpdate = false; // #15581 + + } + } if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) { @@ -24717,7 +25223,7 @@ // Uniforms (refresh uniforms objects) - function refreshUniformsCommon( uniforms, material ) { + function refreshUniformsCommon( uniforms, material, environment ) { uniforms.opacity.value = material.opacity; @@ -24751,20 +25257,18 @@ } - if ( material.envMap ) { + var envMap = material.envMap || environment; + + if ( envMap ) { - uniforms.envMap.value = material.envMap; + uniforms.envMap.value = envMap; - // don't flip CubeTexture envMaps, flip everything else: - // WebGLRenderTargetCube will be flipped for backwards compatibility - // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture - // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future - uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1; + uniforms.flipEnvMap.value = envMap.isCubeTexture ? - 1 : 1; uniforms.reflectivity.value = material.reflectivity; uniforms.refractionRatio.value = material.refractionRatio; - uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel; + uniforms.maxMipLevel.value = properties.get( envMap ).__maxMipLevel; } @@ -24849,6 +25353,41 @@ } + // uv repeat and offset setting priorities for uv2 + // 1. ao map + // 2. light map + + var uv2ScaleMap; + + if ( material.aoMap ) { + + uv2ScaleMap = material.aoMap; + + } else if ( material.lightMap ) { + + uv2ScaleMap = material.lightMap; + + } + + if ( uv2ScaleMap !== undefined ) { + + // backwards compatibility + if ( uv2ScaleMap.isWebGLRenderTarget ) { + + uv2ScaleMap = uv2ScaleMap.texture; + + } + + if ( uv2ScaleMap.matrixAutoUpdate === true ) { + + uv2ScaleMap.updateMatrix(); + + } + + uniforms.uv2Transform.value.copy( uv2ScaleMap.matrix ); + + } + } function refreshUniformsLine( uniforms, material ) { @@ -24873,17 +25412,43 @@ uniforms.size.value = material.size * _pixelRatio; uniforms.scale.value = _height * 0.5; - uniforms.map.value = material.map; + if ( material.map ) { + + uniforms.map.value = material.map; - if ( material.map !== null ) { + } - if ( material.map.matrixAutoUpdate === true ) { + if ( material.alphaMap ) { + + uniforms.alphaMap.value = material.alphaMap; - material.map.updateMatrix(); + } + + // uv repeat and offset setting priorities + // 1. color map + // 2. alpha map + + var uvScaleMap; + + if ( material.map ) { + + uvScaleMap = material.map; + + } else if ( material.alphaMap ) { + + uvScaleMap = material.alphaMap; + + } + + if ( uvScaleMap !== undefined ) { + + if ( uvScaleMap.matrixAutoUpdate === true ) { + + uvScaleMap.updateMatrix(); } - uniforms.uvTransform.value.copy( material.map.matrix ); + uniforms.uvTransform.value.copy( uvScaleMap.matrix ); } @@ -24894,17 +25459,44 @@ uniforms.diffuse.value.copy( material.color ); uniforms.opacity.value = material.opacity; uniforms.rotation.value = material.rotation; - uniforms.map.value = material.map; - if ( material.map !== null ) { + if ( material.map ) { + + uniforms.map.value = material.map; + + } + + if ( material.alphaMap ) { - if ( material.map.matrixAutoUpdate === true ) { + uniforms.alphaMap.value = material.alphaMap; + + } - material.map.updateMatrix(); + // uv repeat and offset setting priorities + // 1. color map + // 2. alpha map + + var uvScaleMap; + + if ( material.map ) { + + uvScaleMap = material.map; + + } else if ( material.alphaMap ) { + + uvScaleMap = material.alphaMap; + + } + + if ( uvScaleMap !== undefined ) { + + if ( uvScaleMap.matrixAutoUpdate === true ) { + + uvScaleMap.updateMatrix(); } - uniforms.uvTransform.value.copy( material.map.matrix ); + uniforms.uvTransform.value.copy( uvScaleMap.matrix ); } @@ -24952,7 +25544,7 @@ uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; - if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; } } @@ -24960,7 +25552,7 @@ uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy( material.normalScale ); - if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); } } @@ -24976,7 +25568,8 @@ function refreshUniformsToon( uniforms, material ) { - refreshUniformsPhong( uniforms, material ); + uniforms.specular.value.copy( material.specular ); + uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 ) if ( material.gradientMap ) { @@ -24984,9 +25577,39 @@ } + if ( material.emissiveMap ) { + + uniforms.emissiveMap.value = material.emissiveMap; + + } + + if ( material.bumpMap ) { + + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; } + + } + + if ( material.normalMap ) { + + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy( material.normalScale ); + if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); } + + } + + if ( material.displacementMap ) { + + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + + } + } - function refreshUniformsStandard( uniforms, material ) { + function refreshUniformsStandard( uniforms, material, environment ) { uniforms.roughness.value = material.roughness; uniforms.metalness.value = material.metalness; @@ -25013,7 +25636,7 @@ uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; - if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; } } @@ -25021,7 +25644,7 @@ uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy( material.normalScale ); - if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); } } @@ -25033,7 +25656,7 @@ } - if ( material.envMap ) { + if ( material.envMap || environment ) { //uniforms.envMap.value = material.envMap; // part of uniforms common uniforms.envMapIntensity.value = material.envMapIntensity; @@ -25042,28 +25665,43 @@ } - function refreshUniformsPhysical( uniforms, material ) { + function refreshUniformsPhysical( uniforms, material, environment ) { - refreshUniformsStandard( uniforms, material ); + refreshUniformsStandard( uniforms, material, environment ); uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common - uniforms.clearCoat.value = material.clearCoat; - uniforms.clearCoatRoughness.value = material.clearCoatRoughness; + uniforms.clearcoat.value = material.clearcoat; + uniforms.clearcoatRoughness.value = material.clearcoatRoughness; + if ( material.sheen ) { uniforms.sheen.value.copy( material.sheen ); } + + if ( material.clearcoatMap ) { + + uniforms.clearcoatMap.value = material.clearcoatMap; - if ( material.clearCoatNormalMap ) { + } + + if ( material.clearcoatRoughnessMap ) { + + uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; + + } + + if ( material.clearcoatNormalMap ) { - uniforms.clearCoatNormalScale.value.copy( material.clearCoatNormalScale ); - uniforms.clearCoatNormalMap.value = material.clearCoatNormalMap; + uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale ); + uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; if ( material.side === BackSide ) { - uniforms.clearCoatNormalScale.value.negate(); + uniforms.clearcoatNormalScale.value.negate(); } } + uniforms.transparency.value = material.transparency; + } function refreshUniformsMatcap( uniforms, material ) { @@ -25078,7 +25716,7 @@ uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; - if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; } } @@ -25086,7 +25724,7 @@ uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy( material.normalScale ); - if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); } } @@ -25134,7 +25772,7 @@ uniforms.bumpMap.value = material.bumpMap; uniforms.bumpScale.value = material.bumpScale; - if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; } } @@ -25142,7 +25780,7 @@ uniforms.normalMap.value = material.normalMap; uniforms.normalScale.value.copy( material.normalScale ); - if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); } } @@ -25164,17 +25802,28 @@ uniforms.lightProbe.needsUpdate = value; uniforms.directionalLights.needsUpdate = value; + uniforms.directionalLightShadows.needsUpdate = value; uniforms.pointLights.needsUpdate = value; + uniforms.pointLightShadows.needsUpdate = value; uniforms.spotLights.needsUpdate = value; + uniforms.spotLightShadows.needsUpdate = value; uniforms.rectAreaLights.needsUpdate = value; uniforms.hemisphereLights.needsUpdate = value; } + function materialNeedsLights( material ) { + + return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || + material.isMeshStandardMaterial || material.isShadowMaterial || + ( material.isShaderMaterial && material.lights === true ); + + } + // this.setFramebuffer = function ( value ) { - if ( _framebuffer !== value ) _gl.bindFramebuffer( 36160, value ); + if ( _framebuffer !== value && _currentRenderTarget === null ) { _gl.bindFramebuffer( 36160, value ); } _framebuffer = value; @@ -25217,7 +25866,7 @@ var __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; - if ( renderTarget.isWebGLRenderTargetCube ) { + if ( renderTarget.isWebGLCubeRenderTarget ) { framebuffer = __webglFramebuffer[ activeCubeFace || 0 ]; isCube = true; @@ -25275,7 +25924,7 @@ var framebuffer = properties.get( renderTarget ).__webglFramebuffer; - if ( renderTarget.isWebGLRenderTargetCube && activeCubeFaceIndex !== undefined ) { + if ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) { framebuffer = framebuffer[ activeCubeFaceIndex ]; @@ -25347,13 +25996,18 @@ this.copyFramebufferToTexture = function ( position, texture, level ) { - var width = texture.image.width; - var height = texture.image.height; + if ( level === undefined ) { level = 0; } + + var levelScale = Math.pow( 2, - level ); + var width = Math.floor( texture.image.width * levelScale ); + var height = Math.floor( texture.image.height * levelScale ); var glFormat = utils.convert( texture.format ); textures.setTexture2D( texture, 0 ); - _gl.copyTexImage2D( 3553, level || 0, glFormat, position.x, position.y, width, height, 0 ); + _gl.copyTexImage2D( 3553, level, glFormat, position.x, position.y, width, height, 0 ); + + state.unbindTexture(); }; @@ -25376,6 +26030,16 @@ } + state.unbindTexture(); + + }; + + this.initTexture = function ( texture ) { + + textures.setTexture2D( texture, 0 ); + + state.unbindTexture(); + }; if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { @@ -25471,7 +26135,7 @@ this.stride = stride; this.count = array !== undefined ? array.length / stride : 0; - this.dynamic = false; + this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: - 1 }; this.version = 0; @@ -25482,7 +26146,7 @@ set: function ( value ) { - if ( value === true ) this.version ++; + if ( value === true ) { this.version ++; } } @@ -25494,24 +26158,9 @@ onUploadCallback: function () {}, - setArray: function ( array ) { - - if ( Array.isArray( array ) ) { + setUsage: function ( value ) { - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - - } - - this.count = array !== undefined ? array.length / this.stride : 0; - this.array = array; - - return this; - - }, - - setDynamic: function ( value ) { - - this.dynamic = value; + this.usage = value; return this; @@ -25522,7 +26171,7 @@ this.array = new source.array.constructor( source.array ); this.count = source.count; this.stride = source.stride; - this.dynamic = source.dynamic; + this.usage = source.usage; return this; @@ -25545,7 +26194,7 @@ set: function ( value, offset ) { - if ( offset === undefined ) offset = 0; + if ( offset === undefined ) { offset = 0; } this.array.set( value, offset ); @@ -25573,6 +26222,8 @@ * @author benaadams / https://twitter.com/ben_a_adams */ + var _vector$6 = new Vector3(); + function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) { this.data = interleavedBuffer; @@ -25611,6 +26262,24 @@ isInterleavedBufferAttribute: true, + applyMatrix4: function ( m ) { + + for ( var i = 0, l = this.data.count; i < l; i ++ ) { + + _vector$6.x = this.getX( i ); + _vector$6.y = this.getY( i ); + _vector$6.z = this.getZ( i ); + + _vector$6.applyMatrix4( m ); + + this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z ); + + } + + return this; + + }, + setX: function ( index, x ) { this.data.array[ index * this.data.stride + this.offset ] = x; @@ -25711,6 +26380,7 @@ * parameters = { * color: , * map: new THREE.Texture( ), + * alphaMap: new THREE.Texture( ), * rotation: , * sizeAttenuation: * } @@ -25723,13 +26393,15 @@ this.type = 'SpriteMaterial'; this.color = new Color( 0xffffff ); + this.map = null; + this.alphaMap = null; + this.rotation = 0; this.sizeAttenuation = true; - this.lights = false; this.transparent = true; this.setValues( parameters ); @@ -25745,8 +26417,11 @@ Material.prototype.copy.call( this, source ); this.color.copy( source.color ); + this.map = source.map; + this.alphaMap = source.alphaMap; + this.rotation = source.rotation; this.sizeAttenuation = source.sizeAttenuation; @@ -25798,8 +26473,8 @@ var interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); - _geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); - _geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); + _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); } @@ -25876,7 +26551,7 @@ var distance = raycaster.ray.origin.distanceTo( _intersectPoint ); - if ( distance < raycaster.near || distance > raycaster.far ) return; + if ( distance < raycaster.near || distance > raycaster.far ) { return; } intersects.push( { @@ -25900,7 +26575,7 @@ Object3D.prototype.copy.call( this, source ); - if ( source.center !== undefined ) this.center.copy( source.center ); + if ( source.center !== undefined ) { this.center.copy( source.center ); } return this; @@ -25949,6 +26624,8 @@ Object3D.call( this ); + this._currentLevel = 0; + this.type = 'LOD'; Object.defineProperties( this, { @@ -25982,13 +26659,15 @@ } + this.autoUpdate = source.autoUpdate; + return this; }, addLevel: function ( object, distance ) { - if ( distance === undefined ) distance = 0; + if ( distance === undefined ) { distance = 0; } distance = Math.abs( distance ); @@ -26012,31 +26691,49 @@ }, + getCurrentLevel: function () { + + return this._currentLevel; + + }, + getObjectForDistance: function ( distance ) { var levels = this.levels; - for ( var i = 1, l = levels.length; i < l; i ++ ) { + if ( levels.length > 0 ) { - if ( distance < levels[ i ].distance ) { + for ( var i = 1, l = levels.length; i < l; i ++ ) { - break; + if ( distance < levels[ i ].distance ) { + + break; + + } } + return levels[ i - 1 ].object; + } - return levels[ i - 1 ].object; + return null; }, raycast: function ( raycaster, intersects ) { - _v1$4.setFromMatrixPosition( this.matrixWorld ); + var levels = this.levels; + + if ( levels.length > 0 ) { + + _v1$4.setFromMatrixPosition( this.matrixWorld ); + + var distance = raycaster.ray.origin.distanceTo( _v1$4 ); - var distance = raycaster.ray.origin.distanceTo( _v1$4 ); + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); - this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + } }, @@ -26049,7 +26746,7 @@ _v1$4.setFromMatrixPosition( camera.matrixWorld ); _v2$2.setFromMatrixPosition( this.matrixWorld ); - var distance = _v1$4.distanceTo( _v2$2 ); + var distance = _v1$4.distanceTo( _v2$2 ) / camera.zoom; levels[ 0 ].object.visible = true; @@ -26068,6 +26765,8 @@ } + this._currentLevel = i - 1; + for ( ; i < l; i ++ ) { levels[ i ].object.visible = false; @@ -26082,6 +26781,8 @@ var data = Object3D.prototype.toJSON.call( this, meta ); + if ( this.autoUpdate === false ) { data.object.autoUpdate = false; } + data.object.levels = []; var levels = this.levels; @@ -26236,6 +26937,8 @@ this.bones = bones.slice( 0 ); this.boneMatrices = new Float32Array( this.bones.length * 16 ); + this.frame = - 1; + // use the supplied bone inverses or calculate the inverses if ( boneInverses === undefined ) { @@ -26409,6 +27112,94 @@ } ); + /** + * @author mrdoob / http://mrdoob.com/ + */ + + var _instanceLocalMatrix = new Matrix4(); + var _instanceWorldMatrix = new Matrix4(); + + var _instanceIntersects = []; + + var _mesh = new Mesh(); + + function InstancedMesh( geometry, material, count ) { + + Mesh.call( this, geometry, material ); + + this.instanceMatrix = new BufferAttribute( new Float32Array( count * 16 ), 16 ); + + this.count = count; + + this.frustumCulled = false; + + } + + InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { + + constructor: InstancedMesh, + + isInstancedMesh: true, + + getMatrixAt: function ( index, matrix ) { + + matrix.fromArray( this.instanceMatrix.array, index * 16 ); + + }, + + raycast: function ( raycaster, intersects ) { + + var matrixWorld = this.matrixWorld; + var raycastTimes = this.count; + + _mesh.geometry = this.geometry; + _mesh.material = this.material; + + if ( _mesh.material === undefined ) { return; } + + for ( var instanceId = 0; instanceId < raycastTimes; instanceId ++ ) { + + // calculate the world matrix for each instance + + this.getMatrixAt( instanceId, _instanceLocalMatrix ); + + _instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix ); + + // the mesh represents this single instance + + _mesh.matrixWorld = _instanceWorldMatrix; + + _mesh.raycast( raycaster, _instanceIntersects ); + + // process the result of raycast + + if ( _instanceIntersects.length > 0 ) { + + _instanceIntersects[ 0 ].instanceId = instanceId; + _instanceIntersects[ 0 ].object = this; + + intersects.push( _instanceIntersects[ 0 ] ); + + _instanceIntersects.length = 0; + + } + + } + + }, + + setMatrixAt: function ( index, matrix ) { + + matrix.toArray( this.instanceMatrix.array, index * 16 ); + + }, + + updateMorphTargets: function () { + + } + + } ); + /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ @@ -26435,8 +27226,6 @@ this.linecap = 'round'; this.linejoin = 'round'; - this.lights = false; - this.setValues( parameters ); } @@ -26483,7 +27272,7 @@ this.type = 'Line'; this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } ); + this.material = material !== undefined ? material : new LineBasicMaterial(); } @@ -26516,7 +27305,7 @@ } - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); } else { @@ -26546,28 +27335,27 @@ raycast: function ( raycaster, intersects ) { - var precision = raycaster.linePrecision; - var geometry = this.geometry; var matrixWorld = this.matrixWorld; + var threshold = raycaster.params.Line.threshold; // Checking boundingSphere distance to ray - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); } _sphere$2.copy( geometry.boundingSphere ); _sphere$2.applyMatrix4( matrixWorld ); - _sphere$2.radius += precision; + _sphere$2.radius += threshold; - if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) return; + if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) { return; } // _inverseMatrix$1.getInverse( matrixWorld ); _ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 ); - var localPrecision = precision / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); - var localPrecisionSq = localPrecision * localPrecision; + var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); + var localThresholdSq = localThreshold * localThreshold; var vStart = new Vector3(); var vEnd = new Vector3(); @@ -26595,13 +27383,13 @@ var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - if ( distSq > localPrecisionSq ) continue; + if ( distSq > localThresholdSq ) { continue; } interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation var distance = raycaster.ray.origin.distanceTo( interRay ); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + if ( distance < raycaster.near || distance > raycaster.far ) { continue; } intersects.push( { @@ -26627,13 +27415,13 @@ var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - if ( distSq > localPrecisionSq ) continue; + if ( distSq > localThresholdSq ) { continue; } interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation var distance = raycaster.ray.origin.distanceTo( interRay ); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + if ( distance < raycaster.near || distance > raycaster.far ) { continue; } intersects.push( { @@ -26661,13 +27449,13 @@ var distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); - if ( distSq > localPrecisionSq ) continue; + if ( distSq > localThresholdSq ) { continue; } interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation var distance = raycaster.ray.origin.distanceTo( interRay ); - if ( distance < raycaster.near || distance > raycaster.far ) continue; + if ( distance < raycaster.near || distance > raycaster.far ) { continue; } intersects.push( { @@ -26740,7 +27528,7 @@ } - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); } else { @@ -26799,6 +27587,7 @@ * color: , * opacity: , * map: new THREE.Texture( ), + * alphaMap: new THREE.Texture( ), * * size: , * sizeAttenuation: @@ -26817,13 +27606,13 @@ this.map = null; + this.alphaMap = null; + this.size = 1; this.sizeAttenuation = true; this.morphTargets = false; - this.lights = false; - this.setValues( parameters ); } @@ -26841,6 +27630,8 @@ this.map = source.map; + this.alphaMap = source.alphaMap; + this.size = source.size; this.sizeAttenuation = source.sizeAttenuation; @@ -26866,7 +27657,7 @@ this.type = 'Points'; this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } ); + this.material = material !== undefined ? material : new PointsMaterial(); this.updateMorphTargets(); @@ -26886,13 +27677,13 @@ // Checking boundingSphere distance to ray - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); } _sphere$3.copy( geometry.boundingSphere ); _sphere$3.applyMatrix4( matrixWorld ); _sphere$3.radius += threshold; - if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) return; + if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) { return; } // @@ -27015,7 +27806,7 @@ var distance = raycaster.ray.origin.distanceTo( intersectPoint ); - if ( distance < raycaster.near || distance > raycaster.far ) return; + if ( distance < raycaster.near || distance > raycaster.far ) { return; } intersects.push( { @@ -27128,8 +27919,8 @@ } - if ( type === undefined && format === DepthFormat ) type = UnsignedShortType; - if ( type === undefined && format === DepthStencilFormat ) type = UnsignedInt248Type; + if ( type === undefined && format === DepthFormat ) { type = UnsignedShortType; } + if ( type === undefined && format === DepthStencilFormat ) { type = UnsignedInt248Type; } Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); @@ -27313,7 +28104,7 @@ // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); } @@ -27325,7 +28116,7 @@ * @author Mugen87 / https://github.com/Mugen87 * * Parametric Surfaces Geometry - * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 + * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html */ // ParametricGeometry @@ -27467,9 +28258,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -27543,9 +28334,9 @@ // build non-indexed geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); if ( detail === 0 ) { @@ -27711,9 +28502,9 @@ if ( max > 0.9 && min < 0.1 ) { - if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1; - if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1; - if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1; + if ( x0 < 0.2 ) { uvBuffer[ i + 0 ] += 1; } + if ( x1 < 0.2 ) { uvBuffer[ i + 2 ] += 1; } + if ( x2 < 0.2 ) { uvBuffer[ i + 4 ] += 1; } } @@ -28084,7 +28875,7 @@ closed: closed }; - if ( taper !== undefined ) console.warn( 'THREE.TubeGeometry: taper has been removed.' ); + if ( taper !== undefined ) { console.warn( 'THREE.TubeGeometry: taper has been removed.' ); } var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ); @@ -28156,9 +28947,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // functions @@ -28307,7 +29098,7 @@ q: q }; - if ( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); + if ( heightScale !== undefined ) { console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); } this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) ); this.mergeVertices(); @@ -28446,9 +29237,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // this function calculates the current position on the torus curve @@ -28596,9 +29387,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -28621,11 +29412,11 @@ outerNode = linkedList( data, 0, outerLen, dim, true ), triangles = []; - if ( ! outerNode || outerNode.next === outerNode.prev ) return triangles; + if ( ! outerNode || outerNode.next === outerNode.prev ) { return triangles; } var minX, minY, maxX, maxY, x, y, invSize; - if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); + if ( hasHoles ) { outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); } // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox if ( data.length > 80 * dim ) { @@ -28637,10 +29428,10 @@ x = data[ i ]; y = data[ i + 1 ]; - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; + if ( x < minX ) { minX = x; } + if ( y < minY ) { minY = y; } + if ( x > maxX ) { maxX = x; } + if ( y > maxY ) { maxY = y; } } @@ -28665,11 +29456,11 @@ if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) { - for ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); + for ( i = start; i < end; i += dim ) { last = insertNode( i, data[ i ], data[ i + 1 ], last ); } } else { - for ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last ); + for ( i = end - dim; i >= start; i -= dim ) { last = insertNode( i, data[ i ], data[ i + 1 ], last ); } } @@ -28687,8 +29478,8 @@ // eliminate colinear or duplicate points function filterPoints( start, end ) { - if ( ! start ) return start; - if ( ! end ) end = start; + if ( ! start ) { return start; } + if ( ! end ) { end = start; } var p = start, again; @@ -28700,7 +29491,7 @@ removeNode( p ); p = end = p.prev; - if ( p === p.next ) break; + if ( p === p.next ) { break; } again = true; } else { @@ -28718,10 +29509,10 @@ // main ear slicing loop which triangulates a polygon (given as a linked list) function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { - if ( ! ear ) return; + if ( ! ear ) { return; } // interlink polygon nodes in z-order - if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); + if ( ! pass && invSize ) { indexCurve( ear, minX, minY, invSize ); } var stop = ear, prev, next; @@ -28789,7 +29580,7 @@ b = ear, c = ear.next; - if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + if ( area( a, b, c ) >= 0 ) { return false; } // reflex, can't be an ear // now make sure we don't have other points inside the potential ear var p = ear.next.next; @@ -28797,7 +29588,7 @@ while ( p !== ear.prev ) { if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && - area( p.prev, p, p.next ) >= 0 ) return false; + area( p.prev, p, p.next ) >= 0 ) { return false; } p = p.next; } @@ -28812,7 +29603,7 @@ b = ear, c = ear.next; - if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear + if ( area( a, b, c ) >= 0 ) { return false; } // reflex, can't be an ear // triangle bbox; min & max are calculated like this for speed var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ), @@ -28832,12 +29623,12 @@ if ( p !== ear.prev && p !== ear.next && pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && - area( p.prev, p, p.next ) >= 0 ) return false; + area( p.prev, p, p.next ) >= 0 ) { return false; } p = p.prevZ; if ( n !== ear.prev && n !== ear.next && pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) && - area( n.prev, n, n.next ) >= 0 ) return false; + area( n.prev, n, n.next ) >= 0 ) { return false; } n = n.nextZ; } @@ -28847,7 +29638,7 @@ if ( p !== ear.prev && p !== ear.next && pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && - area( p.prev, p, p.next ) >= 0 ) return false; + area( p.prev, p, p.next ) >= 0 ) { return false; } p = p.prevZ; } @@ -28857,7 +29648,7 @@ if ( n !== ear.prev && n !== ear.next && pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) && - area( n.prev, n, n.next ) >= 0 ) return false; + area( n.prev, n, n.next ) >= 0 ) { return false; } n = n.nextZ; } @@ -28944,7 +29735,7 @@ start = holeIndices[ i ] * dim; end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length; list = linkedList( data, start, end, dim, false ); - if ( list === list.next ) list.steiner = true; + if ( list === list.next ) { list.steiner = true; } queue.push( getLeftmost( list ) ); } @@ -29003,8 +29794,8 @@ qx = x; if ( x === hx ) { - if ( hy === p.y ) return p; - if ( hy === p.next.y ) return p.next; + if ( hy === p.y ) { return p; } + if ( hy === p.next.y ) { return p.next; } } @@ -29018,9 +29809,9 @@ } while ( p !== outerNode ); - if ( ! m ) return null; + if ( ! m ) { return null; } - if ( hx === qx ) return m.prev; // hole touches outer segment; pick lower endpoint + if ( hx === qx ) { return m.prev; } // hole touches outer segment; pick lower endpoint // look for points inside the triangle of hole point, segment intersection and endpoint; // if there are no points found, we have a valid connection; @@ -29064,7 +29855,7 @@ var p = start; do { - if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); + if ( p.z === null ) { p.z = zOrder( p.x, p.y, minX, minY, invSize ); } p.prevZ = p.prev; p.nextZ = p.next; p = p.next; @@ -29101,7 +29892,7 @@ pSize ++; q = q.nextZ; - if ( ! q ) break; + if ( ! q ) { break; } } @@ -29123,8 +29914,8 @@ } - if ( tail ) tail.nextZ = e; - else list = e; + if ( tail ) { tail.nextZ = e; } + else { list = e; } e.prevZ = tail; tail = e; @@ -29172,7 +29963,7 @@ leftmost = start; do { - if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p; + if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) { leftmost = p; } p = p.next; } while ( p !== start ); @@ -29216,7 +30007,7 @@ function intersects( p1, q1, p2, q2 ) { if ( ( equals( p1, p2 ) && equals( q1, q2 ) ) || - ( equals( p1, q2 ) && equals( p2, q1 ) ) ) return true; + ( equals( p1, q2 ) && equals( p2, q1 ) ) ) { return true; } return area( p1, q1, p2 ) > 0 !== area( p1, q1, q2 ) > 0 && area( p2, q2, p1 ) > 0 !== area( p2, q2, q1 ) > 0; @@ -29229,7 +30020,7 @@ do { if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && - intersects( p, p.next, a, b ) ) return true; + intersects( p, p.next, a, b ) ) { return true; } p = p.next; } while ( p !== a ); @@ -29258,7 +30049,7 @@ if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y && ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) - inside = ! inside; + { inside = ! inside; } p = p.next; } while ( p !== a ); @@ -29320,8 +30111,8 @@ p.next.prev = p.prev; p.prev.next = p.next; - if ( p.prevZ ) p.prevZ.nextZ = p.nextZ; - if ( p.nextZ ) p.nextZ.prevZ = p.prevZ; + if ( p.prevZ ) { p.prevZ.nextZ = p.nextZ; } + if ( p.nextZ ) { p.nextZ.prevZ = p.prevZ; } } @@ -29542,8 +30333,8 @@ // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); this.computeVertexNormals(); @@ -29664,7 +30455,7 @@ function scalePt2( pt, vec, size ) { - if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" ); + if ( ! vec ) { console.error( "THREE.ExtrudeGeometry: vec does not exist" ); } return vec.clone().multiplyScalar( size ).add( pt ); @@ -29805,8 +30596,8 @@ for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { - if ( j === il ) j = 0; - if ( k === il ) k = 0; + if ( j === il ) { j = 0; } + if ( k === il ) { k = 0; } // (j)---(i)---(k) // console.log('i,j,k', i, j , k) @@ -29826,8 +30617,8 @@ for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) { - if ( j === il ) j = 0; - if ( k === il ) k = 0; + if ( j === il ) { j = 0; } + if ( k === il ) { k = 0; } // (j)---(i)---(k) oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] ); @@ -30087,7 +30878,7 @@ j = i; k = i - 1; - if ( k < 0 ) k = contour.length - 1; + if ( k < 0 ) { k = contour.length - 1; } //console.log('b', i,j, i-1, k,vertices.length); @@ -30277,7 +31068,7 @@ // - if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON(); + if ( options.extrudePath !== undefined ) { data.options.extrudePath = options.extrudePath.toJSON(); } return data; @@ -30347,9 +31138,9 @@ // defaults - if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10; - if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8; - if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false; + if ( parameters.bevelThickness === undefined ) { parameters.bevelThickness = 10; } + if ( parameters.bevelSize === undefined ) { parameters.bevelSize = 8; } + if ( parameters.bevelEnabled === undefined ) { parameters.bevelEnabled = false; } ExtrudeBufferGeometry.call( this, shapes, parameters ); @@ -30500,8 +31291,8 @@ var c = grid[ iy + 1 ][ ix ]; var d = grid[ iy + 1 ][ ix + 1 ]; - if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d ); - if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d ); + if ( iy !== 0 || thetaStart > 0 ) { indices.push( a, b, d ); } + if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) { indices.push( b, c, d ); } } @@ -30510,9 +31301,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -30654,9 +31445,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -30713,7 +31504,7 @@ // clamp phiLength so it's in range of [ 0, 2PI ] - phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 ); + phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 ); // buffers @@ -30786,8 +31577,8 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // generate normals @@ -30935,9 +31726,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // helper functions @@ -31076,7 +31867,7 @@ // helper variables - var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle ); + var thresholdDot = Math.cos( MathUtils.DEG2RAD * thresholdAngle ); var edge = [ 0, 0 ], edges = {}, edge1, edge2; var key, keys = [ 'a', 'b', 'c' ]; @@ -31152,7 +31943,7 @@ // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); } @@ -31243,17 +32034,17 @@ if ( openEnded === false ) { - if ( radiusTop > 0 ) generateCap( true ); - if ( radiusBottom > 0 ) generateCap( false ); + if ( radiusTop > 0 ) { generateCap( true ); } + if ( radiusBottom > 0 ) { generateCap( false ); } } // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); function generateTorso() { @@ -31621,9 +32412,9 @@ // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -31633,6 +32424,7 @@ var Geometries = /*#__PURE__*/Object.freeze({ + __proto__: null, WireframeGeometry: WireframeGeometry, ParametricGeometry: ParametricGeometry, ParametricBufferGeometry: ParametricBufferGeometry, @@ -31791,8 +32583,8 @@ this.type = 'MeshStandardMaterial'; this.color = new Color( 0xffffff ); // diffuse - this.roughness = 0.5; - this.metalness = 0.5; + this.roughness = 1.0; + this.metalness = 0.0; this.map = null; @@ -31837,6 +32629,8 @@ this.morphTargets = false; this.morphNormals = false; + this.vertexTangents = false; + this.setValues( parameters ); } @@ -31899,6 +32693,8 @@ this.morphTargets = source.morphTargets; this.morphNormals = source.morphNormals; + this.vertexTangents = source.vertexTangents; + return this; }; @@ -31907,12 +32703,18 @@ * @author WestLangley / http://github.com/WestLangley * * parameters = { - * reflectivity: - * clearCoat: - * clearCoatRoughness: + * clearcoat: , + * clearcoatMap: new THREE.Texture( ), + * clearcoatRoughness: , + * clearcoatRoughnessMap: new THREE.Texture( ), + * clearcoatNormalScale: , + * clearcoatNormalMap: new THREE.Texture( ), * - * clearCoatNormalScale: , - * clearCoatNormalMap: new THREE.Texture( ), + * reflectivity: , + * + * sheen: , + * + * transparency: * } */ @@ -31920,17 +32722,27 @@ MeshStandardMaterial.call( this ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; this.type = 'MeshPhysicalMaterial'; + this.clearcoat = 0.0; + this.clearcoatMap = null; + this.clearcoatRoughness = 0.0; + this.clearcoatRoughnessMap = null; + this.clearcoatNormalScale = new Vector2( 1, 1 ); + this.clearcoatNormalMap = null; + this.reflectivity = 0.5; // maps to F0 = 0.04 - this.clearCoat = 0.0; - this.clearCoatRoughness = 0.0; + this.sheen = null; // null will disable sheen bsdf - this.clearCoatNormalScale = new Vector2( 1, 1 ); - this.clearCoatNormalMap = null; + this.transparency = 0.0; this.setValues( parameters ); @@ -31945,15 +32757,33 @@ MeshStandardMaterial.prototype.copy.call( this, source ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; + + this.clearcoat = source.clearcoat; + this.clearcoatMap = source.clearcoatMap; + this.clearcoatRoughness = source.clearcoatRoughness; + this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; + this.clearcoatNormalMap = source.clearcoatNormalMap; + this.clearcoatNormalScale.copy( source.clearcoatNormalScale ); this.reflectivity = source.reflectivity; - this.clearCoat = source.clearCoat; - this.clearCoatRoughness = source.clearCoatRoughness; + if ( source.sheen ) { - this.clearCoatNormalMap = source.clearCoatNormalMap; - this.clearCoatNormalScale.copy( source.clearCoatNormalScale ); + this.sheen = ( this.sheen || new Color() ).copy( source.sheen ); + + } else { + + this.sheen = null; + + } + + this.transparency = source.transparency; return this; @@ -31997,7 +32827,7 @@ * alphaMap: new THREE.Texture( ), * * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, + * combine: THREE.MultiplyOperation, * reflectivity: , * refractionRatio: , * @@ -32127,35 +32957,150 @@ * @author takahirox / http://github.com/takahirox * * parameters = { - * gradientMap: new THREE.Texture( ) + * color: , + * specular: , + * shininess: , + * + * map: new THREE.Texture( ), + * gradientMap: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: * } */ function MeshToonMaterial( parameters ) { - MeshPhongMaterial.call( this ); + Material.call( this ); this.defines = { 'TOON': '' }; this.type = 'MeshToonMaterial'; + this.color = new Color( 0xffffff ); + this.specular = new Color( 0x111111 ); + this.shininess = 30; + + this.map = null; this.gradientMap = null; + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.specularMap = null; + + this.alphaMap = null; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.setValues( parameters ); } - MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype ); + MeshToonMaterial.prototype = Object.create( Material.prototype ); MeshToonMaterial.prototype.constructor = MeshToonMaterial; MeshToonMaterial.prototype.isMeshToonMaterial = true; MeshToonMaterial.prototype.copy = function ( source ) { - MeshPhongMaterial.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); + + this.color.copy( source.color ); + this.specular.copy( source.specular ); + this.shininess = source.shininess; + this.map = source.map; this.gradientMap = source.gradientMap; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.specularMap = source.specularMap; + + this.alphaMap = source.alphaMap; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + return this; }; @@ -32208,7 +33153,6 @@ this.wireframeLinewidth = 1; this.fog = false; - this.lights = false; this.skinning = false; this.morphTargets = false; @@ -32435,8 +33379,6 @@ this.morphTargets = false; this.morphNormals = false; - this.lights = false; - this.setValues( parameters ); } @@ -32528,6 +33470,7 @@ var Materials = /*#__PURE__*/Object.freeze({ + __proto__: null, ShadowMaterial: ShadowMaterial, SpriteMaterial: SpriteMaterial, RawShaderMaterial: RawShaderMaterial, @@ -32575,7 +33518,7 @@ convertArray: function ( array, type, forceClone ) { if ( ! array || // let 'undefined' and 'null' pass - ! forceClone && array.constructor === type ) return array; + ! forceClone && array.constructor === type ) { return array; } if ( typeof type.BYTES_PER_ELEMENT === 'number' ) { @@ -32605,7 +33548,7 @@ var n = times.length; var result = new Array( n ); - for ( var i = 0; i !== n; ++ i ) result[ i ] = i; + for ( var i = 0; i !== n; ++ i ) { result[ i ] = i; } result.sort( compareTime ); @@ -32646,10 +33589,10 @@ } - if ( key === undefined ) return; // no data + if ( key === undefined ) { return; } // no data var value = key[ valuePropertyName ]; - if ( value === undefined ) return; // no data + if ( value === undefined ) { return; } // no data if ( Array.isArray( value ) ) { @@ -32708,6 +33651,79 @@ } + }, + + subclip: function ( sourceClip, name, startFrame, endFrame, fps ) { + + fps = fps || 30; + + var clip = sourceClip.clone(); + + clip.name = name; + + var tracks = []; + + for ( var i = 0; i < clip.tracks.length; ++ i ) { + + var track = clip.tracks[ i ]; + var valueSize = track.getValueSize(); + + var times = []; + var values = []; + + for ( var j = 0; j < track.times.length; ++ j ) { + + var frame = track.times[ j ] * fps; + + if ( frame < startFrame || frame >= endFrame ) { continue; } + + times.push( track.times[ j ] ); + + for ( var k = 0; k < valueSize; ++ k ) { + + values.push( track.values[ j * valueSize + k ] ); + + } + + } + + if ( times.length === 0 ) { continue; } + + track.times = AnimationUtils.convertArray( times, track.times.constructor ); + track.values = AnimationUtils.convertArray( values, track.values.constructor ); + + tracks.push( track ); + + } + + clip.tracks = tracks; + + // find minimum .times value across all tracks in the trimmed clip + + var minStartTime = Infinity; + + for ( var i = 0; i < clip.tracks.length; ++ i ) { + + if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) { + + minStartTime = clip.tracks[ i ].times[ 0 ]; + + } + + } + + // shift all tracks such that clip begins at t=0 + + for ( var i = 0; i < clip.tracks.length; ++ i ) { + + clip.tracks[ i ].shift( - 1 * minStartTime ); + + } + + clip.resetDuration(); + + return clip; + } }; @@ -32774,7 +33790,7 @@ if ( t1 === undefined ) { - if ( t < t0 ) break forward_scan; + if ( t < t0 ) { break forward_scan; } // after end @@ -32784,7 +33800,7 @@ } - if ( i1 === giveUpAt ) break; // this loop + if ( i1 === giveUpAt ) { break; } // this loop t0 = t1; t1 = pp[ ++ i1 ]; @@ -32832,7 +33848,7 @@ } - if ( i1 === giveUpAt ) break; // this loop + if ( i1 === giveUpAt ) { break; } // this loop t1 = t0; t0 = pp[ -- i1 - 1 ]; @@ -33197,8 +34213,8 @@ function KeyframeTrack( name, times, values, interpolation ) { - if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); - if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); + if ( name === undefined ) { throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); } + if ( times === undefined || times.length === 0 ) { throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); } this.name = name; @@ -33431,7 +34447,12 @@ if ( from !== 0 || to !== nKeys ) { // empty tracks are forbidden, so keep at least one keyframe - if ( from >= to ) to = Math.max( to, 1 ), from = to - 1; + if ( from >= to ) { + + to = Math.max( to, 1 ); + from = to - 1; + + } var stride = this.getValueSize(); this.times = AnimationUtils.arraySlice( times, from, to ); @@ -33524,8 +34545,9 @@ // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) optimize: function () { - var times = this.times, - values = this.values, + // times or values may be shared with other tracks, so overwriting is unsafe + var times = AnimationUtils.arraySlice( this.times ), + values = AnimationUtils.arraySlice( this.values ), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth, @@ -33620,6 +34642,11 @@ this.times = AnimationUtils.arraySlice( times, 0, writeIndex ); this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride ); + } else { + + this.times = times; + this.values = values; + } return this; @@ -33881,7 +34908,7 @@ this.tracks = tracks; this.duration = ( duration !== undefined ) ? duration : - 1; - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); // this means it should figure out its duration by scanning the tracks if ( this.duration < 0 ) { @@ -34167,7 +35194,7 @@ var animationKeys = hierarchyTracks[ h ].keys; // skip empty tracks - if ( ! animationKeys || animationKeys.length === 0 ) continue; + if ( ! animationKeys || animationKeys.length === 0 ) { continue; } // process morph targets if ( animationKeys[ 0 ].morphTargets ) { @@ -34306,7 +35333,6 @@ }, - clone: function () { var tracks = []; @@ -34335,7 +35361,7 @@ add: function ( key, file ) { - if ( this.enabled === false ) return; + if ( this.enabled === false ) { return; } // console.log( 'THREE.Cache', 'Adding key:', key ); @@ -34345,7 +35371,7 @@ get: function ( key ) { - if ( this.enabled === false ) return; + if ( this.enabled === false ) { return; } // console.log( 'THREE.Cache', 'Checking key:', key ); @@ -34379,6 +35405,7 @@ var itemsLoaded = 0; var itemsTotal = 0; var urlModifier = undefined; + var handlers = []; // Refer to #5689 for the reason why we don't set .onStart // in the constructor @@ -34455,14 +35482,101 @@ this.setURLModifier = function ( transform ) { urlModifier = transform; + + return this; + + }; + + this.addHandler = function ( regex, loader ) { + + handlers.push( regex, loader ); + + return this; + + }; + + this.removeHandler = function ( regex ) { + + var index = handlers.indexOf( regex ); + + if ( index !== - 1 ) { + + handlers.splice( index, 2 ); + + } + return this; }; + this.getHandler = function ( file ) { + + for ( var i = 0, l = handlers.length; i < l; i += 2 ) { + + var regex = handlers[ i ]; + var loader = handlers[ i + 1 ]; + + if ( regex.global ) { regex.lastIndex = 0; } // see #17920 + + if ( regex.test( file ) ) { + + return loader; + + } + + } + + return null; + + }; + } var DefaultLoadingManager = new LoadingManager(); + /** + * @author alteredq / http://alteredqualia.com/ + */ + + function Loader( manager ) { + + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + + this.crossOrigin = 'anonymous'; + this.path = ''; + this.resourcePath = ''; + + } + + Object.assign( Loader.prototype, { + + load: function ( /* url, onLoad, onProgress, onError */ ) {}, + + parse: function ( /* data */ ) {}, + + setCrossOrigin: function ( crossOrigin ) { + + this.crossOrigin = crossOrigin; + return this; + + }, + + setPath: function ( path ) { + + this.path = path; + return this; + + }, + + setResourcePath: function ( resourcePath ) { + + this.resourcePath = resourcePath; + return this; + + } + + } ); + /** * @author mrdoob / http://mrdoob.com/ */ @@ -34471,17 +35585,19 @@ function FileLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( FileLoader.prototype, { + FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: FileLoader, load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; + if ( url === undefined ) { url = ''; } - if ( this.path !== undefined ) url = this.path + url; + if ( this.path !== undefined ) { url = this.path + url; } url = this.manager.resolveURL( url ); @@ -34495,7 +35611,7 @@ setTimeout( function () { - if ( onLoad ) onLoad( cached ); + if ( onLoad ) { onLoad( cached ); } scope.manager.itemEnd( url ); @@ -34534,7 +35650,7 @@ data = decodeURIComponent( data ); - if ( isBase64 ) data = atob( data ); + if ( isBase64 ) { data = atob( data ); } try { @@ -34590,7 +35706,7 @@ // Wait for next browser tick like standard XMLHttpRequest event dispatching does setTimeout( function () { - if ( onLoad ) onLoad( response ); + if ( onLoad ) { onLoad( response ); } scope.manager.itemEnd( url ); @@ -34601,7 +35717,7 @@ // Wait for next browser tick like standard XMLHttpRequest event dispatching does setTimeout( function () { - if ( onError ) onError( error ); + if ( onError ) { onError( error ); } scope.manager.itemError( url ); scope.manager.itemEnd( url ); @@ -34632,8 +35748,6 @@ var response = this.response; - Cache.add( url, response ); - var callbacks = loading[ url ]; delete loading[ url ]; @@ -34643,12 +35757,16 @@ // Some browsers return HTTP Status 0 when using non-http protocol // e.g. 'file://' or 'data://'. Handle as success. - if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); + if ( this.status === 0 ) { console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); } + + // Add to cache only on HTTP success, so that we do not cache + // error response bodies as proper responses to requests. + Cache.add( url, response ); for ( var i = 0, il = callbacks.length; i < il; i ++ ) { var callback = callbacks[ i ]; - if ( callback.onLoad ) callback.onLoad( response ); + if ( callback.onLoad ) { callback.onLoad( response ); } } @@ -34659,7 +35777,7 @@ for ( var i = 0, il = callbacks.length; i < il; i ++ ) { var callback = callbacks[ i ]; - if ( callback.onError ) callback.onError( event ); + if ( callback.onError ) { callback.onError( event ); } } @@ -34677,7 +35795,7 @@ for ( var i = 0, il = callbacks.length; i < il; i ++ ) { var callback = callbacks[ i ]; - if ( callback.onProgress ) callback.onProgress( event ); + if ( callback.onProgress ) { callback.onProgress( event ); } } @@ -34692,7 +35810,7 @@ for ( var i = 0, il = callbacks.length; i < il; i ++ ) { var callback = callbacks[ i ]; - if ( callback.onError ) callback.onError( event ); + if ( callback.onError ) { callback.onError( event ); } } @@ -34710,7 +35828,7 @@ for ( var i = 0, il = callbacks.length; i < il; i ++ ) { var callback = callbacks[ i ]; - if ( callback.onError ) callback.onError( event ); + if ( callback.onError ) { callback.onError( event ); } } @@ -34719,10 +35837,10 @@ }, false ); - if ( this.responseType !== undefined ) request.responseType = this.responseType; - if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials; + if ( this.responseType !== undefined ) { request.responseType = this.responseType; } + if ( this.withCredentials !== undefined ) { request.withCredentials = this.withCredentials; } - if ( request.overrideMimeType ) request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); + if ( request.overrideMimeType ) { request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); } for ( var header in this.requestHeader ) { @@ -34740,13 +35858,6 @@ }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - setResponseType: function ( value ) { this.responseType = value; @@ -34783,11 +35894,13 @@ function AnimationLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( AnimationLoader.prototype, { + AnimationLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: AnimationLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -34817,13 +35930,6 @@ return animations; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -34832,18 +35938,19 @@ * @author mrdoob / http://mrdoob.com/ * * Abstract Base class to block based textures loader (dds, pvr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). */ function CompressedTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - - // override in sub classes - this._parser = null; + Loader.call( this, manager ); } - Object.assign( CompressedTextureLoader.prototype, { + CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: CompressedTextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -34862,7 +35969,7 @@ loader.load( url[ i ], function ( buffer ) { - var texDatas = scope._parser( buffer, true ); + var texDatas = scope.parse( buffer, true ); images[ i ] = { width: texDatas.width, @@ -34876,12 +35983,12 @@ if ( loaded === 6 ) { if ( texDatas.mipmapCount === 1 ) - texture.minFilter = LinearFilter; + { texture.minFilter = LinearFilter; } texture.format = texDatas.format; texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); + if ( onLoad ) { onLoad( texture ); } } @@ -34905,7 +36012,7 @@ loader.load( url, function ( buffer ) { - var texDatas = scope._parser( buffer, true ); + var texDatas = scope.parse( buffer, true ); if ( texDatas.isCubemap ) { @@ -34943,7 +36050,7 @@ texture.format = texDatas.format; texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); + if ( onLoad ) { onLoad( texture ); } }, onProgress, onError ); @@ -34951,13 +36058,6 @@ return texture; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -34966,18 +36066,19 @@ * @author Nikos M. / https://github.com/foo123/ * * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). */ function DataTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - - // override in sub classes - this._parser = null; + Loader.call( this, manager ); } - Object.assign( DataTextureLoader.prototype, { + DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: DataTextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -34990,9 +36091,9 @@ loader.setPath( this.path ); loader.load( url, function ( buffer ) { - var texData = scope._parser( buffer ); + var texData = scope.parse( buffer ); - if ( ! texData ) return; + if ( ! texData ) { return; } if ( texData.image !== undefined ) { @@ -35010,7 +36111,7 @@ texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping; texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter; - texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearMipmapLinearFilter; + texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter; texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1; @@ -35028,6 +36129,7 @@ if ( texData.mipmaps !== undefined ) { texture.mipmaps = texData.mipmaps; + texture.minFilter = LinearMipmapLinearFilter; // presumably... } @@ -35039,20 +36141,13 @@ texture.needsUpdate = true; - if ( onLoad ) onLoad( texture, texData ); + if ( onLoad ) { onLoad( texture, texData ); } }, onProgress, onError ); return texture; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35061,22 +36156,19 @@ * @author mrdoob / http://mrdoob.com/ */ - function ImageLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( ImageLoader.prototype, { + ImageLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: ImageLoader, load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; - - if ( this.path !== undefined ) url = this.path + url; + if ( this.path !== undefined ) { url = this.path + url; } url = this.manager.resolveURL( url ); @@ -35090,7 +36182,7 @@ setTimeout( function () { - if ( onLoad ) onLoad( cached ); + if ( onLoad ) { onLoad( cached ); } scope.manager.itemEnd( url ); @@ -35109,7 +36201,7 @@ Cache.add( url, this ); - if ( onLoad ) onLoad( this ); + if ( onLoad ) { onLoad( this ); } scope.manager.itemEnd( url ); @@ -35120,7 +36212,7 @@ image.removeEventListener( 'load', onImageLoad, false ); image.removeEventListener( 'error', onImageError, false ); - if ( onError ) onError( event ); + if ( onError ) { onError( event ); } scope.manager.itemError( url ); scope.manager.itemEnd( url ); @@ -35132,7 +36224,7 @@ if ( url.substr( 0, 5 ) !== 'data:' ) { - if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin; + if ( this.crossOrigin !== undefined ) { image.crossOrigin = this.crossOrigin; } } @@ -35142,20 +36234,6 @@ return image; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35167,13 +36245,13 @@ function CubeTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( CubeTextureLoader.prototype, { + CubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: CubeTextureLoader, load: function ( urls, onLoad, onProgress, onError ) { @@ -35197,7 +36275,7 @@ texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); + if ( onLoad ) { onLoad( texture ); } } @@ -35213,20 +36291,6 @@ return texture; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35235,16 +36299,15 @@ * @author mrdoob / http://mrdoob.com/ */ - function TextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( TextureLoader.prototype, { + TextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: TextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -35274,20 +36337,6 @@ return texture; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35361,7 +36410,7 @@ getPoints: function ( divisions ) { - if ( divisions === undefined ) divisions = 5; + if ( divisions === undefined ) { divisions = 5; } var points = []; @@ -35379,7 +36428,7 @@ getSpacedPoints: function ( divisions ) { - if ( divisions === undefined ) divisions = 5; + if ( divisions === undefined ) { divisions = 5; } var points = []; @@ -35406,7 +36455,7 @@ getLengths: function ( divisions ) { - if ( divisions === undefined ) divisions = this.arcLengthDivisions; + if ( divisions === undefined ) { divisions = this.arcLengthDivisions; } if ( this.cacheArcLengths && ( this.cacheArcLengths.length === divisions + 1 ) && @@ -35535,8 +36584,8 @@ // Capping in case of danger - if ( t1 < 0 ) t1 = 0; - if ( t2 > 1 ) t2 = 1; + if ( t1 < 0 ) { t1 = 0; } + if ( t2 > 1 ) { t2 = 1; } var pt1 = this.getPoint( t1 ); var pt2 = this.getPoint( t2 ); @@ -35629,7 +36678,7 @@ vec.normalize(); - theta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors + theta = Math.acos( MathUtils.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); @@ -35643,7 +36692,7 @@ if ( closed === true ) { - theta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); + theta = Math.acos( MathUtils.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); theta /= segments; if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) { @@ -35746,8 +36795,8 @@ var samePoints = Math.abs( deltaAngle ) < Number.EPSILON; // ensures that deltaAngle is 0 .. 2 PI - while ( deltaAngle < 0 ) deltaAngle += twoPi; - while ( deltaAngle > twoPi ) deltaAngle -= twoPi; + while ( deltaAngle < 0 ) { deltaAngle += twoPi; } + while ( deltaAngle > twoPi ) { deltaAngle -= twoPi; } if ( deltaAngle < Number.EPSILON ) { @@ -36036,9 +37085,9 @@ var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow ); // safety check for repeated points - if ( dt1 < 1e-4 ) dt1 = 1.0; - if ( dt0 < 1e-4 ) dt0 = dt1; - if ( dt2 < 1e-4 ) dt2 = dt1; + if ( dt1 < 1e-4 ) { dt1 = 1.0; } + if ( dt0 < 1e-4 ) { dt0 = dt1; } + if ( dt2 < 1e-4 ) { dt2 = dt1; } px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 ); py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 ); @@ -36742,6 +37791,7 @@ var Curves = /*#__PURE__*/Object.freeze({ + __proto__: null, ArcCurve: ArcCurve, CatmullRomCurve3: CatmullRomCurve3, CubicBezierCurve: CubicBezierCurve, @@ -36893,7 +37943,7 @@ getSpacedPoints: function ( divisions ) { - if ( divisions === undefined ) divisions = 40; + if ( divisions === undefined ) { divisions = 40; } var points = []; @@ -36933,7 +37983,7 @@ var point = pts[ j ]; - if ( last && last.equals( point ) ) continue; // ensures no consecutive points are duplicates + if ( last && last.equals( point ) ) { continue; } // ensures no consecutive points are duplicates points.push( point ); last = point; @@ -37045,12 +38095,16 @@ } + return this; + }, moveTo: function ( x, y ) { this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying? + return this; + }, lineTo: function ( x, y ) { @@ -37060,6 +38114,8 @@ this.currentPoint.set( x, y ); + return this; + }, quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { @@ -37074,6 +38130,8 @@ this.currentPoint.set( aX, aY ); + return this; + }, bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { @@ -37089,6 +38147,8 @@ this.currentPoint.set( aX, aY ); + return this; + }, splineThru: function ( pts /*Array of Vector*/ ) { @@ -37100,6 +38160,8 @@ this.currentPoint.copy( pts[ pts.length - 1 ] ); + return this; + }, arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { @@ -37110,12 +38172,16 @@ this.absarc( aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise ); + return this; + }, absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); + return this; + }, ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { @@ -37125,6 +38191,8 @@ this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); + return this; + }, absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { @@ -37149,6 +38217,8 @@ var lastPoint = curve.getPoint( 1 ); this.currentPoint.copy( lastPoint ); + return this; + }, copy: function ( source ) { @@ -37198,7 +38268,7 @@ Path.call( this, points ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.type = 'Shape'; @@ -37335,14 +38405,14 @@ data.object.color = this.color.getHex(); data.object.intensity = this.intensity; - if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); + if ( this.groundColor !== undefined ) { data.object.groundColor = this.groundColor.getHex(); } - if ( this.distance !== undefined ) data.object.distance = this.distance; - if ( this.angle !== undefined ) data.object.angle = this.angle; - if ( this.decay !== undefined ) data.object.decay = this.decay; - if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; + if ( this.distance !== undefined ) { data.object.distance = this.distance; } + if ( this.angle !== undefined ) { data.object.angle = this.angle; } + if ( this.decay !== undefined ) { data.object.decay = this.decay; } + if ( this.penumbra !== undefined ) { data.object.penumbra = this.penumbra; } - if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); + if ( this.shadow !== undefined ) { data.object.shadow = this.shadow.toJSON(); } return data; @@ -37401,12 +38471,84 @@ this.mapSize = new Vector2( 512, 512 ); this.map = null; + this.mapPass = null; this.matrix = new Matrix4(); + this._frustum = new Frustum(); + this._frameExtents = new Vector2( 1, 1 ); + + this._viewportCount = 1; + + this._viewports = [ + + new Vector4( 0, 0, 1, 1 ) + + ]; + } Object.assign( LightShadow.prototype, { + _projScreenMatrix: new Matrix4(), + + _lightPositionWorld: new Vector3(), + + _lookTarget: new Vector3(), + + getViewportCount: function () { + + return this._viewportCount; + + }, + + getFrustum: function () { + + return this._frustum; + + }, + + updateMatrices: function ( light ) { + + var shadowCamera = this.camera, + shadowMatrix = this.matrix, + projScreenMatrix = this._projScreenMatrix, + lookTarget = this._lookTarget, + lightPositionWorld = this._lightPositionWorld; + + lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + shadowCamera.position.copy( lightPositionWorld ); + + lookTarget.setFromMatrixPosition( light.target.matrixWorld ); + shadowCamera.lookAt( lookTarget ); + shadowCamera.updateMatrixWorld(); + + projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); + this._frustum.setFromProjectionMatrix( projScreenMatrix ); + + shadowMatrix.set( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0 + ); + + shadowMatrix.multiply( shadowCamera.projectionMatrix ); + shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + + }, + + getViewport: function ( viewportIndex ) { + + return this._viewports[ viewportIndex ]; + + }, + + getFrameExtents: function () { + + return this._frameExtents; + + }, + copy: function ( source ) { this.camera = source.camera.clone(); @@ -37430,9 +38572,9 @@ var object = {}; - if ( this.bias !== 0 ) object.bias = this.bias; - if ( this.radius !== 1 ) object.radius = this.radius; - if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) object.mapSize = this.mapSize.toArray(); + if ( this.bias !== 0 ) { object.bias = this.bias; } + if ( this.radius !== 1 ) { object.radius = this.radius; } + if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) { object.mapSize = this.mapSize.toArray(); } object.camera = this.camera.toJSON( false ).object; delete object.camera.matrix; @@ -37459,11 +38601,11 @@ isSpotLightShadow: true, - update: function ( light ) { + updateMatrices: function ( light ) { var camera = this.camera; - var fov = _Math.RAD2DEG * 2 * light.angle; + var fov = MathUtils.RAD2DEG * 2 * light.angle; var aspect = this.mapSize.width / this.mapSize.height; var far = light.distance || camera.far; @@ -37476,6 +38618,8 @@ } + LightShadow.prototype.updateMatrices.call( this, light ); + } } ); @@ -37546,6 +38690,88 @@ } ); + function PointLightShadow() { + + LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) ); + + this._frameExtents = new Vector2( 4, 2 ); + + this._viewportCount = 6; + + this._viewports = [ + // These viewports map a cube-map onto a 2D texture with the + // following orientation: + // + // xzXZ + // y Y + // + // X - Positive x direction + // x - Negative x direction + // Y - Positive y direction + // y - Negative y direction + // Z - Positive z direction + // z - Negative z direction + + // positive X + new Vector4( 2, 1, 1, 1 ), + // negative X + new Vector4( 0, 1, 1, 1 ), + // positive Z + new Vector4( 3, 1, 1, 1 ), + // negative Z + new Vector4( 1, 1, 1, 1 ), + // positive Y + new Vector4( 3, 0, 1, 1 ), + // negative Y + new Vector4( 1, 0, 1, 1 ) + ]; + + this._cubeDirections = [ + new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), + new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) + ]; + + this._cubeUps = [ + new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), + new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) + ]; + + } + + PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { + + constructor: PointLightShadow, + + isPointLightShadow: true, + + updateMatrices: function ( light, viewportIndex ) { + + if ( viewportIndex === undefined ) { viewportIndex = 0; } + + var camera = this.camera, + shadowMatrix = this.matrix, + lightPositionWorld = this._lightPositionWorld, + lookTarget = this._lookTarget, + projScreenMatrix = this._projScreenMatrix; + + lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + camera.position.copy( lightPositionWorld ); + + lookTarget.copy( camera.position ); + lookTarget.add( this._cubeDirections[ viewportIndex ] ); + camera.up.copy( this._cubeUps[ viewportIndex ] ); + camera.lookAt( lookTarget ); + camera.updateMatrixWorld(); + + shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z ); + + projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + this._frustum.setFromProjectionMatrix( projScreenMatrix ); + + } + + } ); + /** * @author mrdoob / http://mrdoob.com/ */ @@ -37577,7 +38803,7 @@ this.distance = ( distance !== undefined ) ? distance : 0; this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. - this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) ); + this.shadow = new PointLightShadow(); } @@ -37706,15 +38932,13 @@ if ( this.view !== null && this.view.enabled ) { - var zoomW = this.zoom / ( this.view.width / this.view.fullWidth ); - var zoomH = this.zoom / ( this.view.height / this.view.fullHeight ); - var scaleW = ( this.right - this.left ) / this.view.width; - var scaleH = ( this.top - this.bottom ) / this.view.height; + var scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom; + var scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom; - left += scaleW * ( this.view.offsetX / zoomW ); - right = left + scaleW * ( this.view.width / zoomW ); - top -= scaleH * ( this.view.offsetY / zoomH ); - bottom = top - scaleH * ( this.view.height / zoomH ); + left += scaleW * this.view.offsetX; + right = left + scaleW * this.view.width; + top -= scaleH * this.view.offsetY; + bottom = top - scaleH * this.view.height; } @@ -37736,7 +38960,7 @@ data.object.near = this.near; data.object.far = this.far; - if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + if ( this.view !== null ) { data.object.view = Object.assign( {}, this.view ); } return data; @@ -37748,7 +38972,7 @@ * @author mrdoob / http://mrdoob.com/ */ - function DirectionalLightShadow( ) { + function DirectionalLightShadow() { LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); @@ -37756,7 +38980,15 @@ DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { - constructor: DirectionalLightShadow + constructor: DirectionalLightShadow, + + isDirectionalLightShadow: true, + + updateMatrices: function ( light ) { + + LightShadow.prototype.updateMatrices.call( this, light ); + + } } ); @@ -37873,12 +39105,15 @@ function MaterialLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); + this.textures = {}; } - Object.assign( MaterialLoader.prototype, { + MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: MaterialLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -37912,51 +39147,80 @@ var material = new Materials[ json.type ](); - if ( json.uuid !== undefined ) material.uuid = json.uuid; - if ( json.name !== undefined ) material.name = json.name; - if ( json.color !== undefined ) material.color.setHex( json.color ); - if ( json.roughness !== undefined ) material.roughness = json.roughness; - if ( json.metalness !== undefined ) material.metalness = json.metalness; - if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); - if ( json.specular !== undefined ) material.specular.setHex( json.specular ); - if ( json.shininess !== undefined ) material.shininess = json.shininess; - if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat; - if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness; - if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors; - if ( json.fog !== undefined ) material.fog = json.fog; - if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; - if ( json.blending !== undefined ) material.blending = json.blending; - if ( json.combine !== undefined ) material.combine = json.combine; - if ( json.side !== undefined ) material.side = json.side; - if ( json.opacity !== undefined ) material.opacity = json.opacity; - if ( json.transparent !== undefined ) material.transparent = json.transparent; - if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest; - if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; - if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; - if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; - if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; - if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; - if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; - if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin; - - if ( json.rotation !== undefined ) material.rotation = json.rotation; - - if ( json.linewidth !== 1 ) material.linewidth = json.linewidth; - if ( json.dashSize !== undefined ) material.dashSize = json.dashSize; - if ( json.gapSize !== undefined ) material.gapSize = json.gapSize; - if ( json.scale !== undefined ) material.scale = json.scale; - - if ( json.polygonOffset !== undefined ) material.polygonOffset = json.polygonOffset; - if ( json.polygonOffsetFactor !== undefined ) material.polygonOffsetFactor = json.polygonOffsetFactor; - if ( json.polygonOffsetUnits !== undefined ) material.polygonOffsetUnits = json.polygonOffsetUnits; - - if ( json.skinning !== undefined ) material.skinning = json.skinning; - if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets; - if ( json.morphNormals !== undefined ) material.morphNormals = json.morphNormals; - if ( json.dithering !== undefined ) material.dithering = json.dithering; - - if ( json.visible !== undefined ) material.visible = json.visible; - if ( json.userData !== undefined ) material.userData = json.userData; + if ( json.uuid !== undefined ) { material.uuid = json.uuid; } + if ( json.name !== undefined ) { material.name = json.name; } + if ( json.color !== undefined ) { material.color.setHex( json.color ); } + if ( json.roughness !== undefined ) { material.roughness = json.roughness; } + if ( json.metalness !== undefined ) { material.metalness = json.metalness; } + if ( json.sheen !== undefined ) { material.sheen = new Color().setHex( json.sheen ); } + if ( json.emissive !== undefined ) { material.emissive.setHex( json.emissive ); } + if ( json.specular !== undefined ) { material.specular.setHex( json.specular ); } + if ( json.shininess !== undefined ) { material.shininess = json.shininess; } + if ( json.clearcoat !== undefined ) { material.clearcoat = json.clearcoat; } + if ( json.clearcoatRoughness !== undefined ) { material.clearcoatRoughness = json.clearcoatRoughness; } + if ( json.fog !== undefined ) { material.fog = json.fog; } + if ( json.flatShading !== undefined ) { material.flatShading = json.flatShading; } + if ( json.blending !== undefined ) { material.blending = json.blending; } + if ( json.combine !== undefined ) { material.combine = json.combine; } + if ( json.side !== undefined ) { material.side = json.side; } + if ( json.opacity !== undefined ) { material.opacity = json.opacity; } + if ( json.transparent !== undefined ) { material.transparent = json.transparent; } + if ( json.alphaTest !== undefined ) { material.alphaTest = json.alphaTest; } + if ( json.depthTest !== undefined ) { material.depthTest = json.depthTest; } + if ( json.depthWrite !== undefined ) { material.depthWrite = json.depthWrite; } + if ( json.colorWrite !== undefined ) { material.colorWrite = json.colorWrite; } + + if ( json.stencilWrite !== undefined ) { material.stencilWrite = json.stencilWrite; } + if ( json.stencilWriteMask !== undefined ) { material.stencilWriteMask = json.stencilWriteMask; } + if ( json.stencilFunc !== undefined ) { material.stencilFunc = json.stencilFunc; } + if ( json.stencilRef !== undefined ) { material.stencilRef = json.stencilRef; } + if ( json.stencilFuncMask !== undefined ) { material.stencilFuncMask = json.stencilFuncMask; } + if ( json.stencilFail !== undefined ) { material.stencilFail = json.stencilFail; } + if ( json.stencilZFail !== undefined ) { material.stencilZFail = json.stencilZFail; } + if ( json.stencilZPass !== undefined ) { material.stencilZPass = json.stencilZPass; } + + if ( json.wireframe !== undefined ) { material.wireframe = json.wireframe; } + if ( json.wireframeLinewidth !== undefined ) { material.wireframeLinewidth = json.wireframeLinewidth; } + if ( json.wireframeLinecap !== undefined ) { material.wireframeLinecap = json.wireframeLinecap; } + if ( json.wireframeLinejoin !== undefined ) { material.wireframeLinejoin = json.wireframeLinejoin; } + + if ( json.rotation !== undefined ) { material.rotation = json.rotation; } + + if ( json.linewidth !== 1 ) { material.linewidth = json.linewidth; } + if ( json.dashSize !== undefined ) { material.dashSize = json.dashSize; } + if ( json.gapSize !== undefined ) { material.gapSize = json.gapSize; } + if ( json.scale !== undefined ) { material.scale = json.scale; } + + if ( json.polygonOffset !== undefined ) { material.polygonOffset = json.polygonOffset; } + if ( json.polygonOffsetFactor !== undefined ) { material.polygonOffsetFactor = json.polygonOffsetFactor; } + if ( json.polygonOffsetUnits !== undefined ) { material.polygonOffsetUnits = json.polygonOffsetUnits; } + + if ( json.skinning !== undefined ) { material.skinning = json.skinning; } + if ( json.morphTargets !== undefined ) { material.morphTargets = json.morphTargets; } + if ( json.morphNormals !== undefined ) { material.morphNormals = json.morphNormals; } + if ( json.dithering !== undefined ) { material.dithering = json.dithering; } + + if ( json.vertexTangents !== undefined ) { material.vertexTangents = json.vertexTangents; } + + if ( json.visible !== undefined ) { material.visible = json.visible; } + + if ( json.toneMapped !== undefined ) { material.toneMapped = json.toneMapped; } + + if ( json.userData !== undefined ) { material.userData = json.userData; } + + if ( json.vertexColors !== undefined ) { + + if ( typeof json.vertexColors === 'number' ) { + + material.vertexColors = ( json.vertexColors > 0 ) ? true : false; + + } else { + + material.vertexColors = json.vertexColors; + + } + + } // Shader Material @@ -38006,9 +39270,9 @@ } - if ( json.defines !== undefined ) material.defines = json.defines; - if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader; - if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader; + if ( json.defines !== undefined ) { material.defines = json.defines; } + if ( json.vertexShader !== undefined ) { material.vertexShader = json.vertexShader; } + if ( json.fragmentShader !== undefined ) { material.fragmentShader = json.fragmentShader; } if ( json.extensions !== undefined ) { @@ -38022,30 +39286,25 @@ // Deprecated - if ( json.shading !== undefined ) material.flatShading = json.shading === 1; // THREE.FlatShading + if ( json.shading !== undefined ) { material.flatShading = json.shading === 1; } // THREE.FlatShading // for PointsMaterial - if ( json.size !== undefined ) material.size = json.size; - if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation; + if ( json.size !== undefined ) { material.size = json.size; } + if ( json.sizeAttenuation !== undefined ) { material.sizeAttenuation = json.sizeAttenuation; } // maps - if ( json.map !== undefined ) material.map = getTexture( json.map ); - if ( json.matcap !== undefined ) material.matcap = getTexture( json.matcap ); - - if ( json.alphaMap !== undefined ) { + if ( json.map !== undefined ) { material.map = getTexture( json.map ); } + if ( json.matcap !== undefined ) { material.matcap = getTexture( json.matcap ); } - material.alphaMap = getTexture( json.alphaMap ); - material.transparent = true; - - } + if ( json.alphaMap !== undefined ) { material.alphaMap = getTexture( json.alphaMap ); } - if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); - if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; + if ( json.bumpMap !== undefined ) { material.bumpMap = getTexture( json.bumpMap ); } + if ( json.bumpScale !== undefined ) { material.bumpScale = json.bumpScale; } - if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap ); - if ( json.normalMapType !== undefined ) material.normalMapType = json.normalMapType; + if ( json.normalMap !== undefined ) { material.normalMap = getTexture( json.normalMap ); } + if ( json.normalMapType !== undefined ) { material.normalMapType = json.normalMapType; } if ( json.normalScale !== undefined ) { var normalScale = json.normalScale; @@ -38062,46 +39321,41 @@ } - if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap ); - if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale; - if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias; + if ( json.displacementMap !== undefined ) { material.displacementMap = getTexture( json.displacementMap ); } + if ( json.displacementScale !== undefined ) { material.displacementScale = json.displacementScale; } + if ( json.displacementBias !== undefined ) { material.displacementBias = json.displacementBias; } - if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap ); - if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap ); + if ( json.roughnessMap !== undefined ) { material.roughnessMap = getTexture( json.roughnessMap ); } + if ( json.metalnessMap !== undefined ) { material.metalnessMap = getTexture( json.metalnessMap ); } - if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap ); - if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity; + if ( json.emissiveMap !== undefined ) { material.emissiveMap = getTexture( json.emissiveMap ); } + if ( json.emissiveIntensity !== undefined ) { material.emissiveIntensity = json.emissiveIntensity; } - if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap ); + if ( json.specularMap !== undefined ) { material.specularMap = getTexture( json.specularMap ); } - if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap ); - if ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity; + if ( json.envMap !== undefined ) { material.envMap = getTexture( json.envMap ); } + if ( json.envMapIntensity !== undefined ) { material.envMapIntensity = json.envMapIntensity; } - if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; - if ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio; + if ( json.reflectivity !== undefined ) { material.reflectivity = json.reflectivity; } + if ( json.refractionRatio !== undefined ) { material.refractionRatio = json.refractionRatio; } - if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); - if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; + if ( json.lightMap !== undefined ) { material.lightMap = getTexture( json.lightMap ); } + if ( json.lightMapIntensity !== undefined ) { material.lightMapIntensity = json.lightMapIntensity; } - if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap ); - if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity; + if ( json.aoMap !== undefined ) { material.aoMap = getTexture( json.aoMap ); } + if ( json.aoMapIntensity !== undefined ) { material.aoMapIntensity = json.aoMapIntensity; } - if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); + if ( json.gradientMap !== undefined ) { material.gradientMap = getTexture( json.gradientMap ); } - if ( json.clearCoatNormalMap !== undefined ) material.clearCoatNormalMap = getTexture( json.clearCoatNormalMap ); - if ( json.clearCoatNormalScale !== undefined ) material.clearCoatNormalScale = new Vector2().fromArray( json.clearCoatNormalScale ); + if ( json.clearcoatMap !== undefined ) { material.clearcoatMap = getTexture( json.clearcoatMap ); } + if ( json.clearcoatRoughnessMap !== undefined ) { material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap ); } + if ( json.clearcoatNormalMap !== undefined ) { material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); } + if ( json.clearcoatNormalScale !== undefined ) { material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); } return material; }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - setTextures: function ( value ) { this.textures = value; @@ -38155,7 +39409,7 @@ var index = url.lastIndexOf( '/' ); - if ( index === - 1 ) return './'; + if ( index === - 1 ) { return './'; } return url.substr( 0, index + 1 ); @@ -38270,11 +39524,13 @@ function BufferGeometryLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( BufferGeometryLoader.prototype, { + BufferGeometryLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: BufferGeometryLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -38311,8 +39567,8 @@ var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); var bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute; var bufferAttribute = new bufferAttributeConstr( typedArray, attribute.itemSize, attribute.normalized ); - if ( attribute.name !== undefined ) bufferAttribute.name = attribute.name; - geometry.addAttribute( key, bufferAttribute ); + if ( attribute.name !== undefined ) { bufferAttribute.name = attribute.name; } + geometry.setAttribute( key, bufferAttribute ); } @@ -38332,7 +39588,7 @@ var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); var bufferAttribute = new BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ); - if ( attribute.name !== undefined ) bufferAttribute.name = attribute.name; + if ( attribute.name !== undefined ) { bufferAttribute.name = attribute.name; } array.push( bufferAttribute ); } @@ -38343,6 +39599,14 @@ } + var morphTargetsRelative = json.data.morphTargetsRelative; + + if ( morphTargetsRelative ) { + + geometry.morphTargetsRelative = true; + + } + var groups = json.data.groups || json.data.drawcalls || json.data.offsets; if ( groups !== undefined ) { @@ -38373,18 +39637,11 @@ } - if ( json.name ) geometry.name = json.name; - if ( json.userData ) geometry.userData = json.userData; + if ( json.name ) { geometry.name = json.name; } + if ( json.userData ) { geometry.userData = json.userData; } return geometry; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -38408,20 +39665,19 @@ function ObjectLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - this.resourcePath = ''; + Loader.call( this, manager ); } - Object.assign( ObjectLoader.prototype, { + ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: ObjectLoader, load: function ( url, onLoad, onProgress, onError ) { var scope = this; - var path = ( this.path === undefined ) ? LoaderUtils.extractUrlBase( url ) : this.path; + var path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path; this.resourcePath = this.resourcePath || path; var loader = new FileLoader( scope.manager ); @@ -38436,7 +39692,7 @@ } catch ( error ) { - if ( onError !== undefined ) onError( error ); + if ( onError !== undefined ) { onError( error ); } console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message ); @@ -38459,27 +39715,6 @@ }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - parse: function ( json, onLoad ) { var shapes = this.parseShape( json.shapes ); @@ -38487,7 +39722,7 @@ var images = this.parseImages( json.images, function () { - if ( onLoad !== undefined ) onLoad( object ); + if ( onLoad !== undefined ) { onLoad( object ); } } ); @@ -38504,7 +39739,7 @@ if ( json.images === undefined || json.images.length === 0 ) { - if ( onLoad !== undefined ) onLoad( object ); + if ( onLoad !== undefined ) { onLoad( object ); } } @@ -38786,17 +40021,7 @@ case 'Geometry': - if ( 'THREE' in window && 'LegacyJSONLoader' in THREE ) { - - var geometryLoader = new THREE.LegacyJSONLoader(); - geometry = geometryLoader.parse( data, this.resourcePath ).geometry; - - - } else { - - console.error( 'THREE.ObjectLoader: You have to import LegacyJSONLoader in order load geometry data of type "Geometry".' ); - - } + console.error( 'THREE.ObjectLoader: Loading "Geometry" is not supported anymore.' ); break; @@ -38810,8 +40035,8 @@ geometry.uuid = data.uuid; - if ( data.name !== undefined ) geometry.name = data.name; - if ( geometry.isBufferGeometry === true && data.userData !== undefined ) geometry.userData = data.userData; + if ( data.name !== undefined ) { geometry.name = data.name; } + if ( geometry.isBufferGeometry === true && data.userData !== undefined ) { geometry.userData = data.userData; } geometries[ data.uuid ] = geometry; @@ -38889,7 +40114,7 @@ var clip = AnimationClip.parse( data ); - if ( data.uuid !== undefined ) clip.uuid = data.uuid; + if ( data.uuid !== undefined ) { clip.uuid = data.uuid; } animations.push( clip ); @@ -38971,7 +40196,7 @@ function parseConstant( value, type ) { - if ( typeof value === 'number' ) return value; + if ( typeof value === 'number' ) { return value; } console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value ); @@ -39015,14 +40240,14 @@ texture.uuid = data.uuid; - if ( data.name !== undefined ) texture.name = data.name; + if ( data.name !== undefined ) { texture.name = data.name; } - if ( data.mapping !== undefined ) texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); + if ( data.mapping !== undefined ) { texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); } - if ( data.offset !== undefined ) texture.offset.fromArray( data.offset ); - if ( data.repeat !== undefined ) texture.repeat.fromArray( data.repeat ); - if ( data.center !== undefined ) texture.center.fromArray( data.center ); - if ( data.rotation !== undefined ) texture.rotation = data.rotation; + if ( data.offset !== undefined ) { texture.offset.fromArray( data.offset ); } + if ( data.repeat !== undefined ) { texture.repeat.fromArray( data.repeat ); } + if ( data.center !== undefined ) { texture.center.fromArray( data.center ); } + if ( data.rotation !== undefined ) { texture.rotation = data.rotation; } if ( data.wrap !== undefined ) { @@ -39031,18 +40256,18 @@ } - if ( data.format !== undefined ) texture.format = data.format; - if ( data.type !== undefined ) texture.type = data.type; - if ( data.encoding !== undefined ) texture.encoding = data.encoding; + if ( data.format !== undefined ) { texture.format = data.format; } + if ( data.type !== undefined ) { texture.type = data.type; } + if ( data.encoding !== undefined ) { texture.encoding = data.encoding; } - if ( data.minFilter !== undefined ) texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); - if ( data.magFilter !== undefined ) texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); - if ( data.anisotropy !== undefined ) texture.anisotropy = data.anisotropy; + if ( data.minFilter !== undefined ) { texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); } + if ( data.magFilter !== undefined ) { texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); } + if ( data.anisotropy !== undefined ) { texture.anisotropy = data.anisotropy; } - if ( data.flipY !== undefined ) texture.flipY = data.flipY; + if ( data.flipY !== undefined ) { texture.flipY = data.flipY; } - if ( data.premultiplyAlpha !== undefined ) texture.premultiplyAlpha = data.premultiplyAlpha; - if ( data.unpackAlignment !== undefined ) texture.unpackAlignment = data.unpackAlignment; + if ( data.premultiplyAlpha !== undefined ) { texture.premultiplyAlpha = data.premultiplyAlpha; } + if ( data.unpackAlignment !== undefined ) { texture.unpackAlignment = data.unpackAlignment; } textures[ data.uuid ] = texture; @@ -39072,7 +40297,7 @@ function getMaterial( name ) { - if ( name === undefined ) return undefined; + if ( name === undefined ) { return undefined; } if ( Array.isArray( name ) ) { @@ -39142,11 +40367,11 @@ object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); - if ( data.focus !== undefined ) object.focus = data.focus; - if ( data.zoom !== undefined ) object.zoom = data.zoom; - if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; - if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; - if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); + if ( data.focus !== undefined ) { object.focus = data.focus; } + if ( data.zoom !== undefined ) { object.zoom = data.zoom; } + if ( data.filmGauge !== undefined ) { object.filmGauge = data.filmGauge; } + if ( data.filmOffset !== undefined ) { object.filmOffset = data.filmOffset; } + if ( data.view !== undefined ) { object.view = Object.assign( {}, data.view ); } break; @@ -39154,8 +40379,8 @@ object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far ); - if ( data.zoom !== undefined ) object.zoom = data.zoom; - if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); + if ( data.zoom !== undefined ) { object.zoom = data.zoom; } + if ( data.view !== undefined ) { object.view = Object.assign( {}, data.view ); } break; @@ -39214,7 +40439,17 @@ } - if ( data.drawMode !== undefined ) object.setDrawMode( data.drawMode ); + break; + + case 'InstancedMesh': + + var geometry = getGeometry( data.geometry ); + var material = getMaterial( data.material ); + var count = data.count; + var instanceMatrix = data.instanceMatrix; + + object = new InstancedMesh( geometry, material, count ); + object.instanceMatrix = new BufferAttribute( new Float32Array( instanceMatrix.array ), 16 ); break; @@ -39269,41 +40504,41 @@ object.uuid = data.uuid; - if ( data.name !== undefined ) object.name = data.name; + if ( data.name !== undefined ) { object.name = data.name; } if ( data.matrix !== undefined ) { object.matrix.fromArray( data.matrix ); - if ( data.matrixAutoUpdate !== undefined ) object.matrixAutoUpdate = data.matrixAutoUpdate; - if ( object.matrixAutoUpdate ) object.matrix.decompose( object.position, object.quaternion, object.scale ); + if ( data.matrixAutoUpdate !== undefined ) { object.matrixAutoUpdate = data.matrixAutoUpdate; } + if ( object.matrixAutoUpdate ) { object.matrix.decompose( object.position, object.quaternion, object.scale ); } } else { - if ( data.position !== undefined ) object.position.fromArray( data.position ); - if ( data.rotation !== undefined ) object.rotation.fromArray( data.rotation ); - if ( data.quaternion !== undefined ) object.quaternion.fromArray( data.quaternion ); - if ( data.scale !== undefined ) object.scale.fromArray( data.scale ); + if ( data.position !== undefined ) { object.position.fromArray( data.position ); } + if ( data.rotation !== undefined ) { object.rotation.fromArray( data.rotation ); } + if ( data.quaternion !== undefined ) { object.quaternion.fromArray( data.quaternion ); } + if ( data.scale !== undefined ) { object.scale.fromArray( data.scale ); } } - if ( data.castShadow !== undefined ) object.castShadow = data.castShadow; - if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow; + if ( data.castShadow !== undefined ) { object.castShadow = data.castShadow; } + if ( data.receiveShadow !== undefined ) { object.receiveShadow = data.receiveShadow; } if ( data.shadow ) { - if ( data.shadow.bias !== undefined ) object.shadow.bias = data.shadow.bias; - if ( data.shadow.radius !== undefined ) object.shadow.radius = data.shadow.radius; - if ( data.shadow.mapSize !== undefined ) object.shadow.mapSize.fromArray( data.shadow.mapSize ); - if ( data.shadow.camera !== undefined ) object.shadow.camera = this.parseObject( data.shadow.camera ); + if ( data.shadow.bias !== undefined ) { object.shadow.bias = data.shadow.bias; } + if ( data.shadow.radius !== undefined ) { object.shadow.radius = data.shadow.radius; } + if ( data.shadow.mapSize !== undefined ) { object.shadow.mapSize.fromArray( data.shadow.mapSize ); } + if ( data.shadow.camera !== undefined ) { object.shadow.camera = this.parseObject( data.shadow.camera ); } } - if ( data.visible !== undefined ) object.visible = data.visible; - if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled; - if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder; - if ( data.userData !== undefined ) object.userData = data.userData; - if ( data.layers !== undefined ) object.layers.mask = data.layers; + if ( data.visible !== undefined ) { object.visible = data.visible; } + if ( data.frustumCulled !== undefined ) { object.frustumCulled = data.frustumCulled; } + if ( data.renderOrder !== undefined ) { object.renderOrder = data.renderOrder; } + if ( data.userData !== undefined ) { object.userData = data.userData; } + if ( data.layers !== undefined ) { object.layers.mask = data.layers; } if ( data.children !== undefined ) { @@ -39319,6 +40554,8 @@ if ( data.type === 'LOD' ) { + if ( data.autoUpdate !== undefined ) { object.autoUpdate = data.autoUpdate; } + var levels = data.levels; for ( var l = 0; l < levels.length; l ++ ) { @@ -39387,12 +40624,13 @@ } - this.manager = manager !== undefined ? manager : DefaultLoadingManager; + Loader.call( this, manager ); + this.options = undefined; } - ImageBitmapLoader.prototype = { + ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ), { constructor: ImageBitmapLoader, @@ -39406,9 +40644,9 @@ load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; + if ( url === undefined ) { url = ''; } - if ( this.path !== undefined ) url = this.path + url; + if ( this.path !== undefined ) { url = this.path + url; } url = this.manager.resolveURL( url ); @@ -39422,7 +40660,7 @@ setTimeout( function () { - if ( onLoad ) onLoad( cached ); + if ( onLoad ) { onLoad( cached ); } scope.manager.itemEnd( url ); @@ -39453,13 +40691,13 @@ Cache.add( url, imageBitmap ); - if ( onLoad ) onLoad( imageBitmap ); + if ( onLoad ) { onLoad( imageBitmap ); } scope.manager.itemEnd( url ); } ).catch( function ( e ) { - if ( onError ) onError( e ); + if ( onError ) { onError( e ); } scope.manager.itemError( url ); scope.manager.itemEnd( url ); @@ -39468,22 +40706,9 @@ scope.manager.itemStart( url ); - }, - - setCrossOrigin: function ( /* value */ ) { - - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } - }; + } ); /** * @author zz85 / http://www.lab4games.net/zz85/blog @@ -39509,30 +40734,40 @@ this.subPaths.push( this.currentPath ); this.currentPath.moveTo( x, y ); + return this; + }, lineTo: function ( x, y ) { this.currentPath.lineTo( x, y ); + return this; + }, quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); + return this; + }, bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); + return this; + }, splineThru: function ( pts ) { this.currentPath.splineThru( pts ); + return this; + }, toShapes: function ( isCCW, noHoles ) { @@ -39582,18 +40817,18 @@ edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; } - if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; + if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) { continue; } if ( inPt.y === edgeLowPt.y ) { - if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? + if ( inPt.x === edgeLowPt.x ) { return true; } // inPt is on contour ? // continue; // no intersection or edgeLowPt => doesn't count !!! } else { var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); - if ( perpEdge === 0 ) return true; // inPt is on contour ? - if ( perpEdge < 0 ) continue; + if ( perpEdge === 0 ) { return true; } // inPt is on contour ? + if ( perpEdge < 0 ) { continue; } inside = ! inside; // true intersection left of inPt } @@ -39601,10 +40836,10 @@ } else { // parallel or collinear - if ( inPt.y !== edgeLowPt.y ) continue; // parallel + if ( inPt.y !== edgeLowPt.y ) { continue; } // parallel // edge lies on the same horizontal line as inPt if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || - ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! + ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) { return true; } // inPt: Point on contour ! // continue; } @@ -39618,9 +40853,9 @@ var isClockWise = ShapeUtils.isClockWise; var subPaths = this.subPaths; - if ( subPaths.length === 0 ) return []; + if ( subPaths.length === 0 ) { return []; } - if ( noHoles === true ) return toShapesNoHoles( subPaths ); + if ( noHoles === true ) { return toShapesNoHoles( subPaths ); } var solid, tmpPath, tmpShape, shapes = []; @@ -39658,12 +40893,12 @@ if ( solid ) { - if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; + if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) { mainIdx ++; } newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints }; newShapes[ mainIdx ].s.curves = tmpPath.curves; - if ( holesFirst ) mainIdx ++; + if ( holesFirst ) { mainIdx ++; } newShapeHoles[ mainIdx ] = []; //console.log('cw', i); @@ -39679,7 +40914,7 @@ } // only Holes? -> probably all Shapes with wrong orientation - if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); + if ( ! newShapes[ 0 ] ) { return toShapesNoHoles( subPaths ); } if ( newShapes.length > 1 ) { @@ -39706,7 +40941,7 @@ if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { - if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); + if ( sIdx !== s2Idx ) { toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); } if ( hole_unassigned ) { hole_unassigned = false; @@ -39734,7 +40969,7 @@ if ( toChange.length > 0 ) { // console.log("to change: ", toChange); - if ( ! ambiguous ) newShapeHoles = betterShapeHoles; + if ( ! ambiguous ) { newShapeHoles = betterShapeHoles; } } @@ -39784,7 +41019,7 @@ generateShapes: function ( text, size ) { - if ( size === undefined ) size = 100; + if ( size === undefined ) { size = 100; } var shapes = []; var paths = createPaths( text, size, this.data ); @@ -39803,7 +41038,7 @@ function createPaths( text, size, data ) { - var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // see #13988 + var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // workaround for IE11, see #13988 var scale = size / data.resolution; var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale; @@ -39918,11 +41153,13 @@ function FontLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( FontLoader.prototype, { + FontLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: FontLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -39947,7 +41184,7 @@ var font = scope.parse( json ); - if ( onLoad ) onLoad( font ); + if ( onLoad ) { onLoad( font ); } }, onProgress, onError ); @@ -39957,332 +41194,10 @@ return new Font( json ); - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - } - - } ); - - /** - * @author alteredq / http://alteredqualia.com/ - */ - - var _BlendingMode = { - NoBlending: NoBlending, - NormalBlending: NormalBlending, - AdditiveBlending: AdditiveBlending, - SubtractiveBlending: SubtractiveBlending, - MultiplyBlending: MultiplyBlending, - CustomBlending: CustomBlending - }; - - var _color = new Color(); - var _textureLoader = new TextureLoader(); - var _materialLoader = new MaterialLoader(); - - function Loader() {} - - Loader.Handlers = { - - handlers: [], - - add: function ( regex, loader ) { - - this.handlers.push( regex, loader ); - - }, - - get: function ( file ) { - - var handlers = this.handlers; - - for ( var i = 0, l = handlers.length; i < l; i += 2 ) { - - var regex = handlers[ i ]; - var loader = handlers[ i + 1 ]; - - if ( regex.test( file ) ) { - - return loader; - - } - - } - - return null; - - } - - }; - - Object.assign( Loader.prototype, { - - crossOrigin: 'anonymous', - - onLoadStart: function () {}, - - onLoadProgress: function () {}, - - onLoadComplete: function () {}, - - initMaterials: function ( materials, texturePath, crossOrigin ) { - - var array = []; - - for ( var i = 0; i < materials.length; ++ i ) { - - array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin ); - - } - - return array; - - }, - - createMaterial: function ( m, texturePath, crossOrigin ) { - - // convert from old material format - - var textures = {}; - - // - - var json = { - uuid: _Math.generateUUID(), - type: 'MeshLambertMaterial' - }; - - for ( var name in m ) { - - var value = m[ name ]; - - switch ( name ) { - - case 'DbgColor': - case 'DbgIndex': - case 'opticalDensity': - case 'illumination': - break; - case 'DbgName': - json.name = value; - break; - case 'blending': - json.blending = _BlendingMode[ value ]; - break; - case 'colorAmbient': - case 'mapAmbient': - console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); - break; - case 'colorDiffuse': - json.color = _color.fromArray( value ).getHex(); - break; - case 'colorSpecular': - json.specular = _color.fromArray( value ).getHex(); - break; - case 'colorEmissive': - json.emissive = _color.fromArray( value ).getHex(); - break; - case 'specularCoef': - json.shininess = value; - break; - case 'shading': - if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial'; - if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial'; - if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial'; - break; - case 'mapDiffuse': - json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapDiffuseRepeat': - case 'mapDiffuseOffset': - case 'mapDiffuseWrap': - case 'mapDiffuseAnisotropy': - break; - case 'mapEmissive': - json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapEmissiveRepeat': - case 'mapEmissiveOffset': - case 'mapEmissiveWrap': - case 'mapEmissiveAnisotropy': - break; - case 'mapLight': - json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapLightRepeat': - case 'mapLightOffset': - case 'mapLightWrap': - case 'mapLightAnisotropy': - break; - case 'mapAO': - json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapAORepeat': - case 'mapAOOffset': - case 'mapAOWrap': - case 'mapAOAnisotropy': - break; - case 'mapBump': - json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapBumpScale': - json.bumpScale = value; - break; - case 'mapBumpRepeat': - case 'mapBumpOffset': - case 'mapBumpWrap': - case 'mapBumpAnisotropy': - break; - case 'mapNormal': - json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapNormalFactor': - json.normalScale = value; - break; - case 'mapNormalRepeat': - case 'mapNormalOffset': - case 'mapNormalWrap': - case 'mapNormalAnisotropy': - break; - case 'mapSpecular': - json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapSpecularRepeat': - case 'mapSpecularOffset': - case 'mapSpecularWrap': - case 'mapSpecularAnisotropy': - break; - case 'mapMetalness': - json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapMetalnessRepeat': - case 'mapMetalnessOffset': - case 'mapMetalnessWrap': - case 'mapMetalnessAnisotropy': - break; - case 'mapRoughness': - json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapRoughnessRepeat': - case 'mapRoughnessOffset': - case 'mapRoughnessWrap': - case 'mapRoughnessAnisotropy': - break; - case 'mapAlpha': - json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapAlphaRepeat': - case 'mapAlphaOffset': - case 'mapAlphaWrap': - case 'mapAlphaAnisotropy': - break; - case 'flipSided': - json.side = BackSide; - break; - case 'doubleSided': - json.side = DoubleSide; - break; - case 'transparency': - console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' ); - json.opacity = value; - break; - case 'depthTest': - case 'depthWrite': - case 'colorWrite': - case 'opacity': - case 'reflectivity': - case 'transparent': - case 'visible': - case 'wireframe': - json[ name ] = value; - break; - case 'vertexColors': - if ( value === true ) json.vertexColors = VertexColors; - if ( value === 'face' ) json.vertexColors = FaceColors; - break; - default: - console.error( 'THREE.Loader.createMaterial: Unsupported', name, value ); - break; - - } - - } - - if ( json.type === 'MeshBasicMaterial' ) delete json.emissive; - if ( json.type !== 'MeshPhongMaterial' ) delete json.specular; - - if ( json.opacity < 1 ) json.transparent = true; - - _materialLoader.setTextures( textures ); - - return _materialLoader.parse( json ); - } } ); - function loadTexture( path, repeat, offset, wrap, anisotropy, textures, texturePath, crossOrigin ) { - - var fullPath = texturePath + path; - var loader = Loader.Handlers.get( fullPath ); - - var texture; - - if ( loader !== null ) { - - texture = loader.load( fullPath ); - - } else { - - _textureLoader.setCrossOrigin( crossOrigin ); - texture = _textureLoader.load( fullPath ); - - } - - if ( repeat !== undefined ) { - - texture.repeat.fromArray( repeat ); - - if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping; - if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping; - - } - - if ( offset !== undefined ) { - - texture.offset.fromArray( offset ); - - } - - if ( wrap !== undefined ) { - - if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping; - if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping; - - if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping; - if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping; - - } - - if ( anisotropy !== undefined ) { - - texture.anisotropy = anisotropy; - - } - - var uuid = _Math.generateUUID(); - - textures[ uuid ] = texture; - - return uuid; - - } - /** * @author mrdoob / http://mrdoob.com/ */ @@ -40317,11 +41232,13 @@ function AudioLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } - Object.assign( AudioLoader.prototype, { + AudioLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: AudioLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -40343,13 +41260,6 @@ }, onProgress, onError ); - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -40531,13 +41441,15 @@ }, - fromArray: function ( array ) { + fromArray: function ( array, offset ) { + + if ( offset === undefined ) { offset = 0; } var coefficients = this.coefficients; for ( var i = 0; i < 9; i ++ ) { - coefficients[ i ].fromArray( array, i * 3 ); + coefficients[ i ].fromArray( array, offset + ( i * 3 ) ); } @@ -40545,14 +41457,16 @@ }, - toArray: function () { + toArray: function ( array, offset ) { + + if ( array === undefined ) { array = []; } + if ( offset === undefined ) { offset = 0; } - var array = []; var coefficients = this.coefficients; for ( var i = 0; i < 9; i ++ ) { - coefficients[ i ].toArray( array, i * 3 ); + coefficients[ i ].toArray( array, offset + ( i * 3 ) ); } @@ -40785,7 +41699,7 @@ var projectionMatrix = camera.projectionMatrix.clone(); var eyeSepHalf = cache.eyeSep / 2; var eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; - var ymax = ( cache.near * Math.tan( _Math.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom; + var ymax = ( cache.near * Math.tan( MathUtils.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom; var xmin, xmax; // translate xOffset @@ -41051,13 +41965,18 @@ this.buffer = null; this.detune = 0; this.loop = false; - this.startTime = 0; + this.loopStart = 0; + this.loopEnd = 0; this.offset = 0; + this.duration = undefined; this.playbackRate = 1; this.isPlaying = false; this.hasPlaybackControl = true; this.sourceType = 'empty'; + this._startedAt = 0; + this._pausedAt = 0; + this.filters = []; } @@ -41094,18 +42013,31 @@ }, + setMediaStreamSource: function ( mediaStream ) { + + this.hasPlaybackControl = false; + this.sourceType = 'mediaStreamNode'; + this.source = this.context.createMediaStreamSource( mediaStream ); + this.connect(); + + return this; + + }, + setBuffer: function ( audioBuffer ) { this.buffer = audioBuffer; this.sourceType = 'buffer'; - if ( this.autoplay ) this.play(); + if ( this.autoplay ) { this.play(); } return this; }, - play: function () { + play: function ( delay ) { + + if ( delay === undefined ) { delay = 0; } if ( this.isPlaying === true ) { @@ -41121,13 +42053,15 @@ } - var source = this.context.createBufferSource(); + this._startedAt = this.context.currentTime + delay; + var source = this.context.createBufferSource(); source.buffer = this.buffer; source.loop = this.loop; + source.loopStart = this.loopStart; + source.loopEnd = this.loopEnd; source.onended = this.onEnded.bind( this ); - this.startTime = this.context.currentTime; - source.start( this.startTime, this.offset ); + source.start( this._startedAt, this._pausedAt + this.offset, this.duration ); this.isPlaying = true; @@ -41151,9 +42085,11 @@ if ( this.isPlaying === true ) { + this._pausedAt += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate; + this.source.stop(); this.source.onended = null; - this.offset += ( this.context.currentTime - this.startTime ) * this.playbackRate; + this.isPlaying = false; } @@ -41171,9 +42107,10 @@ } + this._pausedAt = 0; + this.source.stop(); this.source.onended = null; - this.offset = 0; this.isPlaying = false; return this; @@ -41236,7 +42173,7 @@ setFilters: function ( value ) { - if ( ! value ) value = []; + if ( ! value ) { value = []; } if ( this.isPlaying === true ) { @@ -41258,7 +42195,7 @@ this.detune = value; - if ( this.source.detune === undefined ) return; // only set detune when available + if ( this.source.detune === undefined ) { return; } // only set detune when available if ( this.isPlaying === true ) { @@ -41355,6 +42292,22 @@ }, + setLoopStart: function ( value ) { + + this.loopStart = value; + + return this; + + }, + + setLoopEnd: function ( value ) { + + this.loopEnd = value; + + return this; + + }, + getVolume: function () { return this.gain.gain.value; @@ -41470,7 +42423,7 @@ Object3D.prototype.updateMatrixWorld.call( this, force ); - if ( this.hasPlaybackControl === true && this.isPlaying === false ) return; + if ( this.hasPlaybackControl === true && this.isPlaying === false ) { return; } this.matrixWorld.decompose( _position$3, _quaternion$4, _scale$2 ); @@ -41813,7 +42766,7 @@ binding = this._bindings[ firstValidIndex ]; // and only call .getValue on the first - if ( binding !== undefined ) binding.getValue( array, offset ); + if ( binding !== undefined ) { binding.getValue( array, offset ); } }, @@ -41948,7 +42901,7 @@ findNode: function ( root, nodeName ) { - if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { + if ( ! nodeName || nodeName === "" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { return root; @@ -41984,7 +42937,7 @@ var result = searchNodeSubtree( childNode.children ); - if ( result ) return result; + if ( result ) { return result; } } @@ -42494,7 +43447,7 @@ function AnimationObjectGroup() { - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); // cached objects followed by the active ones this._objects = Array.prototype.slice.call( arguments ); @@ -42775,7 +43728,7 @@ index = indicesByPath[ path ], bindings = this._bindings; - if ( index !== undefined ) return bindings[ index ]; + if ( index !== undefined ) { return bindings[ index ]; } var paths = this._paths, parsedPaths = this._parsedPaths, @@ -43313,7 +44266,7 @@ if ( deltaTime === 0 ) { - if ( loopCount === - 1 ) return time; + if ( loopCount === - 1 ) { return time; } return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time; @@ -43348,8 +44301,8 @@ } - if ( this.clampWhenFinished ) this.paused = true; - else this.enabled = false; + if ( this.clampWhenFinished ) { this.paused = true; } + else { this.enabled = false; } this.time = time; @@ -43399,8 +44352,8 @@ // have to stop (switch state, clamp time, fire event) - if ( this.clampWhenFinished ) this.paused = true; - else this.enabled = false; + if ( this.clampWhenFinished ) { this.paused = true; } + else { this.enabled = false; } time = deltaTime > 0 ? duration : 0; @@ -44062,12 +45015,12 @@ // also, take the clip from the prototype action if ( clipObject === null ) - clipObject = prototypeAction._clip; + { clipObject = prototypeAction._clip; } } // clip must be known when specified via string - if ( clipObject === null ) return null; + if ( clipObject === null ) { return null; } // allocate all resources required to run it var newAction = new AnimationAction( this, clipObject, optionalRoot ); @@ -44169,6 +45122,20 @@ }, + // Allows you to seek to a specific time in an animation. + setTime: function ( timeInSeconds ) { + + this.time = 0; // Zero out time attribute for AnimationMixer object; + for ( var i = 0; i < this._actions.length; i ++ ) { + + this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects. + + } + + return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object. + + }, + // return this mixer's root target object getRoot: function () { @@ -44338,10 +45305,11 @@ this.near = near || 0; this.far = far || Infinity; this.camera = null; + this.layers = new Layers(); this.params = { Mesh: {}, - Line: {}, + Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} @@ -44368,9 +45336,11 @@ function intersectObject( object, raycaster, intersects, recursive ) { - if ( object.visible === false ) return; + if ( object.layers.test( raycaster.layers ) ) { + + object.raycast( raycaster, intersects ); - object.raycast( raycaster, intersects ); + } if ( recursive === true ) { @@ -44388,8 +45358,6 @@ Object.assign( Raycaster.prototype, { - linePrecision: 1, - set: function ( origin, direction ) { // direction is assumed to be normalized (for accurate distance calculations) @@ -44464,7 +45432,7 @@ * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system * * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. - * The azimuthal angle (theta) is measured from the positive z-axiz. + * The azimuthal angle (theta) is measured from the positive z-axis. */ function Spherical( radius, phi, theta ) { @@ -44533,7 +45501,7 @@ } else { this.theta = Math.atan2( x, z ); - this.phi = Math.acos( _Math.clamp( y / this.radius, - 1, 1 ) ); + this.phi = Math.acos( MathUtils.clamp( y / this.radius, - 1, 1 ) ); } @@ -44610,7 +45578,7 @@ * @author bhouston / http://clara.io */ - var _vector$6 = new Vector2(); + var _vector$7 = new Vector2(); function Box2( min, max ) { @@ -44646,7 +45614,7 @@ setFromCenterAndSize: function ( center, size ) { - var halfSize = _vector$6.copy( size ).multiplyScalar( 0.5 ); + var halfSize = _vector$7.copy( size ).multiplyScalar( 0.5 ); this.min.copy( center ).sub( halfSize ); this.max.copy( center ).add( halfSize ); @@ -44796,7 +45764,7 @@ distanceToPoint: function ( point ) { - var clampedPoint = _vector$6.copy( point ).clamp( this.min, this.max ); + var clampedPoint = _vector$7.copy( point ).clamp( this.min, this.max ); return clampedPoint.sub( point ).length(); }, @@ -44939,7 +45907,7 @@ if ( clampToLine ) { - t = _Math.clamp( t, 0, 1 ); + t = MathUtils.clamp( t, 0, 1 ); } @@ -44997,152 +45965,13 @@ ImmediateRenderObject.prototype.isImmediateRenderObject = true; - /** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ - - var _v1$5 = new Vector3(); - var _v2$3 = new Vector3(); - var _normalMatrix$1 = new Matrix3(); - var _keys = [ 'a', 'b', 'c' ]; - - function VertexNormalsHelper( object, size, hex, linewidth ) { - - this.object = object; - - this.size = ( size !== undefined ) ? size : 1; - - var color = ( hex !== undefined ) ? hex : 0xff0000; - - var width = ( linewidth !== undefined ) ? linewidth : 1; - - // - - var nNormals = 0; - - var objGeometry = this.object.geometry; - - if ( objGeometry && objGeometry.isGeometry ) { - - nNormals = objGeometry.faces.length * 3; - - } else if ( objGeometry && objGeometry.isBufferGeometry ) { - - nNormals = objGeometry.attributes.normal.count; - - } - - // - - var geometry = new BufferGeometry(); - - var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); - - geometry.addAttribute( 'position', positions ); - - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); - - // - - this.matrixAutoUpdate = false; - - this.update(); - - } - - VertexNormalsHelper.prototype = Object.create( LineSegments.prototype ); - VertexNormalsHelper.prototype.constructor = VertexNormalsHelper; - - VertexNormalsHelper.prototype.update = function () { - - this.object.updateMatrixWorld( true ); - - _normalMatrix$1.getNormalMatrix( this.object.matrixWorld ); - - var matrixWorld = this.object.matrixWorld; - - var position = this.geometry.attributes.position; - - // - - var objGeometry = this.object.geometry; - - if ( objGeometry && objGeometry.isGeometry ) { - - var vertices = objGeometry.vertices; - - var faces = objGeometry.faces; - - var idx = 0; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - - var vertex = vertices[ face[ _keys[ j ] ] ]; - - var normal = face.vertexNormals[ j ]; - - _v1$5.copy( vertex ).applyMatrix4( matrixWorld ); - - _v2$3.copy( normal ).applyMatrix3( _normalMatrix$1 ).normalize().multiplyScalar( this.size ).add( _v1$5 ); - - position.setXYZ( idx, _v1$5.x, _v1$5.y, _v1$5.z ); - - idx = idx + 1; - - position.setXYZ( idx, _v2$3.x, _v2$3.y, _v2$3.z ); - - idx = idx + 1; - - } - - } - - } else if ( objGeometry && objGeometry.isBufferGeometry ) { - - var objPos = objGeometry.attributes.position; - - var objNorm = objGeometry.attributes.normal; - - var idx = 0; - - // for simplicity, ignore index and drawcalls, and render every normal - - for ( var j = 0, jl = objPos.count; j < jl; j ++ ) { - - _v1$5.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld ); - - _v2$3.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) ); - - _v2$3.applyMatrix3( _normalMatrix$1 ).normalize().multiplyScalar( this.size ).add( _v1$5 ); - - position.setXYZ( idx, _v1$5.x, _v1$5.y, _v1$5.z ); - - idx = idx + 1; - - position.setXYZ( idx, _v2$3.x, _v2$3.y, _v2$3.z ); - - idx = idx + 1; - - } - - } - - position.needsUpdate = true; - - }; - /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ * @author WestLangley / http://github.com/WestLangley */ - var _vector$7 = new Vector3(); + var _vector$8 = new Vector3(); function SpotLightHelper( light, color ) { @@ -45178,7 +46007,7 @@ } - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); var material = new LineBasicMaterial( { fog: false } ); @@ -45208,9 +46037,9 @@ this.cone.scale.set( coneWidth, coneWidth, coneLength ); - _vector$7.setFromMatrixPosition( this.light.target.matrixWorld ); + _vector$8.setFromMatrixPosition( this.light.target.matrixWorld ); - this.cone.lookAt( _vector$7 ); + this.cone.lookAt( _vector$8 ); if ( this.color !== undefined ) { @@ -45232,7 +46061,7 @@ * @author Mugen87 / https://github.com/Mugen87 */ - var _vector$8 = new Vector3(); + var _vector$9 = new Vector3(); var _boneMatrix = new Matrix4(); var _matrixWorldInv = new Matrix4(); @@ -45283,10 +46112,10 @@ } - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } ); + var material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, transparent: true } ); LineSegments.call( this, geometry, material ); @@ -45301,6 +46130,8 @@ SkeletonHelper.prototype = Object.create( LineSegments.prototype ); SkeletonHelper.prototype.constructor = SkeletonHelper; + SkeletonHelper.prototype.isSkeletonHelper = true; + SkeletonHelper.prototype.updateMatrixWorld = function ( force ) { var bones = this.bones; @@ -45317,12 +46148,12 @@ if ( bone.parent && bone.parent.isBone ) { _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld ); - _vector$8.setFromMatrixPosition( _boneMatrix ); - position.setXYZ( j, _vector$8.x, _vector$8.y, _vector$8.z ); + _vector$9.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j, _vector$9.x, _vector$9.y, _vector$9.z ); _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld ); - _vector$8.setFromMatrixPosition( _boneMatrix ); - position.setXYZ( j + 1, _vector$8.x, _vector$8.y, _vector$8.z ); + _vector$9.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j + 1, _vector$9.x, _vector$9.y, _vector$9.z ); j += 2; @@ -45422,89 +46253,13 @@ }; - /** - * @author abelnation / http://github.com/abelnation - * @author Mugen87 / http://github.com/Mugen87 - * @author WestLangley / http://github.com/WestLangley - * - * This helper must be added as a child of the light - */ - - function RectAreaLightHelper( light, color ) { - - this.type = 'RectAreaLightHelper'; - - this.light = light; - - this.color = color; // optional hardwired color for the helper - - var positions = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ]; - - var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); - geometry.computeBoundingSphere(); - - var material = new LineBasicMaterial( { fog: false } ); - - Line.call( this, geometry, material ); - - // - - var positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ]; - - var geometry2 = new BufferGeometry(); - geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); - geometry2.computeBoundingSphere(); - - this.add( new Mesh( geometry2, new MeshBasicMaterial( { side: BackSide, fog: false } ) ) ); - - this.update(); - - } - - RectAreaLightHelper.prototype = Object.create( Line.prototype ); - RectAreaLightHelper.prototype.constructor = RectAreaLightHelper; - - RectAreaLightHelper.prototype.update = function () { - - this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 ); - - if ( this.color !== undefined ) { - - this.material.color.set( this.color ); - this.children[ 0 ].material.color.set( this.color ); - - } else { - - this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - // prevent hue shift - var c = this.material.color; - var max = Math.max( c.r, c.g, c.b ); - if ( max > 1 ) c.multiplyScalar( 1 / max ); - - this.children[ 0 ].material.color.copy( this.material.color ); - - } - - }; - - RectAreaLightHelper.prototype.dispose = function () { - - this.geometry.dispose(); - this.material.dispose(); - this.children[ 0 ].geometry.dispose(); - this.children[ 0 ].material.dispose(); - - }; - /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ * @author Mugen87 / https://github.com/Mugen87 */ - var _vector$9 = new Vector3(); + var _vector$a = new Vector3(); var _color1 = new Color(); var _color2 = new Color(); @@ -45524,12 +46279,12 @@ geometry.rotateY( Math.PI * 0.5 ); this.material = new MeshBasicMaterial( { wireframe: true, fog: false } ); - if ( this.color === undefined ) this.material.vertexColors = VertexColors; + if ( this.color === undefined ) { this.material.vertexColors = true; } var position = geometry.getAttribute( 'position' ); var colors = new Float32Array( position.count * 3 ); - geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) ); this.add( new Mesh( geometry, this.material ) ); @@ -45574,153 +46329,7 @@ } - mesh.lookAt( _vector$9.setFromMatrixPosition( this.light.matrixWorld ).negate() ); - - }; - - /** - * @author WestLangley / http://github.com/WestLangley - */ - - function LightProbeHelper( lightProbe, size ) { - - this.lightProbe = lightProbe; - - this.size = size; - - var defines = {}; - defines[ 'GAMMA_OUTPUT' ] = ""; - - // material - var material = new ShaderMaterial( { - - defines: defines, - - uniforms: { - - sh: { value: this.lightProbe.sh.coefficients }, // by reference - - intensity: { value: this.lightProbe.intensity } - - }, - - vertexShader: [ - - 'varying vec3 vNormal;', - - 'void main() {', - - ' vNormal = normalize( normalMatrix * normal );', - - ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', - - '}', - - ].join( '\n' ), - - fragmentShader: [ - - '#define RECIPROCAL_PI 0.318309886', - - 'vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {', - - ' // matrix is assumed to be orthogonal', - - ' return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );', - - '}', - - 'vec3 linearToOutput( in vec3 a ) {', - - ' #ifdef GAMMA_OUTPUT', - - ' return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );', - - ' #else', - - ' return a;', - - ' #endif', - - '}', - - '// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf', - 'vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {', - - ' // normal is assumed to have unit length', - - ' float x = normal.x, y = normal.y, z = normal.z;', - - ' // band 0', - ' vec3 result = shCoefficients[ 0 ] * 0.886227;', - - ' // band 1', - ' result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;', - ' result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;', - ' result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;', - - ' // band 2', - ' result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;', - ' result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;', - ' result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );', - ' result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;', - ' result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );', - - ' return result;', - - '}', - - 'uniform vec3 sh[ 9 ]; // sh coefficients', - - 'uniform float intensity; // light probe intensity', - - 'varying vec3 vNormal;', - - 'void main() {', - - ' vec3 normal = normalize( vNormal );', - - ' vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );', - - ' vec3 irradiance = shGetIrradianceAt( worldNormal, sh );', - - ' vec3 outgoingLight = RECIPROCAL_PI * irradiance * intensity;', - - ' outgoingLight = linearToOutput( outgoingLight );', - - ' gl_FragColor = vec4( outgoingLight, 1.0 );', - - '}' - - ].join( '\n' ) - - } ); - - var geometry = new SphereBufferGeometry( 1, 32, 16 ); - - Mesh.call( this, geometry, material ); - - this.onBeforeRender(); - - } - - LightProbeHelper.prototype = Object.create( Mesh.prototype ); - LightProbeHelper.prototype.constructor = LightProbeHelper; - - LightProbeHelper.prototype.dispose = function () { - - this.geometry.dispose(); - this.material.dispose(); - - }; - - LightProbeHelper.prototype.onBeforeRender = function () { - - this.position.copy( this.lightProbe.position ); - - this.scale.set( 1, 1, 1 ).multiplyScalar( this.size ); - - this.material.uniforms.intensity.value = this.lightProbe.intensity; + mesh.lookAt( _vector$a.setFromMatrixPosition( this.light.matrixWorld ).negate() ); }; @@ -45756,10 +46365,10 @@ } var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: true } ); LineSegments.call( this, geometry, material ); @@ -45863,10 +46472,10 @@ } var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: true } ); LineSegments.call( this, geometry, material ); @@ -45875,219 +46484,14 @@ PolarGridHelper.prototype = Object.create( LineSegments.prototype ); PolarGridHelper.prototype.constructor = PolarGridHelper; - /** - * @author Mugen87 / http://github.com/Mugen87 - */ - - function PositionalAudioHelper( audio, range, divisionsInnerAngle, divisionsOuterAngle ) { - - this.audio = audio; - this.range = range || 1; - this.divisionsInnerAngle = divisionsInnerAngle || 16; - this.divisionsOuterAngle = divisionsOuterAngle || 2; - - var geometry = new BufferGeometry(); - var divisions = this.divisionsInnerAngle + this.divisionsOuterAngle * 2; - var positions = new Float32Array( ( divisions * 3 + 3 ) * 3 ); - geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); - - var materialInnerAngle = new LineBasicMaterial( { color: 0x00ff00 } ); - var materialOuterAngle = new LineBasicMaterial( { color: 0xffff00 } ); - - Line.call( this, geometry, [ materialOuterAngle, materialInnerAngle ] ); - - this.update(); - - } - - PositionalAudioHelper.prototype = Object.create( Line.prototype ); - PositionalAudioHelper.prototype.constructor = PositionalAudioHelper; - - PositionalAudioHelper.prototype.update = function () { - - var audio = this.audio; - var range = this.range; - var divisionsInnerAngle = this.divisionsInnerAngle; - var divisionsOuterAngle = this.divisionsOuterAngle; - - var coneInnerAngle = _Math.degToRad( audio.panner.coneInnerAngle ); - var coneOuterAngle = _Math.degToRad( audio.panner.coneOuterAngle ); - - var halfConeInnerAngle = coneInnerAngle / 2; - var halfConeOuterAngle = coneOuterAngle / 2; - - var start = 0; - var count = 0; - var i, stride; - - var geometry = this.geometry; - var positionAttribute = geometry.attributes.position; - - geometry.clearGroups(); - - // - - function generateSegment( from, to, divisions, materialIndex ) { - - var step = ( to - from ) / divisions; - - positionAttribute.setXYZ( start, 0, 0, 0 ); - count ++; - - for ( i = from; i < to; i += step ) { - - stride = start + count; - - positionAttribute.setXYZ( stride, Math.sin( i ) * range, 0, Math.cos( i ) * range ); - positionAttribute.setXYZ( stride + 1, Math.sin( Math.min( i + step, to ) ) * range, 0, Math.cos( Math.min( i + step, to ) ) * range ); - positionAttribute.setXYZ( stride + 2, 0, 0, 0 ); - - count += 3; - - } - - geometry.addGroup( start, count, materialIndex ); - - start += count; - count = 0; - - } - - // - - generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 ); - generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 ); - generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 ); - - // - - positionAttribute.needsUpdate = true; - - if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false; - - }; - - PositionalAudioHelper.prototype.dispose = function () { - - this.geometry.dispose(); - this.material[ 0 ].dispose(); - this.material[ 1 ].dispose(); - - }; - - /** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ - - var _v1$6 = new Vector3(); - var _v2$4 = new Vector3(); - var _normalMatrix$2 = new Matrix3(); - - function FaceNormalsHelper( object, size, hex, linewidth ) { - - // FaceNormalsHelper only supports THREE.Geometry - - this.object = object; - - this.size = ( size !== undefined ) ? size : 1; - - var color = ( hex !== undefined ) ? hex : 0xffff00; - - var width = ( linewidth !== undefined ) ? linewidth : 1; - - // - - var nNormals = 0; - - var objGeometry = this.object.geometry; - - if ( objGeometry && objGeometry.isGeometry ) { - - nNormals = objGeometry.faces.length; - - } else { - - console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' ); - - } - - // - - var geometry = new BufferGeometry(); - - var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); - - geometry.addAttribute( 'position', positions ); - - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); - - // - - this.matrixAutoUpdate = false; - this.update(); - - } - - FaceNormalsHelper.prototype = Object.create( LineSegments.prototype ); - FaceNormalsHelper.prototype.constructor = FaceNormalsHelper; - - FaceNormalsHelper.prototype.update = function () { - - this.object.updateMatrixWorld( true ); - - _normalMatrix$2.getNormalMatrix( this.object.matrixWorld ); - - var matrixWorld = this.object.matrixWorld; - - var position = this.geometry.attributes.position; - - // - - var objGeometry = this.object.geometry; - - var vertices = objGeometry.vertices; - - var faces = objGeometry.faces; - - var idx = 0; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - var normal = face.normal; - - _v1$6.copy( vertices[ face.a ] ) - .add( vertices[ face.b ] ) - .add( vertices[ face.c ] ) - .divideScalar( 3 ) - .applyMatrix4( matrixWorld ); - - _v2$4.copy( normal ).applyMatrix3( _normalMatrix$2 ).normalize().multiplyScalar( this.size ).add( _v1$6 ); - - position.setXYZ( idx, _v1$6.x, _v1$6.y, _v1$6.z ); - - idx = idx + 1; - - position.setXYZ( idx, _v2$4.x, _v2$4.y, _v2$4.z ); - - idx = idx + 1; - - } - - position.needsUpdate = true; - - }; - /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ * @author WestLangley / http://github.com/WestLangley */ - var _v1$7 = new Vector3(); - var _v2$5 = new Vector3(); + var _v1$5 = new Vector3(); + var _v2$3 = new Vector3(); var _v3$1 = new Vector3(); function DirectionalLightHelper( light, size, color ) { @@ -46102,10 +46506,10 @@ this.color = color; - if ( size === undefined ) size = 1; + if ( size === undefined ) { size = 1; } var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( [ + geometry.setAttribute( 'position', new Float32BufferAttribute( [ - size, size, 0, size, size, 0, size, - size, 0, @@ -46119,7 +46523,7 @@ this.add( this.lightPlane ); geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); this.targetLine = new Line( geometry, material ); this.add( this.targetLine ); @@ -46142,11 +46546,11 @@ DirectionalLightHelper.prototype.update = function () { - _v1$7.setFromMatrixPosition( this.light.matrixWorld ); - _v2$5.setFromMatrixPosition( this.light.target.matrixWorld ); - _v3$1.subVectors( _v2$5, _v1$7 ); + _v1$5.setFromMatrixPosition( this.light.matrixWorld ); + _v2$3.setFromMatrixPosition( this.light.target.matrixWorld ); + _v3$1.subVectors( _v2$3, _v1$5 ); - this.lightPlane.lookAt( _v2$5 ); + this.lightPlane.lookAt( _v2$3 ); if ( this.color !== undefined ) { @@ -46160,7 +46564,7 @@ } - this.targetLine.lookAt( _v2$5 ); + this.targetLine.lookAt( _v2$3 ); this.targetLine.scale.z = _v3$1.length(); }; @@ -46175,13 +46579,13 @@ * http://evanw.github.com/lightgl.js/tests/shadowmap.html */ - var _vector$a = new Vector3(); + var _vector$b = new Vector3(); var _camera = new Camera(); function CameraHelper( camera ) { var geometry = new BufferGeometry(); - var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } ); + var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true } ); var vertices = []; var colors = []; @@ -46265,13 +46669,13 @@ } - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); LineSegments.call( this, geometry, material ); this.camera = camera; - if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix(); + if ( this.camera.updateProjectionMatrix ) { this.camera.updateProjectionMatrix(); } this.matrix = camera.matrixWorld; this.matrixAutoUpdate = false; @@ -46340,7 +46744,7 @@ function setPoint( point, pointMap, geometry, camera, x, y, z ) { - _vector$a.set( x, y, z ).unproject( camera ); + _vector$b.set( x, y, z ).unproject( camera ); var points = pointMap[ point ]; @@ -46350,7 +46754,7 @@ for ( var i = 0, l = points.length; i < l; i ++ ) { - position.setXYZ( points[ i ], _vector$a.x, _vector$a.y, _vector$a.z ); + position.setXYZ( points[ i ], _vector$b.x, _vector$b.y, _vector$b.z ); } @@ -46363,20 +46767,20 @@ * @author Mugen87 / http://github.com/Mugen87 */ - var _box$2 = new Box3(); + var _box$3 = new Box3(); function BoxHelper( object, color ) { this.object = object; - if ( color === undefined ) color = 0xffff00; + if ( color === undefined ) { color = 0xffff00; } var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] ); var positions = new Float32Array( 8 * 3 ); var geometry = new BufferGeometry(); geometry.setIndex( new BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) ); LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); @@ -46399,14 +46803,14 @@ if ( this.object !== undefined ) { - _box$2.setFromObject( this.object ); + _box$3.setFromObject( this.object ); } - if ( _box$2.isEmpty() ) return; + if ( _box$3.isEmpty() ) { return; } - var min = _box$2.min; - var max = _box$2.max; + var min = _box$3.min; + var max = _box$3.max; /* 5____4 @@ -46488,7 +46892,7 @@ geometry.setIndex( new BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); @@ -46503,7 +46907,7 @@ var box = this.box; - if ( box.isEmpty() ) return; + if ( box.isEmpty() ) { return; } box.getCenter( this.position ); @@ -46532,7 +46936,7 @@ var positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ]; var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); geometry.computeBoundingSphere(); Line.call( this, geometry, new LineBasicMaterial( { color: color } ) ); @@ -46542,7 +46946,7 @@ var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ]; var geometry2 = new BufferGeometry(); - geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); + geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); geometry2.computeBoundingSphere(); this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false } ) ) ); @@ -46556,7 +46960,7 @@ var scale = - this.plane.constant; - if ( Math.abs( scale ) < 1e-8 ) scale = 1e-8; // sign does not matter + if ( Math.abs( scale ) < 1e-8 ) { scale = 1e-8; } // sign does not matter this.scale.set( 0.5 * this.size, 0.5 * this.size, scale ); @@ -46593,17 +46997,17 @@ Object3D.call( this ); - if ( dir === undefined ) dir = new Vector3( 0, 0, 1 ); - if ( origin === undefined ) origin = new Vector3( 0, 0, 0 ); - if ( length === undefined ) length = 1; - if ( color === undefined ) color = 0xffff00; - if ( headLength === undefined ) headLength = 0.2 * length; - if ( headWidth === undefined ) headWidth = 0.2 * headLength; + if ( dir === undefined ) { dir = new Vector3( 0, 0, 1 ); } + if ( origin === undefined ) { origin = new Vector3( 0, 0, 0 ); } + if ( length === undefined ) { length = 1; } + if ( color === undefined ) { color = 0xffff00; } + if ( headLength === undefined ) { headLength = 0.2 * length; } + if ( headWidth === undefined ) { headWidth = 0.2 * headLength; } if ( _lineGeometry === undefined ) { _lineGeometry = new BufferGeometry(); - _lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); + _lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); _coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); _coneGeometry.translate( 0, - 0.5, 0 ); @@ -46654,10 +47058,10 @@ ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { - if ( headLength === undefined ) headLength = 0.2 * length; - if ( headWidth === undefined ) headWidth = 0.2 * headLength; + if ( headLength === undefined ) { headLength = 0.2 * length; } + if ( headWidth === undefined ) { headWidth = 0.2 * headLength; } - this.line.scale.set( 1, Math.max( 0, length - headLength ), 1 ); + this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458 this.line.updateMatrix(); this.cone.scale.set( headWidth, headLength, headWidth ); @@ -46712,10 +47116,10 @@ ]; var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: true } ); LineSegments.call( this, geometry, material ); @@ -46724,6 +47128,659 @@ AxesHelper.prototype = Object.create( LineSegments.prototype ); AxesHelper.prototype.constructor = AxesHelper; + /** + * @author Emmett Lalish / elalish + * + * This class generates a Prefiltered, Mipmapped Radiance Environment Map + * (PMREM) from a cubeMap environment texture. This allows different levels of + * blur to be quickly accessed based on material roughness. It is packed into a + * special CubeUV format that allows us to perform custom interpolation so that + * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap + * chain, it only goes down to the LOD_MIN level (above), and then creates extra + * even more filtered 'mips' at the same LOD_MIN resolution, associated with + * higher roughness levels. In this way we maintain resolution to smoothly + * interpolate diffuse lighting while limiting sampling computation. + */ + + var LOD_MIN = 4; + var LOD_MAX = 8; + var SIZE_MAX = Math.pow( 2, LOD_MAX ); + // The standard deviations (radians) associated with the extra mips. These are + // chosen to approximate a Trowbridge-Reitz distribution function times the + // geometric shadowing function. These sigma values squared must match the + // variance #defines in cube_uv_reflection_fragment.glsl.js. + var EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ]; + var TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; + // The maximum length of the blur for loop. Smaller sigmas will use fewer + // samples and exit early, but not recompile the shader. + var MAX_SAMPLES = 20; + var ENCODINGS = {}; + ENCODINGS[ LinearEncoding ] = 0; + ENCODINGS[ sRGBEncoding ] = 1; + ENCODINGS[ RGBEEncoding ] = 2; + ENCODINGS[ RGBM7Encoding ] = 3; + ENCODINGS[ RGBM16Encoding ] = 4; + ENCODINGS[ RGBDEncoding ] = 5; + ENCODINGS[ GammaEncoding ] = 6; + + var _flatCamera = new OrthographicCamera(); + var _blurMaterial = _getBlurShader( MAX_SAMPLES ); + var _equirectShader = null; + var _cubemapShader = null; + + var ref = _createPlanes(); + var _lodPlanes = ref._lodPlanes; + var _sizeLods = ref._sizeLods; + var _sigmas = ref._sigmas; + var _pingPongRenderTarget = null; + var _renderer = null; + + var _oldTarget = null; + + // Golden Ratio + var PHI = ( 1 + Math.sqrt( 5 ) ) / 2; + var INV_PHI = 1 / PHI; + // Vertices of a dodecahedron (except the opposites, which represent the + // same axis), used as axis directions evenly spread on a sphere. + var _axisDirections = [ + new Vector3( 1, 1, 1 ), + new Vector3( - 1, 1, 1 ), + new Vector3( 1, 1, - 1 ), + new Vector3( - 1, 1, - 1 ), + new Vector3( 0, PHI, INV_PHI ), + new Vector3( 0, PHI, - INV_PHI ), + new Vector3( INV_PHI, 0, PHI ), + new Vector3( - INV_PHI, 0, PHI ), + new Vector3( PHI, INV_PHI, 0 ), + new Vector3( - PHI, INV_PHI, 0 ) ]; + + function PMREMGenerator( renderer ) { + + _renderer = renderer; + _compileMaterial( _blurMaterial ); + + } + + PMREMGenerator.prototype = { + + constructor: PMREMGenerator, + + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an + * image if networking bandwidth is low. Optional sigma specifies a blur radius + * in radians to be applied to the scene before PMREM generation. Optional near + * and far planes ensure the scene is rendered in its entirety (the cubeCamera + * is placed at the origin). + */ + fromScene: function ( scene, sigma, near, far ) { + if ( sigma === void 0 ) sigma = 0; + if ( near === void 0 ) near = 0.1; + if ( far === void 0 ) far = 100; + + + _oldTarget = _renderer.getRenderTarget(); + var cubeUVRenderTarget = _allocateTargets(); + _sceneToCubeUV( scene, near, far, cubeUVRenderTarget ); + if ( sigma > 0 ) { + + _blur( cubeUVRenderTarget, 0, 0, sigma ); + + } + _applyPMREM( cubeUVRenderTarget ); + _cleanup( cubeUVRenderTarget ); + + return cubeUVRenderTarget; + + }, + + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR + * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), + * as this matches best with the 256 x 256 cubemap output. + */ + fromEquirectangular: function ( equirectangular ) { + + equirectangular.magFilter = NearestFilter; + equirectangular.minFilter = NearestFilter; + equirectangular.generateMipmaps = false; + + return this.fromCubemap( equirectangular ); + + }, + + /** + * Generates a PMREM from an cubemap texture, which can be either LDR + * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, + * as this matches best with the 256 x 256 cubemap output. + */ + fromCubemap: function ( cubemap ) { + + _oldTarget = _renderer.getRenderTarget(); + var cubeUVRenderTarget = _allocateTargets( cubemap ); + _textureToCubeUV( cubemap, cubeUVRenderTarget ); + _applyPMREM( cubeUVRenderTarget ); + _cleanup( cubeUVRenderTarget ); + + return cubeUVRenderTarget; + + }, + + /** + * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + compileCubemapShader: function () { + + if ( _cubemapShader == null ) { + + _cubemapShader = _getCubemapShader(); + _compileMaterial( _cubemapShader ); + + } + + }, + + /** + * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + compileEquirectangularShader: function () { + + if ( _equirectShader == null ) { + + _equirectShader = _getEquirectShader(); + _compileMaterial( _equirectShader ); + + } + + }, + + /** + * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, + * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on + * one of them will cause any others to also become unusable. + */ + dispose: function () { + + _blurMaterial.dispose(); + + if ( _cubemapShader != null ) { _cubemapShader.dispose(); } + if ( _equirectShader != null ) { _equirectShader.dispose(); } + + for ( var i = 0; i < _lodPlanes.length; i ++ ) { + + _lodPlanes[ i ].dispose(); + + } + + }, + + }; + + function _createPlanes() { + + var _lodPlanes = []; + var _sizeLods = []; + var _sigmas = []; + + var lod = LOD_MAX; + for ( var i = 0; i < TOTAL_LODS; i ++ ) { + + var sizeLod = Math.pow( 2, lod ); + _sizeLods.push( sizeLod ); + var sigma = 1.0 / sizeLod; + if ( i > LOD_MAX - LOD_MIN ) { + + sigma = EXTRA_LOD_SIGMA[ i - LOD_MAX + LOD_MIN - 1 ]; + + } else if ( i == 0 ) { + + sigma = 0; + + } + _sigmas.push( sigma ); + + var texelSize = 1.0 / ( sizeLod - 1 ); + var min = - texelSize / 2; + var max = 1 + texelSize / 2; + var uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ]; + + var cubeFaces = 6; + var vertices = 6; + var positionSize = 3; + var uvSize = 2; + var faceIndexSize = 1; + + var position = new Float32Array( positionSize * vertices * cubeFaces ); + var uv = new Float32Array( uvSize * vertices * cubeFaces ); + var faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces ); + + for ( var face = 0; face < cubeFaces; face ++ ) { + + var x = ( face % 3 ) * 2 / 3 - 1; + var y = face > 2 ? 0 : - 1; + var coordinates = [ + x, y, 0, + x + 2 / 3, y, 0, + x + 2 / 3, y + 1, 0, + x, y, 0, + x + 2 / 3, y + 1, 0, + x, y + 1, 0 + ]; + position.set( coordinates, positionSize * vertices * face ); + uv.set( uv1, uvSize * vertices * face ); + var fill = [ face, face, face, face, face, face ]; + faceIndex.set( fill, faceIndexSize * vertices * face ); + + } + var planes = new BufferGeometry(); + planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) ); + planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) ); + planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) ); + _lodPlanes.push( planes ); + + if ( lod > LOD_MIN ) { + + lod --; + + } + + } + return { _lodPlanes: _lodPlanes, _sizeLods: _sizeLods, _sigmas: _sigmas }; + + } + + function _allocateTargets( equirectangular ) { + + var params = { + magFilter: NearestFilter, + minFilter: NearestFilter, + generateMipmaps: false, + type: equirectangular ? equirectangular.type : UnsignedByteType, + format: equirectangular ? equirectangular.format : RGBEFormat, + encoding: equirectangular ? equirectangular.encoding : RGBEEncoding, + depthBuffer: false, + stencilBuffer: false + }; + var cubeUVRenderTarget = _createRenderTarget( params ); + cubeUVRenderTarget.depthBuffer = equirectangular ? false : true; + _pingPongRenderTarget = _createRenderTarget( params ); + return cubeUVRenderTarget; + + } + + function _cleanup( outputTarget ) { + + _pingPongRenderTarget.dispose(); + _renderer.setRenderTarget( _oldTarget ); + outputTarget.scissorTest = false; + // reset viewport and scissor + outputTarget.setSize( outputTarget.width, outputTarget.height ); + + } + + function _sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) { + + var fov = 90; + var aspect = 1; + var cubeCamera = new PerspectiveCamera( fov, aspect, near, far ); + var upSign = [ 1, 1, 1, 1, - 1, 1 ]; + var forwardSign = [ 1, 1, - 1, - 1, - 1, 1 ]; + + var outputEncoding = _renderer.outputEncoding; + var toneMapping = _renderer.toneMapping; + var toneMappingExposure = _renderer.toneMappingExposure; + var clearColor = _renderer.getClearColor(); + var clearAlpha = _renderer.getClearAlpha(); + + _renderer.toneMapping = LinearToneMapping; + _renderer.toneMappingExposure = 1.0; + _renderer.outputEncoding = LinearEncoding; + scene.scale.z *= - 1; + + var background = scene.background; + if ( background && background.isColor ) { + + background.convertSRGBToLinear(); + // Convert linear to RGBE + var maxComponent = Math.max( background.r, background.g, background.b ); + var fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 ); + background = background.multiplyScalar( Math.pow( 2.0, - fExp ) ); + var alpha = ( fExp + 128.0 ) / 255.0; + _renderer.setClearColor( background, alpha ); + scene.background = null; + + } + + for ( var i = 0; i < 6; i ++ ) { + + var col = i % 3; + if ( col == 0 ) { + + cubeCamera.up.set( 0, upSign[ i ], 0 ); + cubeCamera.lookAt( forwardSign[ i ], 0, 0 ); + + } else if ( col == 1 ) { + + cubeCamera.up.set( 0, 0, upSign[ i ] ); + cubeCamera.lookAt( 0, forwardSign[ i ], 0 ); + + } else { + + cubeCamera.up.set( 0, upSign[ i ], 0 ); + cubeCamera.lookAt( 0, 0, forwardSign[ i ] ); + + } + _setViewport( cubeUVRenderTarget, + col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX ); + _renderer.setRenderTarget( cubeUVRenderTarget ); + _renderer.render( scene, cubeCamera ); + + } + + _renderer.toneMapping = toneMapping; + _renderer.toneMappingExposure = toneMappingExposure; + _renderer.outputEncoding = outputEncoding; + _renderer.setClearColor( clearColor, clearAlpha ); + scene.scale.z *= - 1; + + } + + function _textureToCubeUV( texture, cubeUVRenderTarget ) { + + var scene = new Scene(); + if ( texture.isCubeTexture ) { + + if ( _cubemapShader == null ) { + + _cubemapShader = _getCubemapShader(); + + } + + } else { + + if ( _equirectShader == null ) { + + _equirectShader = _getEquirectShader(); + + } + + } + var material = texture.isCubeTexture ? _cubemapShader : _equirectShader; + scene.add( new Mesh( _lodPlanes[ 0 ], material ) ); + var uniforms = material.uniforms; + + uniforms[ 'envMap' ].value = texture; + if ( ! texture.isCubeTexture ) { + + uniforms[ 'texelSize' ].value.set( 1.0 / texture.image.width, 1.0 / texture.image.height ); + + } + uniforms[ 'inputEncoding' ].value = ENCODINGS[ texture.encoding ]; + uniforms[ 'outputEncoding' ].value = ENCODINGS[ texture.encoding ]; + + _setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX ); + _renderer.setRenderTarget( cubeUVRenderTarget ); + _renderer.render( scene, _flatCamera ); + + } + + function _compileMaterial( material ) { + + var tmpScene = new Scene(); + tmpScene.add( new Mesh( _lodPlanes[ 0 ], material ) ); + _renderer.compile( tmpScene, _flatCamera ); + + } + + function _createRenderTarget( params ) { + + var cubeUVRenderTarget = new WebGLRenderTarget( 3 * SIZE_MAX, 3 * SIZE_MAX, params ); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; + + } + + function _setViewport( target, x, y, width, height ) { + + target.viewport.set( x, y, width, height ); + target.scissor.set( x, y, width, height ); + + } + + function _applyPMREM( cubeUVRenderTarget ) { + + var autoClear = _renderer.autoClear; + _renderer.autoClear = false; + + for ( var i = 1; i < TOTAL_LODS; i ++ ) { + + var sigma = Math.sqrt( + _sigmas[ i ] * _sigmas[ i ] - + _sigmas[ i - 1 ] * _sigmas[ i - 1 ] ); + var poleAxis = + _axisDirections[ ( i - 1 ) % _axisDirections.length ]; + _blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis ); + + } + + _renderer.autoClear = autoClear; + + } + + /** + * This is a two-pass Gaussian blur for a cubemap. Normally this is done + * vertically and horizontally, but this breaks down on a cube. Here we apply + * the blur latitudinally (around the poles), and then longitudinally (towards + * the poles) to approximate the orthogonally-separable blur. It is least + * accurate at the poles, but still does a decent job. + */ + function _blur( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) { + + _halfBlur( + cubeUVRenderTarget, + _pingPongRenderTarget, + lodIn, + lodOut, + sigma, + 'latitudinal', + poleAxis ); + + _halfBlur( + _pingPongRenderTarget, + cubeUVRenderTarget, + lodOut, + lodOut, + sigma, + 'longitudinal', + poleAxis ); + + } + + function _halfBlur( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) { + + if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) { + + console.error( + 'blur direction must be either latitudinal or longitudinal!' ); + + } + + // Number of standard deviations at which to cut off the discrete approximation. + var STANDARD_DEVIATIONS = 3; + + var blurScene = new Scene(); + blurScene.add( new Mesh( _lodPlanes[ lodOut ], _blurMaterial ) ); + var blurUniforms = _blurMaterial.uniforms; + + var pixels = _sizeLods[ lodIn ] - 1; + var radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 ); + var sigmaPixels = sigmaRadians / radiansPerPixel; + var samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES; + + if ( samples > MAX_SAMPLES ) { + + console.warn( ("sigmaRadians, " + sigmaRadians + ", is too large and will clip, as it requested " + samples + " samples when the maximum is set to " + MAX_SAMPLES) ); + + } + + var weights = []; + var sum = 0; + + for ( var i = 0; i < MAX_SAMPLES; ++ i ) { + + var x = i / sigmaPixels; + var weight = Math.exp( - x * x / 2 ); + weights.push( weight ); + + if ( i == 0 ) { + + sum += weight; + + } else if ( i < samples ) { + + sum += 2 * weight; + + } + + } + + for ( var i = 0; i < weights.length; i ++ ) { + + weights[ i ] = weights[ i ] / sum; + + } + + blurUniforms[ 'envMap' ].value = targetIn.texture; + blurUniforms[ 'samples' ].value = samples; + blurUniforms[ 'weights' ].value = weights; + blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal'; + if ( poleAxis ) { + + blurUniforms[ 'poleAxis' ].value = poleAxis; + + } + blurUniforms[ 'dTheta' ].value = radiansPerPixel; + blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn; + blurUniforms[ 'inputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ]; + blurUniforms[ 'outputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ]; + + var outputSize = _sizeLods[ lodOut ]; + var x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize ); + var y = ( lodOut === 0 ? 0 : 2 * SIZE_MAX ) + + 2 * outputSize * + ( lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0 ); + + _setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize ); + _renderer.setRenderTarget( targetOut ); + _renderer.render( blurScene, _flatCamera ); + + } + + function _getBlurShader( maxSamples ) { + + var weights = new Float32Array( maxSamples ); + var poleAxis = new Vector3( 0, 1, 0 ); + var shaderMaterial = new RawShaderMaterial( { + + defines: { 'n': maxSamples }, + + uniforms: { + 'envMap': { value: null }, + 'samples': { value: 1 }, + 'weights': { value: weights }, + 'latitudinal': { value: false }, + 'dTheta': { value: 0 }, + 'mipInt': { value: 0 }, + 'poleAxis': { value: poleAxis }, + 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, + 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } + }, + + vertexShader: _getCommonVertexShader(), + + fragmentShader: ("\nprecision mediump float;\nprecision mediump int;\nvarying vec3 vOutputDirection;\nuniform sampler2D envMap;\nuniform int samples;\nuniform float weights[n];\nuniform bool latitudinal;\nuniform float dTheta;\nuniform float mipInt;\nuniform vec3 poleAxis;\n\n" + (_getEncodings()) + "\n\n#define ENVMAP_TYPE_CUBE_UV\n#include \n\nvoid main() {\n\tgl_FragColor = vec4(0.0);\n\tfor (int i = 0; i < n; i++) {\n\t\tif (i >= samples)\n\t\t\tbreak;\n\t\tfor (int dir = -1; dir < 2; dir += 2) {\n\t\t\tif (i == 0 && dir == 1)\n\t\t\t\tcontinue;\n\t\t\tvec3 axis = latitudinal ? poleAxis : cross(poleAxis, vOutputDirection);\n\t\t\tif (all(equal(axis, vec3(0.0))))\n\t\t\t\taxis = cross(vec3(0.0, 1.0, 0.0), vOutputDirection);\n\t\t\taxis = normalize(axis);\n\t\t\tfloat theta = dTheta * float(dir * i);\n\t\t\tfloat cosTheta = cos(theta);\n\t\t\t// Rodrigues' axis-angle rotation\n\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross(axis, vOutputDirection) * sin(theta)\n\t\t\t\t\t+ axis * dot(axis, vOutputDirection) * (1.0 - cosTheta);\n\t\t\tgl_FragColor.rgb +=\n\t\t\t\t\tweights[i] * bilinearCubeUV(envMap, sampleDirection, mipInt);\n\t\t}\n\t}\n\tgl_FragColor = linearToOutputTexel(gl_FragColor);\n}\n\t\t"), + + blending: NoBlending, + depthTest: false, + depthWrite: false + + } ); + + shaderMaterial.type = 'SphericalGaussianBlur'; + + return shaderMaterial; + + } + + function _getEquirectShader() { + + var texelSize = new Vector2( 1, 1 ); + var shaderMaterial = new RawShaderMaterial( { + + uniforms: { + 'envMap': { value: null }, + 'texelSize': { value: texelSize }, + 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, + 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } + }, + + vertexShader: _getCommonVertexShader(), + + fragmentShader: ("\nprecision mediump float;\nprecision mediump int;\nvarying vec3 vOutputDirection;\nuniform sampler2D envMap;\nuniform vec2 texelSize;\n\n" + (_getEncodings()) + "\n\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n\nvoid main() {\n\tgl_FragColor = vec4(0.0);\n\tvec3 outputDirection = normalize(vOutputDirection);\n\tvec2 uv;\n\tuv.y = asin(clamp(outputDirection.y, -1.0, 1.0)) * RECIPROCAL_PI + 0.5;\n\tuv.x = atan(outputDirection.z, outputDirection.x) * RECIPROCAL_PI2 + 0.5;\n\tvec2 f = fract(uv / texelSize - 0.5);\n\tuv -= f * texelSize;\n\tvec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tuv.x += texelSize.x;\n\tvec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tuv.y += texelSize.y;\n\tvec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tuv.x -= texelSize.x;\n\tvec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tvec3 tm = mix(tl, tr, f.x);\n\tvec3 bm = mix(bl, br, f.x);\n\tgl_FragColor.rgb = mix(tm, bm, f.y);\n\tgl_FragColor = linearToOutputTexel(gl_FragColor);\n}\n\t\t"), + + blending: NoBlending, + depthTest: false, + depthWrite: false + + } ); + + shaderMaterial.type = 'EquirectangularToCubeUV'; + + return shaderMaterial; + + } + + function _getCubemapShader() { + + var shaderMaterial = new RawShaderMaterial( { + + uniforms: { + 'envMap': { value: null }, + 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, + 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } + }, + + vertexShader: _getCommonVertexShader(), + + fragmentShader: ("\nprecision mediump float;\nprecision mediump int;\nvarying vec3 vOutputDirection;\nuniform samplerCube envMap;\n\n" + (_getEncodings()) + "\n\nvoid main() {\n\tgl_FragColor = vec4(0.0);\n\tgl_FragColor.rgb = envMapTexelToLinear(textureCube(envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ))).rgb;\n\tgl_FragColor = linearToOutputTexel(gl_FragColor);\n}\n\t\t"), + + blending: NoBlending, + depthTest: false, + depthWrite: false + + } ); + + shaderMaterial.type = 'CubemapToCubeUV'; + + return shaderMaterial; + + } + + function _getCommonVertexShader() { + + return "\nprecision mediump float;\nprecision mediump int;\nattribute vec3 position;\nattribute vec2 uv;\nattribute float faceIndex;\nvarying vec3 vOutputDirection;\nvec3 getDirection(vec2 uv, float face) {\n\tuv = 2.0 * uv - 1.0;\n\tvec3 direction = vec3(uv, 1.0);\n\tif (face == 0.0) {\n\t\tdirection = direction.zyx;\n\t\tdirection.z *= -1.0;\n\t} else if (face == 1.0) {\n\t\tdirection = direction.xzy;\n\t\tdirection.z *= -1.0;\n\t} else if (face == 3.0) {\n\t\tdirection = direction.zyx;\n\t\tdirection.x *= -1.0;\n\t} else if (face == 4.0) {\n\t\tdirection = direction.xzy;\n\t\tdirection.y *= -1.0;\n\t} else if (face == 5.0) {\n\t\tdirection.xz *= -1.0;\n\t}\n\treturn direction;\n}\nvoid main() {\n\tvOutputDirection = getDirection(uv, faceIndex);\n\tgl_Position = vec4( position, 1.0 );\n}\n\t"; + + } + + function _getEncodings() { + + return "\nuniform int inputEncoding;\nuniform int outputEncoding;\n\n#include \n\nvec4 inputTexelToLinear(vec4 value){\n\tif(inputEncoding == 0){\n\t\treturn value;\n\t}else if(inputEncoding == 1){\n\t\treturn sRGBToLinear(value);\n\t}else if(inputEncoding == 2){\n\t\treturn RGBEToLinear(value);\n\t}else if(inputEncoding == 3){\n\t\treturn RGBMToLinear(value, 7.0);\n\t}else if(inputEncoding == 4){\n\t\treturn RGBMToLinear(value, 16.0);\n\t}else if(inputEncoding == 5){\n\t\treturn RGBDToLinear(value, 256.0);\n\t}else{\n\t\treturn GammaToLinear(value, 2.2);\n\t}\n}\n\nvec4 linearToOutputTexel(vec4 value){\n\tif(outputEncoding == 0){\n\t\treturn value;\n\t}else if(outputEncoding == 1){\n\t\treturn LinearTosRGB(value);\n\t}else if(outputEncoding == 2){\n\t\treturn LinearToRGBE(value);\n\t}else if(outputEncoding == 3){\n\t\treturn LinearToRGBM(value, 7.0);\n\t}else if(outputEncoding == 4){\n\t\treturn LinearToRGBM(value, 16.0);\n\t}else if(outputEncoding == 5){\n\t\treturn LinearToRGBD(value, 256.0);\n\t}else{\n\t\treturn LinearToGamma(value, 2.2);\n\t}\n}\n\nvec4 envMapTexelToLinear(vec4 color) {\n\treturn inputTexelToLinear(color);\n}\n\t"; + + } + /** * @author mrdoob / http://mrdoob.com/ */ @@ -46736,8 +47793,10 @@ } var LineStrip = 0; - var LinePieces = 1; + var NoColors = 0; + var FaceColors = 1; + var VertexColors = 2; function MeshFaceMaterial( materials ) { @@ -46748,7 +47807,7 @@ function MultiMaterial( materials ) { - if ( materials === undefined ) materials = []; + if ( materials === undefined ) { materials = []; } console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' ); materials.isMultiMaterial = true; @@ -46815,8 +47874,8 @@ function DynamicBufferAttribute( array, itemSize ) { - console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' ); - return new BufferAttribute( array, itemSize ).setDynamic( true ); + console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.' ); + return new BufferAttribute( array, itemSize ).setUsage( DynamicDrawUsage ); } @@ -46949,7 +48008,7 @@ fromPoints: function ( points ) { console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' ); - this.setFromPoints( points ); + return this.setFromPoints( points ); } @@ -47070,6 +48129,22 @@ } ); + Loader.Handlers = { + + add: function ( /* regex, loader */ ) { + + console.error( 'THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.' ); + + }, + + get: function ( /* file */ ) { + + console.error( 'THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.' ); + + } + + }; + function XHRLoader( manager ) { console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' ); @@ -47159,6 +48234,13 @@ } } ); + Frustum.prototype.setFromMatrix = function ( m ) { + + console.warn( 'THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().' ); + return this.setFromProjectionMatrix( m ); + + }; + Line3.prototype.center = function ( optionalTarget ) { console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' ); @@ -47166,7 +48248,7 @@ }; - Object.assign( _Math, { + Object.assign( MathUtils, { random16: function () { @@ -47178,14 +48260,14 @@ nearestPowerOfTwo: function ( value ) { console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' ); - return _Math.floorPowerOfTwo( value ); + return MathUtils.floorPowerOfTwo( value ); }, nextPowerOfTwo: function ( value ) { console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' ); - return _Math.ceilPowerOfTwo( value ); + return MathUtils.ceilPowerOfTwo( value ); } @@ -47210,10 +48292,10 @@ console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' ); }, - applyToBuffer: function ( buffer /*, offset, length */ ) { + applyToBufferAttribute: function ( attribute ) { - console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); - return this.applyToBufferAttribute( buffer ); + console.warn( 'THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.' ); + return attribute.applyMatrix3( this ); }, applyToVector3Array: function ( /* array, offset, length */ ) { @@ -47309,10 +48391,10 @@ console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); }, - applyToBuffer: function ( buffer /*, offset, length */ ) { + applyToBufferAttribute: function ( attribute ) { - console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); - return this.applyToBufferAttribute( buffer ); + console.warn( 'THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.' ); + return attribute.applyMatrix4( this ); }, applyToVector3Array: function ( /* array, offset, length */ ) { @@ -47551,6 +48633,12 @@ console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' ); + }, + applyMatrix: function ( matrix ) { + + console.warn( 'THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().' ); + return this.applyMatrix4( matrix ); + } } ); @@ -47578,6 +48666,12 @@ console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' ); + }, + applyMatrix: function ( matrix ) { + + console.warn( 'THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().' ); + return this.applyMatrix4( matrix ); + } } ); @@ -47613,6 +48707,34 @@ } ); + Object.assign( Mesh.prototype, { + + setDrawMode: function () { + + console.error( 'THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' ); + + }, + + } ); + + Object.defineProperties( Mesh.prototype, { + + drawMode: { + get: function () { + + console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.' ); + return TrianglesDrawMode; + + }, + set: function () { + + console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' ); + + } + } + + } ); + Object.defineProperties( LOD.prototype, { objects: { @@ -47671,7 +48793,7 @@ console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " + "Use .setFocalLength and .filmGauge for a photographic setup." ); - if ( filmGauge !== undefined ) this.filmGauge = filmGauge; + if ( filmGauge !== undefined ) { this.filmGauge = filmGauge; } this.setFocalLength( focalLength ); }; @@ -47794,12 +48916,41 @@ } }, + dynamic: { + get: function () { + + console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' ); + return this.usage === DynamicDrawUsage; + + }, + set: function ( /* value */ ) { + + console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' ); + this.setUsage( DynamicDrawUsage ); + + } + } + + } ); + + Object.assign( BufferAttribute.prototype, { + setDynamic: function ( value ) { + + console.warn( 'THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.' ); + this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage ); + return this; + + }, copyIndicesArray: function ( /* indices */ ) { console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' ); - } + }, + setArray: function ( /* array */ ) { + console.error( 'THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' ); + + } } ); Object.assign( BufferGeometry.prototype, { @@ -47809,6 +48960,30 @@ console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); this.setIndex( index ); + }, + addAttribute: function ( name, attribute ) { + + console.warn( 'THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().' ); + + if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { + + console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); + + return this.setAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); + + } + + if ( name === 'index' ) { + + console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); + this.setIndex( attribute ); + + return this; + + } + + return this.setAttribute( name, attribute ); + }, addDrawCall: function ( start, count, indexOffset ) { @@ -47836,6 +49011,19 @@ console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); + }, + removeAttribute: function ( name ) { + + console.warn( 'THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().' ); + + return this.deleteAttribute( name ); + + }, + applyMatrix: function ( matrix ) { + + console.warn( 'THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().' ); + return this.applyMatrix4( matrix ); + } } ); @@ -47861,6 +49049,59 @@ } ); + Object.defineProperties( Raycaster.prototype, { + + linePrecision: { + get: function () { + + console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' ); + return this.params.Line.threshold; + + }, + set: function ( value ) { + + console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' ); + this.params.Line.threshold = value; + + } + } + + } ); + + Object.defineProperties( InterleavedBuffer.prototype, { + + dynamic: { + get: function () { + + console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' ); + return this.usage === DynamicDrawUsage; + + }, + set: function ( value ) { + + console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' ); + this.setUsage( value ); + + } + } + + } ); + + Object.assign( InterleavedBuffer.prototype, { + setDynamic: function ( value ) { + + console.warn( 'THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.' ); + this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage ); + return this; + + }, + setArray: function ( /* array */ ) { + + console.error( 'THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' ); + + } + } ); + // Object.assign( ExtrudeBufferGeometry.prototype, { @@ -47957,6 +49198,21 @@ console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); this.flatShading = ( value === FlatShading ); + } + }, + + stencilMask: { + get: function () { + + console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' ); + return this.stencilFuncMask; + + }, + set: function ( value ) { + + console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' ); + this.stencilFuncMask = value; + } } @@ -48195,6 +49451,41 @@ console.warn( 'THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.' ); return this.getContext(); + } + }, + vr: { + get: function () { + + console.warn( 'THREE.WebGLRenderer: .vr has been renamed to .xr' ); + return this.xr; + + } + }, + gammaInput: { + get: function () { + + console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' ); + return false; + + }, + set: function () { + + console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' ); + + } + }, + gammaOutput: { + get: function () { + + console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' ); + return false; + + }, + set: function ( value ) { + + console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' ); + this.outputEncoding = ( value === true ) ? sRGBEncoding : LinearEncoding; + } } @@ -48244,26 +49535,12 @@ } ); - // - - Object.defineProperties( WebGLRenderTargetCube.prototype, { - - activeCubeFace: { - set: function ( /* value */ ) { - - console.warn( 'THREE.WebGLRenderTargetCube: .activeCubeFace has been removed. It is now the second parameter of WebGLRenderer.setRenderTarget().' ); - - } - }, - activeMipMapLevel: { - set: function ( /* value */ ) { - - console.warn( 'THREE.WebGLRenderTargetCube: .activeMipMapLevel has been removed. It is now the third parameter of WebGLRenderer.setRenderTarget().' ); + function WebGLRenderTargetCube( width, height, options ) { - } - } + console.warn( 'THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).' ); + return new WebGLCubeRenderTarget( width, options ); - } ); + } // @@ -48414,41 +49691,33 @@ // - Object.defineProperties( WebVRManager.prototype, { + Object.defineProperties( Audio.prototype, { - standing: { - set: function ( /* value */ ) { + load: { + value: function ( file ) { - console.warn( 'THREE.WebVRManager: .standing has been removed.' ); + console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); + var scope = this; + var audioLoader = new AudioLoader(); + audioLoader.load( file, function ( buffer ) { + + scope.setBuffer( buffer ); + + } ); + return this; } }, - userHeight: { - set: function ( /* value */ ) { + startTime: { + set: function () { - console.warn( 'THREE.WebVRManager: .userHeight has been removed.' ); + console.warn( 'THREE.Audio: .startTime is now .play( delay ).' ); } } } ); - // - - Audio.prototype.load = function ( file ) { - - console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); - var scope = this; - var audioLoader = new AudioLoader(); - audioLoader.load( file, function ( buffer ) { - - scope.setBuffer( buffer ); - - } ); - return this; - - }; - AudioAnalyser.prototype.getData = function () { console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); @@ -48507,7 +49776,7 @@ var texture = loader.load( url, onLoad, undefined, onError ); - if ( mapping ) texture.mapping = mapping; + if ( mapping ) { texture.mapping = mapping; } return texture; @@ -48522,7 +49791,7 @@ var texture = loader.load( urls, onLoad, undefined, onError ); - if ( mapping ) texture.mapping = mapping; + if ( mapping ) { texture.mapping = mapping; } return texture; @@ -48562,19 +49831,19 @@ createMultiMaterialObject: function ( /* geometry, materials */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); }, detach: function ( /* child, parent, scene */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); }, attach: function ( /* child, scene, parent */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); } @@ -48584,7 +49853,17 @@ function LensFlare() { - console.error( 'THREE.LensFlare has been moved to /examples/js/objects/Lensflare.js' ); + console.error( 'THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js' ); + + } + + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + /* eslint-disable no-undef */ + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: { + revision: REVISION, + } } ) ); + /* eslint-enable no-undef */ } @@ -48688,6 +49967,9 @@ exports.DstAlphaFactor = DstAlphaFactor; exports.DstColorFactor = DstColorFactor; exports.DynamicBufferAttribute = DynamicBufferAttribute; + exports.DynamicCopyUsage = DynamicCopyUsage; + exports.DynamicDrawUsage = DynamicDrawUsage; + exports.DynamicReadUsage = DynamicReadUsage; exports.EdgesGeometry = EdgesGeometry; exports.EdgesHelper = EdgesHelper; exports.EllipseCurve = EllipseCurve; @@ -48702,7 +49984,6 @@ exports.Face3 = Face3; exports.Face4 = Face4; exports.FaceColors = FaceColors; - exports.FaceNormalsHelper = FaceNormalsHelper; exports.FileLoader = FileLoader; exports.FlatShading = FlatShading; exports.Float32Attribute = Float32Attribute; @@ -48742,6 +50023,7 @@ exports.InstancedBufferAttribute = InstancedBufferAttribute; exports.InstancedBufferGeometry = InstancedBufferGeometry; exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer; + exports.InstancedMesh = InstancedMesh; exports.Int16Attribute = Int16Attribute; exports.Int16BufferAttribute = Int16BufferAttribute; exports.Int32Attribute = Int32Attribute; @@ -48770,7 +50052,6 @@ exports.LessStencilFunc = LessStencilFunc; exports.Light = Light; exports.LightProbe = LightProbe; - exports.LightProbeHelper = LightProbeHelper; exports.LightShadow = LightShadow; exports.Line = Line; exports.Line3 = Line3; @@ -48802,7 +50083,8 @@ exports.MOUSE = MOUSE; exports.Material = Material; exports.MaterialLoader = MaterialLoader; - exports.Math = _Math; + exports.Math = MathUtils; + exports.MathUtils = MathUtils; exports.Matrix3 = Matrix3; exports.Matrix4 = Matrix4; exports.MaxEquation = MaxEquation; @@ -48851,6 +50133,7 @@ exports.OrthographicCamera = OrthographicCamera; exports.PCFShadowMap = PCFShadowMap; exports.PCFSoftShadowMap = PCFSoftShadowMap; + exports.PMREMGenerator = PMREMGenerator; exports.ParametricBufferGeometry = ParametricBufferGeometry; exports.ParametricGeometry = ParametricGeometry; exports.Particle = Particle; @@ -48873,7 +50156,6 @@ exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry; exports.PolyhedronGeometry = PolyhedronGeometry; exports.PositionalAudio = PositionalAudio; - exports.PositionalAudioHelper = PositionalAudioHelper; exports.PropertyBinding = PropertyBinding; exports.PropertyMixer = PropertyMixer; exports.QuadraticBezierCurve = QuadraticBezierCurve; @@ -48884,6 +50166,7 @@ exports.REVISION = REVISION; exports.RGBADepthPacking = RGBADepthPacking; exports.RGBAFormat = RGBAFormat; + exports.RGBAIntegerFormat = RGBAIntegerFormat; exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format; exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format; exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format; @@ -48898,6 +50181,7 @@ exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format; exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format; exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format; + exports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format; exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format; exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format; exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format; @@ -48907,24 +50191,42 @@ exports.RGBEEncoding = RGBEEncoding; exports.RGBEFormat = RGBEFormat; exports.RGBFormat = RGBFormat; + exports.RGBIntegerFormat = RGBIntegerFormat; exports.RGBM16Encoding = RGBM16Encoding; exports.RGBM7Encoding = RGBM7Encoding; exports.RGB_ETC1_Format = RGB_ETC1_Format; + exports.RGB_ETC2_Format = RGB_ETC2_Format; exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format; exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format; exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format; + exports.RGFormat = RGFormat; + exports.RGIntegerFormat = RGIntegerFormat; exports.RawShaderMaterial = RawShaderMaterial; exports.Ray = Ray; exports.Raycaster = Raycaster; exports.RectAreaLight = RectAreaLight; - exports.RectAreaLightHelper = RectAreaLightHelper; exports.RedFormat = RedFormat; + exports.RedIntegerFormat = RedIntegerFormat; exports.ReinhardToneMapping = ReinhardToneMapping; exports.RepeatWrapping = RepeatWrapping; exports.ReplaceStencilOp = ReplaceStencilOp; exports.ReverseSubtractEquation = ReverseSubtractEquation; exports.RingBufferGeometry = RingBufferGeometry; exports.RingGeometry = RingGeometry; + exports.SRGB8_ALPHA8_ASTC_10x10_Format = SRGB8_ALPHA8_ASTC_10x10_Format; + exports.SRGB8_ALPHA8_ASTC_10x5_Format = SRGB8_ALPHA8_ASTC_10x5_Format; + exports.SRGB8_ALPHA8_ASTC_10x6_Format = SRGB8_ALPHA8_ASTC_10x6_Format; + exports.SRGB8_ALPHA8_ASTC_10x8_Format = SRGB8_ALPHA8_ASTC_10x8_Format; + exports.SRGB8_ALPHA8_ASTC_12x10_Format = SRGB8_ALPHA8_ASTC_12x10_Format; + exports.SRGB8_ALPHA8_ASTC_12x12_Format = SRGB8_ALPHA8_ASTC_12x12_Format; + exports.SRGB8_ALPHA8_ASTC_4x4_Format = SRGB8_ALPHA8_ASTC_4x4_Format; + exports.SRGB8_ALPHA8_ASTC_5x4_Format = SRGB8_ALPHA8_ASTC_5x4_Format; + exports.SRGB8_ALPHA8_ASTC_5x5_Format = SRGB8_ALPHA8_ASTC_5x5_Format; + exports.SRGB8_ALPHA8_ASTC_6x5_Format = SRGB8_ALPHA8_ASTC_6x5_Format; + exports.SRGB8_ALPHA8_ASTC_6x6_Format = SRGB8_ALPHA8_ASTC_6x6_Format; + exports.SRGB8_ALPHA8_ASTC_8x5_Format = SRGB8_ALPHA8_ASTC_8x5_Format; + exports.SRGB8_ALPHA8_ASTC_8x6_Format = SRGB8_ALPHA8_ASTC_8x6_Format; + exports.SRGB8_ALPHA8_ASTC_8x8_Format = SRGB8_ALPHA8_ASTC_8x8_Format; exports.Scene = Scene; exports.SceneUtils = SceneUtils; exports.ShaderChunk = ShaderChunk; @@ -48958,7 +50260,13 @@ exports.SrcAlphaFactor = SrcAlphaFactor; exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor; exports.SrcColorFactor = SrcColorFactor; + exports.StaticCopyUsage = StaticCopyUsage; + exports.StaticDrawUsage = StaticDrawUsage; + exports.StaticReadUsage = StaticReadUsage; exports.StereoCamera = StereoCamera; + exports.StreamCopyUsage = StreamCopyUsage; + exports.StreamDrawUsage = StreamDrawUsage; + exports.StreamReadUsage = StreamReadUsage; exports.StringKeyframeTrack = StringKeyframeTrack; exports.SubtractEquation = SubtractEquation; exports.SubtractiveBlending = SubtractiveBlending; @@ -49000,14 +50308,15 @@ exports.UnsignedShort5551Type = UnsignedShort5551Type; exports.UnsignedShort565Type = UnsignedShort565Type; exports.UnsignedShortType = UnsignedShortType; + exports.VSMShadowMap = VSMShadowMap; exports.Vector2 = Vector2; exports.Vector3 = Vector3; exports.Vector4 = Vector4; exports.VectorKeyframeTrack = VectorKeyframeTrack; exports.Vertex = Vertex; exports.VertexColors = VertexColors; - exports.VertexNormalsHelper = VertexNormalsHelper; exports.VideoTexture = VideoTexture; + exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget; exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget; exports.WebGLRenderTarget = WebGLRenderTarget; exports.WebGLRenderTargetCube = WebGLRenderTargetCube; @@ -49025,4 +50334,4 @@ Object.defineProperty(exports, '__esModule', { value: true }); -})); +}))); diff --git a/build/three.min.js b/build/three.min.js index 7f5171357c1122..d9e61b02052c10 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -1,996 +1,1035 @@ -(function(k,ma){"object"===typeof exports&&"undefined"!==typeof module?ma(exports):"function"===typeof define&&define.amd?define(["exports"],ma):(k=k||self,ma(k.THREE={}))})(this,function(k){function ma(){}function y(a,b){this.x=a||0;this.y=b||0}function na(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function n(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function sa(){this.elements=[1,0,0,0,1,0,0,0,1];0h)return!1}return!0}function ob(a,b){this.center=void 0!==a?a:new n;this.radius=void 0!==b?b:0}function Tb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n}function ta(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!==b?b:new n;this.c=void 0!==c?c:new n}function K(a,b,c){return void 0===b&&void 0=== -c?this.set(a):this.setRGB(a,b,c)}function Pf(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function Qf(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function Rf(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}function Ac(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new K;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex= -void 0!==f?f:0}function Q(){Object.defineProperty(this,"id",{value:Qi++});this.uuid=O.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.stencilFunc=519;this.stencilRef=0;this.stencilMask= -255;this.stencilZPass=this.stencilZFail=this.stencilFail=7680;this.stencilWrite=!1;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.visible=!0;this.userData={};this.needsUpdate=!0}function Fa(a){Q.call(this);this.type="MeshBasicMaterial";this.color=new K(16777215);this.lightMap=this.map= -null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function R(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.name="";this.array=a;this.itemSize=b;this.count= -void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function yd(a,b,c){R.call(this,new Int8Array(a),b,c)}function zd(a,b,c){R.call(this,new Uint8Array(a),b,c)}function Ad(a,b,c){R.call(this,new Uint8ClampedArray(a),b,c)}function Bd(a,b,c){R.call(this,new Int16Array(a),b,c)}function Ub(a,b,c){R.call(this,new Uint16Array(a),b,c)}function Cd(a,b,c){R.call(this,new Int32Array(a),b,c)}function Vb(a,b,c){R.call(this,new Uint32Array(a),b,c)} -function z(a,b,c){R.call(this,new Float32Array(a),b,c)}function Dd(a,b,c){R.call(this,new Float64Array(a),b,c)}function ch(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function dh(a){if(0===a.length)return-Infinity;for(var b=a[0],c=1,d=a.length;c< -d;++c)a[c]>b&&(b=a[c]);return b}function D(){Object.defineProperty(this,"id",{value:Ri+=2});this.uuid=O.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}}function da(a,b){C.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new Fa({color:16777215*Math.random()});this.drawMode=0;this.updateMorphTargets()} -function eh(a,b,c,d,e,f,g,h){if(null===(1===b.side?d.intersectTriangle(g,f,e,!0,h):d.intersectTriangle(e,f,g,2!==b.side,h)))return null;Ge.copy(h);Ge.applyMatrix4(a.matrixWorld);b=c.ray.origin.distanceTo(Ge);return bc.far?null:{distance:b,point:Ge.clone(),object:a}}function He(a,b,c,d,e,f,g,h,l,m,r){Wb.fromBufferAttribute(e,l);Xb.fromBufferAttribute(e,m);Yb.fromBufferAttribute(e,r);e=a.morphTargetInfluences;if(b.morphTargets&&f&&e){Sf.set(0,0,0);Tf.set(0,0,0);Uf.set(0,0,0);for(var t=0, -u=f.length;tg;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function Db(a,b,c){ab.call(this,a,b,c)}function $b(a,b,c,d,e,f,g,h,l,m,r,t){Y.call(this,null,f,g,h,l,m,d,e,r,t);this.image={data:a,width:b,height:c};this.magFilter=void 0!==l?l:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1}function db(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!==b?b:0}function Ie(a,b,c,d,e,f){this.planes=[void 0!==a?a:new db, -void 0!==b?b:new db,void 0!==c?c:new db,void 0!==d?d:new db,void 0!==e?e:new db,void 0!==f?f:new db]}function Wf(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)},stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function Ti(a){function b(b,c){var d=b.array,e=b.dynamic?35048:35044,h=a.createBuffer();a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback(); -c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data); -return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.versionm;m++){if(t=d[m])if(h=t[0],l=t[1]){r&&e.addAttribute("morphTarget"+m,r[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=l;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function dj(a,b){var c={};return{update:function(d){var e=b.render.frame,f=d.geometry,g=a.get(d,f);c[g.id]!==e&&(f.isGeometry&&g.updateFromObject(d),a.update(g),c[g.id]=e);return g},dispose:function(){c={}}}}function qb(a,b,c,d,e,f,g,h,l,m){a= -void 0!==a?a:[];Y.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h,l,m);this.flipY=!1}function Gc(a,b,c,d){Y.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Hc(a,b,c,d){Y.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Ic(a,b,c){var d=a[0];if(0>=d||0/gm,function(a,c){a=P[c];if(void 0===a)throw Error("Can not resolve #include <"+c+">");return Yf(a)})}function yh(a){return a.replace(/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g, -function(a,c,d,e){a="";for(c=parseInt(c);cc;c++)b.probe.push(new n);var d=new n,e=new M,f=new M;return{setup:function(c,h,l){for(var g=0,r=0,t=0,k=0;9>k;k++)b.probe[k].set(0,0,0);var q=h=0,p=0,n=0,v=0,A=0,w=0,I=0;l=l.matrixWorldInverse;c.sort(Xj);k=0;for(var G=c.length;kCa;Ca++)b.probe[Ca].addScaledVector(B.sh.coefficients[Ca], -Z);else if(B.isDirectionalLight){var E=a.get(B);E.color.copy(B.color).multiplyScalar(B.intensity);E.direction.setFromMatrixPosition(B.matrixWorld);d.setFromMatrixPosition(B.target.matrixWorld);E.direction.sub(d);E.direction.transformDirection(l);if(E.shadow=B.castShadow)Z=B.shadow,E.shadowBias=Z.bias,E.shadowRadius=Z.radius,E.shadowMapSize=Z.mapSize,b.directionalShadowMap[h]=Ca,b.directionalShadowMatrix[h]=B.shadow.matrix,A++;b.directional[h]=E;h++}else if(B.isSpotLight){E=a.get(B);E.position.setFromMatrixPosition(B.matrixWorld); -E.position.applyMatrix4(l);E.color.copy(Ga).multiplyScalar(Z);E.distance=y;E.direction.setFromMatrixPosition(B.matrixWorld);d.setFromMatrixPosition(B.target.matrixWorld);E.direction.sub(d);E.direction.transformDirection(l);E.coneCos=Math.cos(B.angle);E.penumbraCos=Math.cos(B.angle*(1-B.penumbra));E.decay=B.decay;if(E.shadow=B.castShadow)Z=B.shadow,E.shadowBias=Z.bias,E.shadowRadius=Z.radius,E.shadowMapSize=Z.mapSize,b.spotShadowMap[p]=Ca,b.spotShadowMatrix[p]=B.shadow.matrix,I++;b.spot[p]=E;p++}else if(B.isRectAreaLight)E= -a.get(B),E.color.copy(Ga).multiplyScalar(Z),E.position.setFromMatrixPosition(B.matrixWorld),E.position.applyMatrix4(l),f.identity(),e.copy(B.matrixWorld),e.premultiply(l),f.extractRotation(e),E.halfWidth.set(.5*B.width,0,0),E.halfHeight.set(0,.5*B.height,0),E.halfWidth.applyMatrix4(f),E.halfHeight.applyMatrix4(f),b.rectArea[n]=E,n++;else if(B.isPointLight){E=a.get(B);E.position.setFromMatrixPosition(B.matrixWorld);E.position.applyMatrix4(l);E.color.copy(B.color).multiplyScalar(B.intensity);E.distance= -B.distance;E.decay=B.decay;if(E.shadow=B.castShadow)Z=B.shadow,E.shadowBias=Z.bias,E.shadowRadius=Z.radius,E.shadowMapSize=Z.mapSize,E.shadowCameraNear=Z.camera.near,E.shadowCameraFar=Z.camera.far,b.pointShadowMap[q]=Ca,b.pointShadowMatrix[q]=B.shadow.matrix,w++;b.point[q]=E;q++}else B.isHemisphereLight&&(E=a.get(B),E.direction.setFromMatrixPosition(B.matrixWorld),E.direction.transformDirection(l),E.direction.normalize(),E.skyColor.copy(B.color).multiplyScalar(Z),E.groundColor.copy(B.groundColor).multiplyScalar(Z), -b.hemi[v]=E,v++)}b.ambient[0]=g;b.ambient[1]=r;b.ambient[2]=t;c=b.hash;if(c.directionalLength!==h||c.pointLength!==q||c.spotLength!==p||c.rectAreaLength!==n||c.hemiLength!==v||c.numDirectionalShadows!==A||c.numPointShadows!==w||c.numSpotShadows!==I)b.directional.length=h,b.spot.length=p,b.rectArea.length=n,b.point.length=q,b.hemi.length=v,b.directionalShadowMap.length=A,b.pointShadowMap.length=w,b.spotShadowMap.length=I,b.directionalShadowMatrix.length=A,b.pointShadowMatrix.length=w,b.spotShadowMatrix.length= -I,c.directionalLength=h,c.pointLength=q,c.spotLength=p,c.rectAreaLength=n,c.hemiLength=v,c.numDirectionalShadows=A,c.numPointShadows=w,c.numSpotShadows=I,b.version=Zj++},state:b}}function Ah(){var a=new Yj,b=[],c=[];return{init:function(){b.length=0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)},pushShadow:function(a){c.push(a)}}}function ak(){function a(c){c=c.target;c.removeEventListener("dispose",a);delete b[c.id]} -var b={};return{get:function(c,d){if(void 0===b[c.id]){var e=new Ah;b[c.id]={};b[c.id][d.id]=e;c.addEventListener("dispose",a)}else void 0===b[c.id][d.id]?(e=new Ah,b[c.id][d.id]=e):e=b[c.id][d.id];return e},dispose:function(){b={}}}}function Fb(a){Q.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights= -this.fog=!1;this.setValues(a)}function Gb(a){Q.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance=1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.lights=this.fog=!1;this.setValues(a)}function Bh(a,b,c){function d(b,c,d,e,f,g){var h=b.geometry;var l=t;var m=b.customDepthMaterial;d&&(l=k,m=b.customDistanceMaterial);m?l=m:(m=!1,c.morphTargets&&(h&&h.isBufferGeometry? -m=h.morphAttributes&&h.morphAttributes.position&&0d||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!== -typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?O.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),void 0===E&&(E=h(b,e)),c=c?h(b,e):E,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+ -").")}return a}function m(a){return O.isPowerOfTwo(a.width)&&O.isPowerOfTwo(a.height)}function r(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function t(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function k(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&& -(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");return d}function q(a){return 1003===a||1004===a||1005===a?9728:9729}function p(b){b=b.target;b.removeEventListener("dispose",p);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&delete Ca[b.id];g.memory.textures--} -function n(b){b=b.target;b.removeEventListener("dispose",n);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--} -function v(a,b){var e=d.get(a);if(a.isVideoTexture){var f=a.id,h=g.render.frame;Ca[f]!==h&&(Ca[f]=h,a.update())}if(0p;p++)q[p]=g||u?u?b.image[p].image:b.image[p]:l(b.image[p],!1,!0,e.maxCubemapSize);var n=q[0],x=m(n)||e.isWebGL2,v=f.convert(b.format),w=f.convert(b.type),V=k(v,w);I(34067,b,x);var B=b.mipmaps;for(p=0;6>p;p++)if(g){B=q[p].mipmaps;ja=0;for(var A=B.length;ja=e.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+ -a+" texture units while this GPU supports only "+e.maxTextures);D+=1;return a};this.resetTextureUnits=function(){D=0};this.setTexture2D=v;this.setTexture2DArray=function(a,b){var e=d.get(a);0u;u++)h.__webglFramebuffer[u]=a.createFramebuffer();else if(h.__webglFramebuffer=a.createFramebuffer(),u)if(e.isWebGL2){h.__webglMultisampledFramebuffer=a.createFramebuffer();h.__webglColorRenderbuffer=a.createRenderbuffer(); -a.bindRenderbuffer(36161,h.__webglColorRenderbuffer);u=f.convert(b.texture.format);var x=f.convert(b.texture.type);u=k(u,x);x=z(b);a.renderbufferStorageMultisample(36161,x,u,b.width,b.height);a.bindFramebuffer(36160,h.__webglMultisampledFramebuffer);a.framebufferRenderbuffer(36160,36064,36161,h.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);b.depthBuffer&&(h.__webglDepthRenderbuffer=a.createRenderbuffer(),Z(h.__webglDepthRenderbuffer,b,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2."); -if(p){c.bindTexture(34067,l.__webglTexture);I(34067,b.texture,q);for(u=0;6>u;u++)y(h.__webglFramebuffer[u],b,36064,34069+u);r(b.texture,q)&&t(34067,b.texture,b.width,b.height);c.bindTexture(34067,null)}else c.bindTexture(3553,l.__webglTexture),I(3553,b.texture,q),y(h.__webglFramebuffer,b,36064,3553),r(b.texture,q)&&t(3553,b.texture,b.width,b.height),c.bindTexture(3553,null);if(b.depthBuffer){h=d.get(b);l=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(l)throw Error("target.depthTexture not supported in Cube render targets"); -if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160,h.__webglFramebuffer);if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width===b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0); -v(b.depthTexture,0);h=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,h,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,h,0);else throw Error("Unknown depthTexture format");}else if(l)for(h.__webglDepthbuffer=[],l=0;6>l;l++)a.bindFramebuffer(36160,h.__webglFramebuffer[l]),h.__webglDepthbuffer[l]=a.createRenderbuffer(),Z(h.__webglDepthbuffer[l],b);else a.bindFramebuffer(36160,h.__webglFramebuffer),h.__webglDepthbuffer= -a.createRenderbuffer(),Z(h.__webglDepthbuffer,b);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture,f=m(a)||e.isWebGL2;if(r(b,f)){f=a.isWebGLRenderTargetCube?34067:3553;var g=d.get(b).__webglTexture;c.bindTexture(f,g);t(f,b,a.width,a.height);c.bindTexture(f,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(e.isWebGL2){var c=d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer); -c=b.width;var f=b.height,g=16384;b.depthBuffer&&(g|=256);b.stencilBuffer&&(g|=1024);a.blitFramebuffer(0,0,c,f,0,0,c,f,g,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===J&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."),J=!0),a=a.texture);v(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&& -(!1===K&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."),K=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?A(a,b):w(a,b)}}function Dh(a,b,c){return{convert:function(a){if(1E3===a)return 10497;if(1001===a)return 33071;if(1002===a)return 33648;if(1003===a)return 9728;if(1004===a)return 9984;if(1005===a)return 9986;if(1006===a)return 9729;if(1007===a)return 9985;if(1008===a)return 9987; -if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010===a)return 5120;if(1011===a)return 5122;if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(c.isWebGL2)return 5131;var d=b.get("OES_texture_half_float");if(null!==d)return d.HALF_FLOAT_OES}if(1021===a)return 6406;if(1022===a)return 6407;if(1023===a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027=== -a)return 34041;if(1028===a)return 6403;if(100===a)return 32774;if(101===a)return 32778;if(102===a)return 32779;if(200===a)return 0;if(201===a)return 1;if(202===a)return 768;if(203===a)return 769;if(204===a)return 770;if(205===a)return 771;if(206===a)return 772;if(207===a)return 773;if(208===a)return 774;if(209===a)return 775;if(210===a)return 776;if(33776===a||33777===a||33778===a||33779===a)if(d=b.get("WEBGL_compressed_texture_s3tc"),null!==d){if(33776===a)return d.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777=== -a)return d.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return d.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return d.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840===a||35841===a||35842===a||35843===a)if(d=b.get("WEBGL_compressed_texture_pvrtc"),null!==d){if(35840===a)return d.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return d.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return d.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return d.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196===a&&(d=b.get("WEBGL_compressed_texture_etc1"), -null!==d))return d.COMPRESSED_RGB_ETC1_WEBGL;if(37808===a||37809===a||37810===a||37811===a||37812===a||37813===a||37814===a||37815===a||37816===a||37817===a||37818===a||37819===a||37820===a||37821===a)if(d=b.get("WEBGL_compressed_texture_astc"),null!==d)return a;if(103===a||104===a){if(c.isWebGL2){if(103===a)return 32775;if(104===a)return 32776}d=b.get("EXT_blend_minmax");if(null!==d){if(103===a)return d.MIN_EXT;if(104===a)return d.MAX_EXT}}if(1020===a){if(c.isWebGL2)return 34042;d=b.get("WEBGL_depth_texture"); -if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}function Jc(){C.call(this);this.type="Group"}function Jd(a){la.call(this);this.cameras=a||[]}function Eh(a,b,c){Fh.setFromMatrixPosition(b.matrixWorld);Gh.setFromMatrixPosition(c.matrixWorld);var d=Fh.distanceTo(Gh),e=b.projectionMatrix.elements,f=c.projectionMatrix.elements,g=e[14]/(e[10]-1);c=e[14]/(e[10]+1);var h=(e[9]+1)/e[5],l=(e[9]-1)/e[5],m=(e[8]-1)/e[0],r=(f[8]+1)/f[0];e=g*m;f=g*r;r=d/(-m+r);m=r*-m;b.matrixWorld.decompose(a.position, -a.quaternion,a.scale);a.translateX(m);a.translateZ(r);a.matrixWorld.compose(a.position,a.quaternion,a.scale);a.matrixWorldInverse.getInverse(a.matrixWorld);b=g+r;g=c+r;a.projectionMatrix.makePerspective(e-m,f+(d-m),h*c/g*b,l*c/g*b,b,g)}function $f(a){function b(){return null!==h&&!0===h.isPresenting}function c(){if(b()){var c=h.getEyeParameters("left");e=2*c.renderWidth*q;f=c.renderHeight*q;Ga=a.getPixelRatio();a.getSize(B);a.setDrawingBufferSize(e,f,1);w.viewport.set(0,0,e/2,f);I.viewport.set(e/ -2,0,e/2,f);z.start();g.dispatchEvent({type:"sessionstart"})}else g.enabled&&a.setDrawingBufferSize(B.width,B.height,Ga),z.stop(),g.dispatchEvent({type:"sessionend"})}function d(a,b){null!==b&&4===b.length&&a.set(b[0]*e,b[1]*f,b[2]*e,b[3]*f)}var e,f,g=this,h=null,l=null,m=null,r=[],t=new M,k=new M,q=1,p="local-floor";"undefined"!==typeof window&&"VRFrameData"in window&&(l=new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var x=new M,v=new na,A=new n,w=new la;w.viewport= -new ha;w.layers.enable(1);var I=new la;I.viewport=new ha;I.layers.enable(2);var G=new Jd([w,I]);G.layers.enable(1);G.layers.enable(2);var B=new y,Ga,Z=[];this.enabled=!1;this.getController=function(a){var b=r[a];void 0===b&&(b=new Jc,b.matrixAutoUpdate=!1,b.visible=!1,r[a]=b);return b};this.getDevice=function(){return h};this.setDevice=function(a){void 0!==a&&(h=a);z.setContext(a)};this.setFramebufferScaleFactor=function(a){q=a};this.setReferenceSpaceType=function(a){p=a};this.setPoseTarget=function(a){void 0!== -a&&(m=a)};this.getCamera=function(a){var c="local-floor"===p?1.6:0;if(!1===b())return a.position.set(0,c,0),a.rotation.set(0,0,0),a;h.depthNear=a.near;h.depthFar=a.far;h.getFrameData(l);if("local-floor"===p){var e=h.stageParameters;e?t.fromArray(e.sittingToStandingTransform):t.makeTranslation(0,c,0)}c=l.pose;e=null!==m?m:a;e.matrix.copy(t);e.matrix.decompose(e.position,e.quaternion,e.scale);null!==c.orientation&&(v.fromArray(c.orientation),e.quaternion.multiply(v));null!==c.position&&(v.setFromRotationMatrix(t), -A.fromArray(c.position),A.applyQuaternion(v),e.position.add(A));e.updateMatrixWorld();w.near=a.near;I.near=a.near;w.far=a.far;I.far=a.far;w.matrixWorldInverse.fromArray(l.leftViewMatrix);I.matrixWorldInverse.fromArray(l.rightViewMatrix);k.getInverse(t);"local-floor"===p&&(w.matrixWorldInverse.multiply(k),I.matrixWorldInverse.multiply(k));a=e.parent;null!==a&&(x.getInverse(a.matrixWorld),w.matrixWorldInverse.multiply(x),I.matrixWorldInverse.multiply(x));w.matrixWorld.getInverse(w.matrixWorldInverse); -I.matrixWorld.getInverse(I.matrixWorldInverse);w.projectionMatrix.fromArray(l.leftProjectionMatrix);I.projectionMatrix.fromArray(l.rightProjectionMatrix);Eh(G,w,I);a=h.getLayers();a.length&&(a=a[0],d(w.viewport,a.leftBounds),d(I.viewport,a.rightBounds));a:for(a=0;af.matrixWorld.determinant();fa.setMaterial(e,h);var l=u(a,c,e,f),m=!1;if(b!==d.id||Y!==l.id||aa!==(!0===e.wireframe))b=d.id,Y=l.id,aa=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(ya.update(f,d,e,l),m=!0);h=d.index;var r=d.attributes.position;c=1;!0===e.wireframe&&(h=va.getWireframeAttribute(d),c=2);a=Aa;if(null!==h){var k=ua.get(h);a=Ba;a.setIndex(k)}if(m){if(d&&d.isInstancedBufferGeometry&& -!Ea.isWebGL2&&null===oa.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");else{fa.initAttributes();m=d.attributes;l=l.getAttributes();var t=e.defaultAttributeValues;for(G in l){var p=l[G];if(0<=p){var q=m[G];if(void 0!==q){var n=q.normalized,x=q.itemSize,v=ua.get(q);if(void 0!==v){var w=v.buffer,A=v.type;v=v.bytesPerElement;if(q.isInterleavedBufferAttribute){var B= -q.data,I=B.stride;q=q.offset;B&&B.isInstancedInterleavedBuffer?(fa.enableAttributeAndDivisor(p,B.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=B.meshPerAttribute*B.count)):fa.enableAttribute(p);N.bindBuffer(34962,w);N.vertexAttribPointer(p,x,A,n,I*v,q*v)}else q.isInstancedBufferAttribute?(fa.enableAttributeAndDivisor(p,q.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=q.meshPerAttribute*q.count)):fa.enableAttribute(p),N.bindBuffer(34962,w),N.vertexAttribPointer(p, -x,A,n,0,0)}}else if(void 0!==t&&(n=t[G],void 0!==n))switch(n.length){case 2:N.vertexAttrib2fv(p,n);break;case 3:N.vertexAttrib3fv(p,n);break;case 4:N.vertexAttrib4fv(p,n);break;default:N.vertexAttrib1fv(p,n)}}}fa.disableUnusedAttributes()}null!==h&&N.bindBuffer(34963,k.buffer)}k=Infinity;null!==h?k=h.count:void 0!==r&&(k=r.count);h=d.drawRange.start*c;r=null!==g?g.start*c:0;var G=Math.max(h,r);g=Math.max(0,Math.min(k,h+d.drawRange.count*c,r+(null!==g?g.count*c:Infinity))-1-G+1);if(0!==g){if(f.isMesh)if(!0=== -e.wireframe)fa.setLineWidth(e.wireframeLinewidth*(null===P?ea:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),fa.setLineWidth(e*(null===P?ea:1)),f.isLineSegments?a.setMode(1):f.isLineLoop?a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);d&&d.isInstancedBufferGeometry?0e.far||f.push({distance:a,distanceToRay:Math.sqrt(h),point:c,index:b,face:null,object:g}))}function eg(a,b,c,d,e,f,g,h,l){Y.call(this,a,b,c,d,e,f,g,h,l);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Nc(a,b,c,d,e,f,g,h,l,m,r,k){Y.call(this,null,f,g,h,l,m,d,e,r,k);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function Pd(a, -b,c,d,e,f,g,h,l){Y.call(this,a,b,c,d,e,f,g,h,l);this.needsUpdate=!0}function Qd(a,b,c,d,e,f,g,h,l,m){m=void 0!==m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);Y.call(this,null,d,e,f,g,h,m,c,l);this.image={width:a,height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!==h?h:1003;this.generateMipmaps=this.flipY=!1}function Oc(a){D.call(this);this.type= -"WireframeGeometry";var b=[],c,d,e,f=[0,0],g={},h=["a","b","c"];if(a&&a.isGeometry){var l=a.faces;var m=0;for(d=l.length;mc;c++){var k=r[h[c]];var u=r[h[(c+1)%3]];f[0]=Math.min(k,u);f[1]=Math.max(k,u);k=f[0]+","+f[1];void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]})}}for(k in g)m=g[k],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){l=a.attributes.position;r=a.index;var q=a.groups; -0===q.length&&(q=[{start:0,count:r.count,materialIndex:0}]);a=0;for(e=q.length;ac;c++)k=r.getX(m+c),u=r.getX(m+(c+1)%3),f[0]=Math.min(k,u),f[1]=Math.max(k,u),k=f[0]+","+f[1],void 0===g[k]&&(g[k]={index1:f[0],index2:f[1]});for(k in g)m=g[k],h.fromBufferAttribute(l,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(l,m.index2),b.push(h.x,h.y,h.z)}else for(l=a.attributes.position,m=0,d=l.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(l, -g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z);this.addAttribute("position",new z(b,3))}function Rd(a,b,c){F.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Pc(a,b,c));this.mergeVertices()}function Pc(a,b,c){D.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,l=new n,m=new n,r=new n,k=new n,u,q;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter."); -var p=b+1;for(u=0;u<=c;u++){var x=u/c;for(q=0;q<=b;q++){var v=q/b;a(v,x,l);e.push(l.x,l.y,l.z);0<=v-1E-5?(a(v-1E-5,x,m),r.subVectors(l,m)):(a(v+1E-5,x,m),r.subVectors(m,l));0<=x-1E-5?(a(v,x-1E-5,m),k.subVectors(l,m)):(a(v,x+1E-5,m),k.subVectors(m,l));h.crossVectors(r,k).normalize();f.push(h.x,h.y,h.z);g.push(v,x)}}for(u=0;ud&&1===a.x&&(l[b]=a.x-1);0===c.x&&0===c.z&&(l[b]=d/2/Math.PI+.5)}D.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a, -indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],l=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(l[a+0]+=1),.2>c&&(l[a+2]+=1),.2>d&&(l[a+4]+=1))})();this.addAttribute("position",new z(h,3));this.addAttribute("normal",new z(h.slice(),3));this.addAttribute("uv",new z(l,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Td(a, -b){F.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Qc(a,b));this.mergeVertices()}function Qc(a,b){pa.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Ud(a,b){F.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new cc(a,b));this.mergeVertices()}function cc(a,b){pa.call(this,[1,0,0, --1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Vd(a,b){F.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Rc(a,b));this.mergeVertices()}function Rc(a,b){var c=(1+Math.sqrt(5))/2;pa.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5, -11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Wd(a,b){F.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Sc(a,b));this.mergeVertices()}function Sc(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;pa.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c, -0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Xd(a,b,c,d,e,f){F.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d, -closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new dc(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function dc(a,b,c,d,e){function f(e){r=a.getPointAt(e/b,r);var f=g.normals[e];e=g.binormals[e];for(u=0;u<=d;u++){var m=u/d*Math.PI*2,k=Math.sin(m);m=-Math.cos(m);l.x=m*f.x+k*e.x;l.y=m*f.y+k*e.y;l.z=m*f.z+k*e.z;l.normalize();p.push(l.x,l.y,l.z);h.x=r.x+c*l.x;h.y=r.y+c*l.y;h.z= -r.z+c*l.z;q.push(h.x,h.y,h.z)}}D.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,l=new n,m=new y,r=new n,k,u,q=[],p=[],x=[],v=[];for(k=0;k=b;e-=d)f=Lh(e,a[e],a[e+1],f);f&&ec(f,f.next)&&($d(f),f=f.next);return f}function ae(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!ec(a,a.next)&&0!==ua(a.prev,a,a.next))a=a.next;else{$d(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b} -function be(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,l=h;do null===l.z&&(l.z=fg(l.x,l.y,d,e,f)),l.prevZ=l.prev,l=l.nextZ=l.next;while(l!==h);l.prevZ.nextZ=null;l.prevZ=null;h=l;var m,r,k,u,q=1;do{l=h;var p=h=null;for(r=0;l;){r++;var n=l;for(m=k=0;mn!==p.next.y>n&&p.next.y!==p.y&&k<(p.next.x-p.x)*(n-p.y)/(p.next.y-p.y)+p.x&&(r=!r),p=p.next;while(p!==l);p=r}l=p}if(l){a=Nh(g,h);g=ae(g,g.next);a=ae(a,a.next);be(g,b,c,d,e,f);be(a,b,c,d,e,f);break a}h= -h.next}g=g.next}while(g!==a)}break}}}}function dk(a,b,c,d){var e=a.prev,f=a.next;if(0<=ua(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,l=fg(e.x=l&&d&&d.z<=b;){if(c!==a.prev&&c!==a.next&&Vc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=ua(c.prev,c,c.next))return!1;c=c.prevZ;if(d!==a.prev&&d!==a.next&&Vc(e.x,e.y,a.x,a.y, -f.x,f.y,d.x,d.y)&&0<=ua(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=l;){if(c!==a.prev&&c!==a.next&&Vc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=ua(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&Vc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=ua(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function ek(a,b){return a.x-b.x}function fk(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f= -g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&Vc(eh.x)&&ce(c,a)&&(h=c,m=r)}c=c.next}return h}function fg(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b| -b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function gk(a){var b=a,c=a;do{if(b.xua(a.prev,a,a.next)?0<=ua(a,b,a.next)&&0<=ua(a,a.prev,b):0>ua(a,b,a.prev)||0>ua(a,a.next,b)}function Nh(a,b){var c=new gg(a.i,a.x,a.y),d=new gg(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function Lh(a,b,c,d){a=new gg(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function $d(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ= -a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function gg(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Oh(a){var b=a.length;2Number.EPSILON){var l=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/l;b=b.y+d/l;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new y(f,d);e=Math.sqrt(e/2)}else a=!1,d>Number.EPSILON?f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)=== -Math.sign(g)&&(a=!0),a?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new y(f/e,d/e)}function h(a,b){for(L=a.length;0<=--L;){var c=L;var f=L-1;0>f&&(f=a.length-1);var g,h=w+2*C;for(g=0;gk;k++){var t=m[f[k]];var n=m[f[(k+1)%3]];d[0]=Math.min(t,n);d[1]=Math.max(t,n);t=d[0]+","+d[1];void 0===e[t]?e[t]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[t].face2=h}for(t in e)if(d=e[t],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new z(c,3))}function ic(a,b,c,d, -e,f,g,h){F.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new sb(a,b,c,d,e,f,g,h));this.mergeVertices()}function sb(a,b,c,d,e,f,g,h){function l(c){var e,f=new y,l=new n,r=0,x=!0===c?a:b,w=!0===c?1:-1;var z=p;for(e=1;e<=d;e++)t.push(0,v*w,0),u.push(0,w,0),q.push(.5,.5),p++;var E=p;for(e=0;e<=d;e++){var C=e/d*h+g,D=Math.cos(C);C=Math.sin(C);l.x=x*C;l.y=v*w; -l.z=x*D;t.push(l.x,l.y,l.z);u.push(0,w,0);f.x=.5*D+.5;f.y=.5*C*w+.5;q.push(f.x,f.y);p++}for(e=0;ethis.duration&&this.resetDuration()}function ik(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return bd;case "vector":case "vector2":case "vector3":case "vector4":return cd; -case "color":return Te;case "quaternion":return le;case "bool":case "boolean":return Se;case "string":return Ve}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function jk(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=ik(a.type);if(void 0===a.times){var c=[],d=[];ba.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function hg(a,b,c){var d=this,e= -!1,f=0,g=0,h=void 0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this}}function Ra(a){this.manager=void 0!==a?a:Da}function Sh(a){this.manager= -void 0!==a?a:Da}function Th(a){this.manager=void 0!==a?a:Da;this._parser=null}function ig(a){this.manager=void 0!==a?a:Da;this._parser=null}function me(a){this.manager=void 0!==a?a:Da}function jg(a){this.manager=void 0!==a?a:Da}function We(a){this.manager=void 0!==a?a:Da}function H(){this.type="Curve";this.arcLengthDivisions=200}function Ja(a,b,c,d,e,f,g,h){H.call(this);this.type="EllipseCurve";this.aX=a||0;this.aY=b||0;this.xRadius=c||1;this.yRadius=d||1;this.aStartAngle=e||0;this.aEndAngle=f||2* -Math.PI;this.aClockwise=g||!1;this.aRotation=h||0}function dd(a,b,c,d,e,f){Ja.call(this,a,b,c,c,d,e,f);this.type="ArcCurve"}function kg(){var a=0,b=0,c=0,d=0;return{initCatmullRom:function(e,f,g,h,l){e=l*(g-e);h=l*(h-f);a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},initNonuniformCatmullRom:function(e,f,g,h,l,m,k){e=((f-e)/l-(g-e)/(l+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+k)+(h-g)/k)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function wa(a,b,c,d){H.call(this); -this.type="CatmullRomCurve3";this.points=a||[];this.closed=b||!1;this.curveType=c||"centripetal";this.tension=d||.5}function Uh(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function ne(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function oe(a,b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}function Sa(a,b,c,d){H.call(this);this.type="CubicBezierCurve";this.v0=a||new y;this.v1=b||new y;this.v2=c||new y;this.v3=d||new y}function hb(a, -b,c,d){H.call(this);this.type="CubicBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n;this.v3=d||new n}function za(a,b){H.call(this);this.type="LineCurve";this.v1=a||new y;this.v2=b||new y}function Ta(a,b){H.call(this);this.type="LineCurve3";this.v1=a||new n;this.v2=b||new n}function Ua(a,b,c){H.call(this);this.type="QuadraticBezierCurve";this.v0=a||new y;this.v1=b||new y;this.v2=c||new y}function ib(a,b,c){H.call(this);this.type="QuadraticBezierCurve3";this.v0=a||new n;this.v1=b|| -new n;this.v2=c||new n}function Va(a){H.call(this);this.type="SplineCurve";this.points=a||[]}function tb(){H.call(this);this.type="CurvePath";this.curves=[];this.autoClose=!1}function Wa(a){tb.call(this);this.type="Path";this.currentPoint=new y;a&&this.setFromPoints(a)}function Kb(a){Wa.call(this,a);this.uuid=O.generateUUID();this.type="Shape";this.holes=[]}function T(a,b){C.call(this);this.type="Light";this.color=new K(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0}function Xe(a,b,c){T.call(this, -a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(C.DefaultUp);this.updateMatrix();this.groundColor=new K(b)}function qc(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new y(512,512);this.map=null;this.matrix=new M}function Ye(){qc.call(this,new la(50,1,.5,500))}function Ze(a,b,c,d,e,f){T.call(this,a,b);this.type="SpotLight";this.position.copy(C.DefaultUp);this.updateMatrix();this.target=new C;Object.defineProperty(this,"power",{get:function(){return this.intensity* -Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Ye}function $e(a,b,c,d){T.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new qc(new la(90,1,.5,500))}function pe(a,b,c,d,e,f){cb.call(this); -this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=void 0!==a?a:-1;this.right=void 0!==b?b:1;this.top=void 0!==c?c:1;this.bottom=void 0!==d?d:-1;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function af(){qc.call(this,new pe(-5,5,5,-5,.5,500))}function bf(a,b){T.call(this,a,b);this.type="DirectionalLight";this.position.copy(C.DefaultUp);this.updateMatrix();this.target=new C;this.shadow=new af}function cf(a,b){T.call(this,a,b);this.type="AmbientLight"; -this.castShadow=void 0}function df(a,b,c,d){T.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function ef(a){this.manager=void 0!==a?a:Da;this.textures={}}function ff(){D.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function gf(a,b,c,d){"number"===typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument."));R.call(this,a,b,c);this.meshPerAttribute= -d||1}function lg(a){this.manager=void 0!==a?a:Da}function mg(a){this.manager=void 0!==a?a:Da;this.resourcePath=""}function ng(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported.");this.manager=void 0!==a?a:Da;this.options=void 0}function og(){this.type="ShapePath";this.color=new K;this.subPaths=[];this.currentPath=null}function pg(a){this.type= -"Font";this.data=a}function Vh(a){this.manager=void 0!==a?a:Da}function qe(){}function jb(a,b,c,d,e,f,g,h){a=g+a;g=qe.Handlers.get(a);null!==g?h=g.load(a):(Wh.setCrossOrigin(h),h=Wh.load(a));void 0!==b&&(h.repeat.fromArray(b),1!==b[0]&&(h.wrapS=1E3),1!==b[1]&&(h.wrapT=1E3));void 0!==c&&h.offset.fromArray(c);void 0!==d&&("repeat"===d[0]&&(h.wrapS=1E3),"mirror"===d[0]&&(h.wrapS=1002),"repeat"===d[1]&&(h.wrapT=1E3),"mirror"===d[1]&&(h.wrapT=1002));void 0!==e&&(h.anisotropy=e);b=O.generateUUID();f[b]= -h;return b}function qg(a){this.manager=void 0!==a?a:Da}function hf(){this.coefficients=[];for(var a=0;9>a;a++)this.coefficients.push(new n)}function Xa(a,b){T.call(this,void 0,b);this.sh=void 0!==a?a:new hf}function rg(a,b,c){Xa.call(this,void 0,c);a=(new K).set(a);c=(new K).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)}function sg(a,b){Xa.call(this, -void 0,b);a=(new K).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))}function Xh(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new la;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new la;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1;this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}function tg(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime= -this.startTime=0;this.running=!1}function ug(){C.call(this);this.type="AudioListener";this.context=vg.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0;this._clock=new tg}function ed(a){C.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.startTime=0;this.playbackRate= -1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function wg(a){ed.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function xg(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function yg(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b= -this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function Yh(a,b,c){c=c||ra.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function ra(a,b,c){this.path=b;this.parsedPath=c||ra.parseTrackName(b);this.node=ra.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Zh(){this.uuid=O.generateUUID();this._objects=Array.prototype.slice.call(arguments); -this.nCachedObjects_=0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function $h(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400, -endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd= -this.zeroSlopeAtStart=!0}function zg(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function jf(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Ag(a,b,c){bc.call(this,a,b);this.meshPerAttribute=c||1}function ai(a,b,c,d){this.ray=new Tb(a,b);this.near=c||0;this.far=d||Infinity;this.camera=null;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params, -{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})}function bi(a,b){return a.distance-b.distance}function Bg(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new z(b,3)); -b=new S({fog:!1});this.cone=new aa(a,b);this.add(this.cone);this.update()}function ei(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;ca?-1:0ye;ye++)qa[ye]=(16>ye?"0":"")+ -ye.toString(16);var O={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var a=4294967295*Math.random()|0,b=4294967295*Math.random()|0,c=4294967295*Math.random()|0,d=4294967295*Math.random()|0;return(qa[a&255]+qa[a>>8&255]+qa[a>>16&255]+qa[a>>24&255]+"-"+qa[b&255]+qa[b>>8&255]+"-"+qa[b>>16&15|64]+qa[b>>24&255]+"-"+qa[c&63|128]+qa[c>>8&255]+"-"+qa[c>>16&255]+qa[c>>24&255]+qa[d&255]+qa[d>>8&255]+qa[d>>16&255]+qa[d>>24&255]).toUpperCase()},clamp:function(a,b,c){return Math.max(b,Math.min(c, -a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,b,c){return(1-c)*a+c*b},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a* -(.5-Math.random())},degToRad:function(a){return a*O.DEG2RAD},radToDeg:function(a){return a*O.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(y.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(y.prototype, -{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x, -this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), -this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y= -a[1]*b+a[4]*c+a[7];return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| -1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x* -a.x+this.y*a.y},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b= -this.x-a.x;a=this.y-a.y;return b*b+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a, -b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(na,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h= -c[d+0],l=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var k=e[f+1],t=e[f+2];e=e[f+3];if(c!==e||h!==d||l!==k||m!==t){f=1-g;var n=h*d+l*k+m*t+c*e,q=0<=n?1:-1,p=1-n*n;p>Number.EPSILON&&(p=Math.sqrt(p),n=Math.atan2(p,n*q),f=Math.sin(f*n)/p,g=Math.sin(g*n)/p);q*=g;h=h*f+d*q;l=l*f+k*q;m=m*f+t*q;c=c*f+e*q;f===1-g&&(g=1/Math.sqrt(h*h+l*l+m*m+c*c),h*=g,l*=g,m*=g,c*=g)}a[b]=h;a[b+1]=l;a[b+2]=m;a[b+3]=c}});Object.defineProperties(na.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}}, -y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(na.prototype,{isQuaternion:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x= -a.x;this._y=a.y;this._z=a.z;this._w=a.w;this._onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),l=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"YXZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z= -h*l*e-c*d*f,this._w=h*l*f+c*d*e):"ZXY"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"ZYX"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f+c*d*e):"YZX"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f-c*d*e):"XZY"===a&&(this._x=c*l*f-h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b); -this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this._onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],l=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(l-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+l)/ -c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+l)/c,this._z=.25*c);this._onChangeCallback();return this},setFromUnitVectors:function(a,b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(O.clamp(this.dot(a),-1,1)))},rotateTowards:function(a, -b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this._onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a= -this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this._onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w; -var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this._onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g* -f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this._onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2]; -this._w=a[b+3];this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});var Gg=new n,hi=new na;Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y= -a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this}, -add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), -this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*= -a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(a){a&&a.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(hi.setFromEuler(a))},applyAxisAngle:function(a,b){return this.applyQuaternion(hi.setFromAxisAngle(a,b))},applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]* -d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,l=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+l*-g-m*-f;this.y=l*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-l*-e;return this}, -project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/ -a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a, -Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x= -0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+ -Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this, -a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(a){Gg.copy(this).projectOnVector(a);return this.sub(Gg)},reflect:function(a){return this.sub(Gg.copy(a).multiplyScalar(2*this.dot(a)))},angleTo:function(a){a=this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(O.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))}, -distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)*a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta, -a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},equals:function(a){return a.x=== -this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});var rc=new n;Object.assign(sa.prototype,{isMatrix3:!0,set:function(a, -b,c,d,e,f,g,h,l){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=l;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this}, -applyToBufferAttribute:function(a){for(var b=0,c=a.count;bc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a}});var nd,Lb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===nd&&(nd=document.createElementNS("http://www.w3.org/1999/xhtml", -"canvas"));nd.width=a.width;nd.height=a.height;var b=nd.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=nd}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(Y.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(ha.prototype,{width:{get:function(){return this.z},set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(ha.prototype,{isVector4:!0,set:function(a,b,c,d){this.x= -a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x; -case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this}, -addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-= -a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/ -a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var l=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g-l)){if(.1>Math.abs(c+e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+l)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI; -b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+l)/4;b>f&&b>m?.01>b?(l=0,c=h=.707106781):(l=Math.sqrt(b),h=c/l,c=d/l):f>m?.01>f?(l=.707106781,h=0,c=.707106781):(h=Math.sqrt(f),l=c/h,c=g/h):.01>m?(h=l=.707106781,c=0):(c=Math.sqrt(m),l=d/c,h=g/c);this.set(l,h,c,a);return this}a=Math.sqrt((l-g)*(l-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(l-g)/a;this.y=(d-h)/a;this.z=(e-c)/a;this.w=Math.acos((b+f+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y, -a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b, -this.y));this.z=Math.max(a,Math.min(b,this.z));this.w=Math.max(a,Math.min(b,this.w));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x= -Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z* -a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z- -this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute()."); -this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});ab.prototype=Object.assign(Object.create(ma.prototype),{constructor:ab,isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.texture.image.width=a,this.texture.image.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport); -this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Mf.prototype=Object.assign(Object.create(ab.prototype),{constructor:Mf,isWebGLMultisampleRenderTarget:!0,copy:function(a){ab.prototype.copy.call(this,a);this.samples=a.samples;return this}});var Ka=new n,U=new M,kk=new n(0,0,0),lk=new n(1,1,1),Mb=new n,of=new n,Aa=new n;Object.assign(M.prototype,{isMatrix4:!0, -set:function(a,b,c,d,e,f,g,h,l,m,k,t,n,q,p,x){var r=this.elements;r[0]=a;r[4]=b;r[8]=c;r[12]=d;r[1]=e;r[5]=f;r[9]=g;r[13]=h;r[2]=l;r[6]=m;r[10]=k;r[14]=t;r[3]=n;r[7]=q;r[11]=p;r[15]=x;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new M).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11]; -b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},copyPosition:function(a){var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(a){var b=this.elements,c=a.elements,d=1/Ka.setFromMatrixColumn(a,0).length(), -e=1/Ka.setFromMatrixColumn(a,1).length();a=1/Ka.setFromMatrixColumn(a,2).length();b[0]=c[0]*d;b[1]=c[1]*d;b[2]=c[2]*d;b[3]=0;b[4]=c[4]*e;b[5]=c[5]*e;b[6]=c[6]*e;b[7]=0;b[8]=c[8]*a;b[9]=c[9]*a;b[10]=c[10]*a;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d); -d=Math.sin(d);var h=Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a=f*h;var l=f*e,m=c*h,k=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=l+m*d;b[5]=a-k*d;b[9]=-c*g;b[2]=k-a*d;b[6]=m+l*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a+k*c,b[4]=m*c-l,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=l*c-m,b[6]=k+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a-k*c,b[4]=-f*e,b[8]=m+l*c,b[1]=l+m*c,b[5]=f*h,b[9]=k-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,l=f*e,m=c*h,k=c*e,b[0]=g*h, -b[4]=m*d-l,b[8]=a*d+k,b[1]=g*e,b[5]=k*d+a,b[9]=l*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=k-a*e,b[8]=m*e+l,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=l*e+m,b[10]=a-k*e):"XZY"===a.order&&(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+k,b[5]=f*h,b[9]=l*e-m,b[2]=m*e-l,b[6]=c*h,b[10]=k*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(a){return this.compose(kk,a,lk)},lookAt:function(a,b, -c){var d=this.elements;Aa.subVectors(a,b);0===Aa.lengthSq()&&(Aa.z=1);Aa.normalize();Mb.crossVectors(c,Aa);0===Mb.lengthSq()&&(1===Math.abs(c.z)?Aa.x+=1E-4:Aa.z+=1E-4,Aa.normalize(),Mb.crossVectors(c,Aa));Mb.normalize();of.crossVectors(Aa,Mb);d[0]=Mb.x;d[4]=of.x;d[8]=Aa.x;d[1]=Mb.y;d[5]=of.y;d[9]=Aa.y;d[2]=Mb.z;d[6]=of.z;d[10]=Aa.z;return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."), -this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],l=c[5],m=c[9],k=c[13],n=c[2],u=c[6],q=c[10],p=c[14],x=c[3],v=c[7],A=c[11];c=c[15];var w=d[0],y=d[4],G=d[8],B=d[12],z=d[1],C=d[5],D=d[9],F=d[13],E=d[2],H=d[6],J=d[10],K=d[14],M=d[3],O=d[7],P=d[11];d=d[15];b[0]=a*w+e*z+f*E+g*M;b[4]=a*y+e*C+f*H+g*O;b[8]=a*G+e*D+f*J+ -g*P;b[12]=a*B+e*F+f*K+g*d;b[1]=h*w+l*z+m*E+k*M;b[5]=h*y+l*C+m*H+k*O;b[9]=h*G+l*D+m*J+k*P;b[13]=h*B+l*F+m*K+k*d;b[2]=n*w+u*z+q*E+p*M;b[6]=n*y+u*C+q*H+p*O;b[10]=n*G+u*D+q*J+p*P;b[14]=n*B+u*F+q*K+p*d;b[3]=x*w+v*z+A*E+c*M;b[7]=x*y+v*C+A*H+c*O;b[11]=x*G+v*D+A*J+c*P;b[15]=x*B+v*F+A*K+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},applyToBufferAttribute:function(a){for(var b= -0,c=a.count;bthis.determinant()&&(e=-e);a.x=d[12];a.y=d[13];a.z=d[14];U.copy(this);a=1/e;d=1/f;var h=1/g;U.elements[0]*=a;U.elements[1]*=a;U.elements[2]*=a;U.elements[4]*=d;U.elements[5]*=d;U.elements[6]*=d;U.elements[8]*=h;U.elements[9]*=h;U.elements[10]*=h;b.setFromRotationMatrix(U);c.x=e;c.y=f;c.z=g;return this},makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); -var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),l=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*l;g[9]=0;g[13]=-((c+d)*l);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements; -a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}});var ii=new M,ji=new na;Rb.RotationOrders= -"XYZ YZX ZXY XZY YXZ ZYX".split(" ");Rb.DefaultOrder="XYZ";Object.defineProperties(Rb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(Rb.prototype,{isEuler:!0,set:function(a, -b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this._onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=O.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],l=e[5],m=e[9],k=e[2],n=e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.9999999>Math.abs(g)? -(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(n,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.9999999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,l)):(this._y=Math.atan2(-k,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(n,-1,1)),.9999999>Math.abs(n)?(this._y=Math.atan2(-k,e),this._z=Math.atan2(-f,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(k,-1,1)),.9999999>Math.abs(k)?(this._x=Math.atan2(n,e),this._z=Math.atan2(h,a)): -(this._x=0,this._z=Math.atan2(-f,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.9999999>Math.abs(h)?(this._x=Math.atan2(-m,l),this._y=Math.atan2(-k,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.9999999>Math.abs(f)?(this._x=Math.atan2(n,l),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(a, -b,c){ii.makeRotationFromQuaternion(a);return this.setFromRotationMatrix(ii,b,c)},setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(a){ji.setFromEuler(this);return this.setFromQuaternion(ji,a)},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a= -[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(Nf.prototype,{set:function(a){this.mask=1<e&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d); -this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,l=a.count;he&&(e=m);k>f&&(f=k);n>g&&(g=n)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y), -(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(a){this.clampPoint(a.center,kb);return kb.distanceToSquared(a.center)<=a.radius*a.radius},intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(a){if(this.isEmpty())return!1;this.getCenter(Ae);qf.subVectors(this.max,Ae);pd.subVectors(a.a,Ae);qd.subVectors(a.b,Ae);rd.subVectors(a.c,Ae);Nb.subVectors(qd,pd);Ob.subVectors(rd,qd);sc.subVectors(pd,rd);a=[0,-Nb.z,Nb.y,0,-Ob.z,Ob.y,0,-sc.z, -sc.y,Nb.z,0,-Nb.x,Ob.z,0,-Ob.x,sc.z,0,-sc.x,-Nb.y,Nb.x,0,-Ob.y,Ob.x,0,-sc.y,sc.x,0];if(!Of(a,pd,qd,rd,qf))return!1;a=[1,0,0,0,1,0,0,0,1];if(!Of(a,pd,qd,rd,qf))return!1;rf.crossVectors(Nb,Ob);a=[rf.x,rf.y,rf.z];return Of(a,pd,qd,rd,qf)},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return kb.copy(a).clamp(this.min,this.max).sub(a).length()},getBoundingSphere:function(a){void 0=== -a&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(a.center);a.radius=.5*this.getSize(kb).length();return a},intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(a){if(this.isEmpty())return this;xb[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(a);xb[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(a); -xb[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(a);xb[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(a);xb[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(a);xb[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(a);xb[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(a);xb[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(a);this.setFromPoints(xb);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&& -a.max.equals(this.max)}});var qk=new bb;Object.assign(ob.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(a,b){var c=this.center;void 0!==b?c.copy(b):qk.setFromPoints(a).getCenter(c);for(var d=b=0,e=a.length;d= -this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a); -void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new bb);a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this}, -translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}});var yb=new n,Hg=new n,sf=new n,Pb=new n,Ig=new n,tf=new n,Jg=new n;Object.assign(Tb.prototype,{set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"), -b=new n);return b.copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(a){this.origin.copy(this.at(a,yb));return this},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"),b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))}, -distanceSqToPoint:function(a){var b=yb.subVectors(a,this.origin).dot(this.direction);if(0>b)return this.origin.distanceToSquared(a);yb.copy(this.direction).multiplyScalar(b).add(this.origin);return yb.distanceToSquared(a)},distanceSqToSegment:function(a,b,c,d){Hg.copy(a).add(b).multiplyScalar(.5);sf.copy(b).sub(a).normalize();Pb.copy(this.origin).sub(Hg);var e=.5*a.distanceTo(b),f=-this.direction.dot(sf),g=Pb.dot(this.direction),h=-Pb.dot(sf),l=Pb.lengthSq(),m=Math.abs(1-f*f);if(0=-k?b<=k?(e=1/m,a*=e,b*=e,f=a*(a+f*b+2*g)+b*(f*a+b+2*h)+l):(b=e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):(b=-e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):b<=-k?(a=Math.max(0,-(-f*e+g)),b=0a)return null;a=Math.sqrt(a-d);d=c-a;c+=a;return 0>d&&0>c?null:0>d?this.at(c,b):this.at(d,b)},intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+ -a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y- -f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null;if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(a){return null!==this.intersectBox(a,yb)},intersectTriangle:function(a,b,c,d,e){Ig.subVectors(b,a);tf.subVectors(c,a);Jg.crossVectors(Ig,tf);b=this.direction.dot(Jg);if(0b)d=-1,b=-b;else return null; -Pb.subVectors(this.origin,a);a=d*this.direction.dot(tf.crossVectors(Pb,tf));if(0>a)return null;c=d*this.direction.dot(Ig.cross(Pb));if(0>c||a+c>b)return null;a=-d*Pb.dot(Jg);return 0>a?null:this.at(a/b,e)},applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});var Ya=new n,zb=new n,Kg=new n,Ab=new n,sd=new n,td=new n,oi=new n,Lg=new n,Mg=new n,Ng=new n;Object.assign(ta, -{getNormal:function(a,b,c,d){void 0===d&&(console.warn("THREE.Triangle: .getNormal() target is now required"),d=new n);d.subVectors(c,b);Ya.subVectors(a,b);d.cross(Ya);a=d.lengthSq();return 0=Ab.x+Ab.y},getUV:function(a,b,c,d,e,f,g,h){this.getBarycoord(a,b,c,d,Ab);h.set(0,0);h.addScaledVector(e,Ab.x);h.addScaledVector(f,Ab.y);h.addScaledVector(g,Ab.z);return h},isFrontFacing:function(a,b,c,d){Ya.subVectors(c,b);zb.subVectors(a,b);return 0>Ya.cross(zb).dot(d)?!0:!1}});Object.assign(ta.prototype,{set:function(a, -b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},getArea:function(){Ya.subVectors(this.c,this.b);zb.subVectors(this.a,this.b);return.5*Ya.cross(zb).length()},getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"), -a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return ta.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new n);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return ta.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return ta.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return ta.containsPoint(a, -this.a,this.b,this.c)},isFrontFacing:function(a){return ta.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),b=new n);var c=this.a,d=this.b,e=this.c;sd.subVectors(d,c);td.subVectors(e,c);Lg.subVectors(a,c);var f=sd.dot(Lg),g=td.dot(Lg);if(0>=f&&0>=g)return b.copy(c);Mg.subVectors(a,d);var h=sd.dot(Mg),l=td.dot(Mg);if(0<=h&&l<= -h)return b.copy(d);var m=f*l-h*g;if(0>=m&&0<=f&&0>=h)return d=f/(f-h),b.copy(c).addScaledVector(sd,d);Ng.subVectors(a,e);a=sd.dot(Ng);var k=td.dot(Ng);if(0<=k&&a<=k)return b.copy(e);f=a*g-f*k;if(0>=f&&0<=g&&0>=k)return m=g/(g-k),b.copy(c).addScaledVector(td,m);g=h*k-a*l;if(0>=g&&0<=l-h&&0<=a-k)return oi.subVectors(e,d),m=(l-h)/(l-h+(a-k)),b.copy(d).addScaledVector(oi,m);e=1/(g+f+m);d=f*e;m*=e;return b.copy(c).addScaledVector(sd,d).addScaledVector(td,m)},equals:function(a){return a.a.equals(this.a)&& -a.b.equals(this.b)&&a.c.equals(this.c)}});var rk={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017, +// threejs.org/license +(function(k,Ea){"object"===typeof exports&&"undefined"!==typeof module?Ea(exports):"function"===typeof define&&define.amd?define(["exports"],Ea):(k=k||self,Ea(k.THREE={}))})(this,function(k){function Ea(){}function u(a,b){this.x=a||0;this.y=b||0}function wa(){this.elements=[1,0,0,0,1,0,0,0,1];0h)return!1}return!0}function pb(a,b){this.center=void 0!==a?a:new n;this.radius=void 0!==b?b:0}function Vb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n(0,0,-1)}function Ta(a,b){this.normal=void 0!==a?a:new n(1, +0,0);this.constant=void 0!==b?b:0}function oa(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!==b?b:new n;this.c=void 0!==c?c:new n}function z(a,b,c){return void 0===b&&void 0===c?this.set(a):this.setRGB(a,b,c)}function ag(a,b,c){0>c&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function bg(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function cg(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}function Bc(a,b,c,d,e,f){this.a=a;this.b= +b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new z;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0}function K(){Object.defineProperty(this,"id",{value:rj++});this.uuid=L.generateUUID();this.name="";this.type="Material";this.fog=!0;this.blending=1;this.side=0;this.vertexColors=this.flatShading=!1;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha= +this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.stencilWriteMask=255;this.stencilFunc=519;this.stencilRef=0;this.stencilFuncMask=255;this.stencilZPass=this.stencilZFail=this.stencilFail=7680;this.stencilWrite=!1;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha= +!1;this.toneMapped=this.visible=!0;this.userData={};this.version=0}function Oa(a){K.call(this);this.type="MeshBasicMaterial";this.color=new z(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphTargets=this.skinning=!1;this.setValues(a)} +function M(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.name="";this.array=a;this.itemSize=b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.usage=35044;this.updateRange={offset:0,count:-1};this.version=0}function Bd(a,b,c){M.call(this,new Int8Array(a),b,c)}function Cd(a,b,c){M.call(this,new Uint8Array(a),b,c)}function Dd(a,b,c){M.call(this,new Uint8ClampedArray(a),b,c)}function Ed(a,b,c){M.call(this,new Int16Array(a), +b,c)}function Wb(a,b,c){M.call(this,new Uint16Array(a),b,c)}function Fd(a,b,c){M.call(this,new Int32Array(a),b,c)}function Xb(a,b,c){M.call(this,new Uint32Array(a),b,c)}function A(a,b,c){M.call(this,new Float32Array(a),b,c)}function Gd(a,b,c){M.call(this,new Float64Array(a),b,c)}function xh(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate= +this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function yh(a){if(0===a.length)return-Infinity;for(var b=a[0],c=1,d=a.length;cb&&(b=a[c]);return b}function B(){Object.defineProperty(this,"id",{value:sj+=2});this.uuid=L.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.morphTargetsRelative=!1;this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity}; +this.userData={}}function S(a,b){E.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new B;this.material=void 0!==b?b:new Oa;this.updateMorphTargets()}function zh(a,b,c,d,e,f,g,h){if(null===(1===b.side?d.intersectTriangle(g,f,e,!0,h):d.intersectTriangle(e,f,g,2!==b.side,h)))return null;Je.copy(h);Je.applyMatrix4(a.matrixWorld);b=c.ray.origin.distanceTo(Je);return bc.far?null:{distance:b,point:Je.clone(),object:a}}function Ke(a,b,c,d,e,f,g,h,l,m,t,p){Yb.fromBufferAttribute(e,m);Zb.fromBufferAttribute(e, +t);$b.fromBufferAttribute(e,p);e=a.morphTargetInfluences;if(b.morphTargets&&f&&e){Le.set(0,0,0);Me.set(0,0,0);Ne.set(0,0,0);for(var x=0,r=f.length;xg;g++)a.setRenderTarget(f, +g),a.clear(b,c,d);a.setRenderTarget(e)}}function Db(a,b,c){Number.isInteger(b)&&(console.warn("THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )"),b=c);Ha.call(this,a,a,b)}function ac(a,b,c,d,e,f,g,h,l,m,t,p){W.call(this,null,f,g,h,l,m,d,e,t,p);this.image={data:a||null,width:b||1,height:c||1};this.magFilter=void 0!==l?l:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1;this.needsUpdate=!0}function Hc(a,b, +c,d,e,f){this.planes=[void 0!==a?a:new Ta,void 0!==b?b:new Ta,void 0!==c?c:new Ta,void 0!==d?d:new Ta,void 0!==e?e:new Ta,void 0!==f?f:new Ta]}function Ah(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)},stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function uj(a,b){function c(b,c){var d=b.array,e=b.usage,f=a.createBuffer();a.bindBuffer(c,f);a.bufferData(c, +d,e);b.onUploadCallback();c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:f,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var d=b.isWebGL2,e=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&& +(a=a.data);return e.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var c=e.get(b);c&&(a.deleteBuffer(c.buffer),e.delete(b))},update:function(b,g){b.isInterleavedBufferAttribute&&(b=b.data);var f=e.get(b);if(void 0===f)e.set(b,c(b,g));else if(f.versionm;m++){if(p=d[m])if(l=p[0],p=p[1]){t&&e.setAttribute("morphTarget"+m,t[l]);f&&e.setAttribute("morphNormal"+m,f[l]);c[m]=p;h+=p;continue}c[m]=0}e=e.morphTargetsRelative?1: +1-h;g.getUniforms().setValue(a,"morphTargetBaseInfluence",e);g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function Fj(a,b,c,d){var e=new WeakMap;return{update:function(a){var f=d.render.frame,h=a.geometry,l=b.get(a,h);e.get(l)!==f&&(h.isGeometry&&l.updateFromObject(a),b.update(l),e.set(l,f));a.isInstancedMesh&&c.update(a.instanceMatrix,34962);return l},dispose:function(){e=new WeakMap}}}function qb(a,b,c,d,e,f,g,h,l,m){a=void 0!==a?a:[];W.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g? +g:1022,h,l,m);this.flipY=!1}function Ic(a,b,c,d){W.call(this,null);this.image={data:a||null,width:b||1,height:c||1,depth:d||1};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1;this.needsUpdate=!0}function Jc(a,b,c,d){W.call(this,null);this.image={data:a||null,width:b||1,height:c||1,depth:d||1};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1;this.needsUpdate=!0}function Kc(a,b,c){var d=a[0];if(0>=d||0");return a.replace(ig,hg)}function Qh(a,b,c,d){console.warn("WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.");return jg(a,b,c,d)}function jg(a,b,c,d){a="";for(b=parseInt(b);bd;d++)c.probe.push(new n);var e=new n,f=new P,g=new P;return{setup:function(d,l,m){for(var h=0,p=0,k=0,r=0;9>r;r++)c.probe[r].set(0,0,0);var q=l=0,v=0,n=0,w=0,F=0,T=0,V=0;m=m.matrixWorldInverse;d.sort(Ek);r=0;for(var da=d.length;rJa;Ja++)c.probe[Ja].addScaledVector(y.sh.coefficients[Ja],ia);else if(y.isDirectionalLight){var H=a.get(y);H.color.copy(y.color).multiplyScalar(y.intensity);H.direction.setFromMatrixPosition(y.matrixWorld);e.setFromMatrixPosition(y.target.matrixWorld);H.direction.sub(e);H.direction.transformDirection(m);y.castShadow&&(ia=y.shadow,u=b.get(y),u.shadowBias=ia.bias,u.shadowRadius=ia.radius,u.shadowMapSize=ia.mapSize, +c.directionalShadow[l]=u,c.directionalShadowMap[l]=Ja,c.directionalShadowMatrix[l]=y.shadow.matrix,F++);c.directional[l]=H;l++}else y.isSpotLight?(H=a.get(y),H.position.setFromMatrixPosition(y.matrixWorld),H.position.applyMatrix4(m),H.color.copy(u).multiplyScalar(ia),H.distance=Ca,H.direction.setFromMatrixPosition(y.matrixWorld),e.setFromMatrixPosition(y.target.matrixWorld),H.direction.sub(e),H.direction.transformDirection(m),H.coneCos=Math.cos(y.angle),H.penumbraCos=Math.cos(y.angle*(1-y.penumbra)), +H.decay=y.decay,y.castShadow&&(ia=y.shadow,u=b.get(y),u.shadowBias=ia.bias,u.shadowRadius=ia.radius,u.shadowMapSize=ia.mapSize,c.spotShadow[v]=u,c.spotShadowMap[v]=Ja,c.spotShadowMatrix[v]=y.shadow.matrix,V++),c.spot[v]=H,v++):y.isRectAreaLight?(H=a.get(y),H.color.copy(u).multiplyScalar(ia),H.position.setFromMatrixPosition(y.matrixWorld),H.position.applyMatrix4(m),g.identity(),f.copy(y.matrixWorld),f.premultiply(m),g.extractRotation(f),H.halfWidth.set(.5*y.width,0,0),H.halfHeight.set(0,.5*y.height, +0),H.halfWidth.applyMatrix4(g),H.halfHeight.applyMatrix4(g),c.rectArea[n]=H,n++):y.isPointLight?(H=a.get(y),H.position.setFromMatrixPosition(y.matrixWorld),H.position.applyMatrix4(m),H.color.copy(y.color).multiplyScalar(y.intensity),H.distance=y.distance,H.decay=y.decay,y.castShadow&&(ia=y.shadow,u=b.get(y),u.shadowBias=ia.bias,u.shadowRadius=ia.radius,u.shadowMapSize=ia.mapSize,u.shadowCameraNear=ia.camera.near,u.shadowCameraFar=ia.camera.far,c.pointShadow[q]=u,c.pointShadowMap[q]=Ja,c.pointShadowMatrix[q]= +y.shadow.matrix,T++),c.point[q]=H,q++):y.isHemisphereLight&&(H=a.get(y),H.direction.setFromMatrixPosition(y.matrixWorld),H.direction.transformDirection(m),H.direction.normalize(),H.skyColor.copy(y.color).multiplyScalar(ia),H.groundColor.copy(y.groundColor).multiplyScalar(ia),c.hemi[w]=H,w++)}c.ambient[0]=h;c.ambient[1]=p;c.ambient[2]=k;d=c.hash;if(d.directionalLength!==l||d.pointLength!==q||d.spotLength!==v||d.rectAreaLength!==n||d.hemiLength!==w||d.numDirectionalShadows!==F||d.numPointShadows!== +T||d.numSpotShadows!==V)c.directional.length=l,c.spot.length=v,c.rectArea.length=n,c.point.length=q,c.hemi.length=w,c.directionalShadow.length=F,c.directionalShadowMap.length=F,c.pointShadow.length=T,c.pointShadowMap.length=T,c.spotShadow.length=V,c.spotShadowMap.length=V,c.directionalShadowMatrix.length=F,c.pointShadowMatrix.length=T,c.spotShadowMatrix.length=V,d.directionalLength=l,d.pointLength=q,d.spotLength=v,d.rectAreaLength=n,d.hemiLength=w,d.numDirectionalShadows=F,d.numPointShadows=T,d.numSpotShadows= +V,c.version=Gk++},state:c}}function Wh(){var a=new Fk,b=[],c=[];return{init:function(){b.length=0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)},pushShadow:function(a){c.push(a)}}}function Hk(){function a(c){c=c.target;c.removeEventListener("dispose",a);b.delete(c)}var b=new WeakMap;return{get:function(c,d){if(!1===b.has(c)){var e=new Wh;b.set(c,new WeakMap);b.get(c).set(d,e);c.addEventListener("dispose",a)}else!1=== +b.get(c).has(d)?(e=new Wh,b.get(c).set(d,e)):e=b.get(c).get(d);return e},dispose:function(){b=new WeakMap}}}function Fb(a){K.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.fog=!1;this.setValues(a)}function Gb(a){K.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance= +1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.fog=!1;this.setValues(a)}function Xh(a,b,c){function d(a,b,c){c=a<<0|b<<1|c<<2;var d=p[c];void 0===d&&(d=new Fb({depthPacking:3201,morphTargets:a,skinning:b}),p[c]=d);return d}function e(a,b,c){c=a<<0|b<<1|c<<2;var d=x[c];void 0===d&&(d=new Gb({morphTargets:a,skinning:b}),x[c]=d);return d}function f(b,c,f,g,h,l){var m=b.geometry,p=d,k=b.customDepthMaterial; +!0===f.isPointLight&&(p=e,k=b.customDistanceMaterial);void 0===k?(k=!1,!0===c.morphTargets&&(!0===m.isBufferGeometry?k=m.morphAttributes&&m.morphAttributes.position&&0\nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = sqrt( squared_mean - mean * mean );\n gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"}), +n=v.clone();n.defines.HORIZONAL_PASS=1;var w=new B;w.setAttribute("position",new M(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));var F=new S(w,v),T=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=1;this.render=function(d,e,f){if(!1!==T.enabled&&(!1!==T.autoUpdate||!1!==T.needsUpdate)&&0!==d.length){var p=a.getRenderTarget(),t=a.getActiveCubeFace(),x=a.getActiveMipmapLevel(),q=a.state;q.setBlending(0);q.buffers.color.setClear(1,1,1,1);q.buffers.depth.setTest(!0);q.setScissorTest(!1); +for(var r=0,w=d.length;rc||l.y>c)console.warn("THREE.WebGLShadowMap:",C,"has shadow exceeding max texture size, reducing"),l.x>c&&(m.x=Math.floor(c/u.x),l.x=m.x*u.x,y.mapSize.x=m.x),l.y>c&&(m.y=Math.floor(c/u.y),l.y=m.y*u.y,y.mapSize.y=m.y);null!==y.map||y.isPointLightShadow||3!==this.type||(u={minFilter:1006,magFilter:1006, +format:1023},y.map=new Ha(l.x,l.y,u),y.map.texture.name=C.name+".shadowMap",y.mapPass=new Ha(l.x,l.y,u),y.camera.updateProjectionMatrix());null===y.map&&(u={minFilter:1003,magFilter:1003,format:1023},y.map=new Ha(l.x,l.y,u),y.map.texture.name=C.name+".shadowMap",y.camera.updateProjectionMatrix());a.setRenderTarget(y.map);a.clear();u=y.getViewportCount();for(var V=0;Vd||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?L.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),void 0=== +G&&(G=h(b,e)),c=c?h(b,e):G,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return L.isPowerOfTwo(a.width)&&L.isPowerOfTwo(a.height)}function k(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function p(b,c,e,f){a.generateMipmap(b); +d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function x(c,d,e){if(!1===Ca)return d;if(null!==c){if(void 0!==a[c])return a[c];console.warn("THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format '"+c+"'")}c=d;6403===d&&(5126===e&&(c=33326),5131===e&&(c=33325),5121===e&&(c=33321));6407===d&&(5126===e&&(c=34837),5131===e&&(c=34843),5121===e&&(c=32849));6408===d&&(5126===e&&(c=34836),5131===e&&(c=34842),5121===e&&(c=32856));33325===c||33326===c||34842===c||34836===c?b.get("EXT_color_buffer_float"): +(34843===c||34837===c)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");return c}function r(a){return 1003===a||1004===a||1005===a?9728:9729}function q(b){b=b.target;b.removeEventListener("dispose",q);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&B.delete(b);g.memory.textures--}function v(b){b=b.target;b.removeEventListener("dispose",v);var c=d.get(b),e=d.get(b.texture); +if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLCubeRenderTarget)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--}function n(a,b){var e=d.get(a);if(a.isVideoTexture){var f=g.render.frame; +B.get(a)!==f&&(B.set(a,f),a.update())}if(0q;q++)t[q]=h||e?e?b.image[q].image:b.image[q]:l(b.image[q],!1,!0,H);var r=t[0],v=m(r)||Ca,n=f.convert(b.format),C=f.convert(b.type),w=x(b.internalFormat,n,C);u(34067,b,v);if(h){for(q=0;6>q;q++){var aa=t[q].mipmaps;for(h=0;hq;q++)if(e)for(c.texImage2D(34069+q,0,w,t[q].width,t[q].height,0,n,C,t[q].data),h=0;h=D&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+D);M+=1;return a};this.resetTextureUnits=function(){M=0};this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0t;t++)e.__webglFramebuffer[t]=a.createFramebuffer();else if(e.__webglFramebuffer=a.createFramebuffer(),t)if(Ca){e.__webglMultisampledFramebuffer=a.createFramebuffer(); +e.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,e.__webglColorRenderbuffer);t=f.convert(b.texture.format);var r=f.convert(b.texture.type);t=x(b.texture.internalFormat,t,r);r=ia(b);a.renderbufferStorageMultisample(36161,r,t,b.width,b.height);a.bindFramebuffer(36160,e.__webglMultisampledFramebuffer);a.framebufferRenderbuffer(36160,36064,36161,e.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);b.depthBuffer&&(e.__webglDepthRenderbuffer=a.createRenderbuffer(),A(e.__webglDepthRenderbuffer, +b,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.");if(l){c.bindTexture(34067,h.__webglTexture);u(34067,b.texture,q);for(t=0;6>t;t++)y(e.__webglFramebuffer[t],b,36064,34069+t);k(b.texture,q)&&p(34067,b.texture,b.width,b.height);c.bindTexture(34067,null)}else c.bindTexture(3553,h.__webglTexture),u(3553,b.texture,q),y(e.__webglFramebuffer,b,36064,3553),k(b.texture,q)&&p(3553,b.texture,b.width,b.height),c.bindTexture(3553, +null);if(b.depthBuffer){e=d.get(b);h=!0===b.isWebGLCubeRenderTarget;if(b.depthTexture){if(h)throw Error("target.depthTexture not supported in Cube render targets");if(b&&b.isWebGLCubeRenderTarget)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160,e.__webglFramebuffer);if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width=== +b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0);n(b.depthTexture,0);e=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,e,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,e,0);else throw Error("Unknown depthTexture format");}else if(h)for(e.__webglDepthbuffer=[],h=0;6>h;h++)a.bindFramebuffer(36160,e.__webglFramebuffer[h]), +e.__webglDepthbuffer[h]=a.createRenderbuffer(),A(e.__webglDepthbuffer[h],b);else a.bindFramebuffer(36160,e.__webglFramebuffer),e.__webglDepthbuffer=a.createRenderbuffer(),A(e.__webglDepthbuffer,b);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture,e=m(a)||Ca;if(k(b,e)){e=a.isWebGLCubeRenderTarget?34067:3553;var f=d.get(b).__webglTexture;c.bindTexture(e,f);p(e,b,a.width,a.height);c.bindTexture(e,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(Ca){var c= +d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer);c=b.width;var e=b.height,f=16384;b.depthBuffer&&(f|=256);b.stencilBuffer&&(f|=1024);a.blitFramebuffer(0,0,c,e,0,0,c,e,f,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===P&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."), +P=!0),a=a.texture);n(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLCubeRenderTarget&&(!1===O&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."),O=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?w(a,b):F(a,b)}}function Zh(a,b,c){var d=c.isWebGL2;return{convert:function(a){if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010=== +a)return 5120;if(1011===a)return 5122;if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(d)return 5131;var c=b.get("OES_texture_half_float");return null!==c?c.HALF_FLOAT_OES:null}if(1021===a)return 6406;if(1022===a)return 6407;if(1023===a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027===a)return 34041;if(1028===a)return 6403;if(1029===a)return 36244;if(1030===a)return 33319;if(1031===a)return 33320; +if(1032===a)return 36248;if(1033===a)return 36249;if(33776===a||33777===a||33778===a||33779===a)if(c=b.get("WEBGL_compressed_texture_s3tc"),null!==c){if(33776===a)return c.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===a)return c.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return c.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return c.COMPRESSED_RGBA_S3TC_DXT5_EXT}else return null;if(35840===a||35841===a||35842===a||35843===a)if(c=b.get("WEBGL_compressed_texture_pvrtc"),null!==c){if(35840===a)return c.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; +if(35841===a)return c.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return c.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return c.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}else return null;if(36196===a)return c=b.get("WEBGL_compressed_texture_etc1"),null!==c?c.COMPRESSED_RGB_ETC1_WEBGL:null;if(37492===a||37496===a)if(c=b.get("WEBGL_compressed_texture_etc"),null!==c){if(37492===a)return c.COMPRESSED_RGB8_ETC2;if(37496===a)return c.COMPRESSED_RGBA8_ETC2_EAC}if(37808===a||37809===a||37810===a||37811===a||37812=== +a||37813===a||37814===a||37815===a||37816===a||37817===a||37818===a||37819===a||37820===a||37821===a||37840===a||37841===a||37842===a||37843===a||37844===a||37845===a||37846===a||37847===a||37848===a||37849===a||37850===a||37851===a||37852===a||37853===a)return c=b.get("WEBGL_compressed_texture_astc"),null!==c?a:null;if(1020===a){if(d)return 34042;c=b.get("WEBGL_depth_texture");return null!==c?c.UNSIGNED_INT_24_8_WEBGL:null}}}}function Qe(a){ba.call(this);this.cameras=a||[]}function Mc(){E.call(this); +this.type="Group"}function $h(a,b){function c(a){var b=q.get(a.inputSource);b&&(b.targetRay&&b.targetRay.dispatchEvent({type:a.type}),b.grip&&b.grip.dispatchEvent({type:a.type}))}function d(){q.forEach(function(a,b){a.targetRay&&(a.targetRay.dispatchEvent({type:"disconnected",data:b}),a.targetRay.visible=!1);a.grip&&(a.grip.dispatchEvent({type:"disconnected",data:b}),a.grip.visible=!1)});q.clear();a.setFramebuffer(null);a.setRenderTarget(a.getRenderTarget());A.stop();h.isPresenting=!1;h.dispatchEvent({type:"sessionend"})} +function e(a){k=a;A.setContext(l);A.start();h.isPresenting=!0;h.dispatchEvent({type:"sessionstart"})}function f(a){for(var b=l.inputSources,c=0;cf.matrixWorld.determinant(),l=x(a,c,e,f); +Z.setMaterial(e,h);var m=!1;if(b!==d.id||ha!==l.id||Pe!==(!0===e.wireframe))b=d.id,ha=l.id,Pe=!0===e.wireframe,m=!0;if(e.morphTargets||e.morphNormals)ya.update(f,d,e,l),m=!0;a=d.index;c=d.attributes.position;if(null===a){if(void 0===c||0===c.count)return}else if(0===a.count)return;var t=1;!0===e.wireframe&&(a=xa.getWireframeAttribute(d),t=2);h=Aa;if(null!==a){var p=oa.get(a);h=Ba;h.setIndex(p)}if(m){if(!1!==Fa.isWebGL2||!f.isInstancedMesh&&!d.isInstancedBufferGeometry||null!==ra.get("ANGLE_instanced_arrays")){Z.initAttributes(); +m=d.attributes;l=l.getAttributes();var k=e.defaultAttributeValues;for(T in l){var q=l[T];if(0<=q){var r=m[T];if(void 0!==r){var n=r.normalized,v=r.itemSize,w=oa.get(r);if(void 0!==w){var C=w.buffer,y=w.type;w=w.bytesPerElement;if(r.isInterleavedBufferAttribute){var F=r.data,u=F.stride;r=r.offset;F&&F.isInstancedInterleavedBuffer?(Z.enableAttributeAndDivisor(q,F.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=F.meshPerAttribute*F.count)):Z.enableAttribute(q);I.bindBuffer(34962, +C);I.vertexAttribPointer(q,v,y,n,u*w,r*w)}else r.isInstancedBufferAttribute?(Z.enableAttributeAndDivisor(q,r.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=r.meshPerAttribute*r.count)):Z.enableAttribute(q),I.bindBuffer(34962,C),I.vertexAttribPointer(q,v,y,n,0,0)}}else if("instanceMatrix"===T)w=oa.get(f.instanceMatrix),void 0!==w&&(C=w.buffer,y=w.type,Z.enableAttributeAndDivisor(q+0,1),Z.enableAttributeAndDivisor(q+1,1),Z.enableAttributeAndDivisor(q+2,1),Z.enableAttributeAndDivisor(q+ +3,1),I.bindBuffer(34962,C),I.vertexAttribPointer(q+0,4,y,!1,64,0),I.vertexAttribPointer(q+1,4,y,!1,64,16),I.vertexAttribPointer(q+2,4,y,!1,64,32),I.vertexAttribPointer(q+3,4,y,!1,64,48));else if(void 0!==k&&(n=k[T],void 0!==n))switch(n.length){case 2:I.vertexAttrib2fv(q,n);break;case 3:I.vertexAttrib3fv(q,n);break;case 4:I.vertexAttrib4fv(q,n);break;default:I.vertexAttrib1fv(q,n)}}}Z.disableUnusedAttributes()}null!==a&&I.bindBuffer(34963,p.buffer)}var T=d.drawRange.start*t;m=null!==g?g.start*t:0; +p=Math.max(T,m);g=Math.max(0,Math.min(null!==a?a.count:c.count,T+d.drawRange.count*t,m+(null!==g?g.count*t:Infinity))-1-p+1);0!==g&&(f.isMesh?!0===e.wireframe?(Z.setLineWidth(e.wireframeLinewidth*(null===O?Q:1)),h.setMode(1)):h.setMode(4):f.isLine?(e=e.linewidth,void 0===e&&(e=1),Z.setLineWidth(e*(null===O?Q:1)),f.isLineSegments?h.setMode(1):f.isLineLoop?h.setMode(2):h.setMode(3)):f.isPoints?h.setMode(0):f.isSprite&&h.setMode(4),f.isInstancedMesh?h.renderInstances(d,p,g,f.count):d.isInstancedBufferGeometry? +h.renderInstances(d,p,g,d.maxInstancedCount):h.render(p,g))};this.compile=function(a,b){z=va.get(a,b);z.init();a.traverse(function(a){a.isLight&&(z.pushLight(a),a.castShadow&&z.pushShadow(a))});z.setupLights(b);var c={};a.traverse(function(b){if(b.material)if(Array.isArray(b.material))for(var d=0;de.far||f.push({distance:a,distanceToRay:Math.sqrt(h),point:c,index:b,face:null,object:g}))}function sg(a,b,c,d,e,f,g,h,l){W.call(this,a,b,c,d,e,f,g,h,l);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Qc(a,b,c,d,e,f,g,h,l,m,t,p){W.call(this,null,f,g,h,l,m,d,e,t,p);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps= +this.flipY=!1}function Td(a,b,c,d,e,f,g,h,l){W.call(this,a,b,c,d,e,f,g,h,l);this.needsUpdate=!0}function Ud(a,b,c,d,e,f,g,h,l,m){m=void 0!==m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);W.call(this,null,d,e,f,g,h,m,c,l);this.image={width:a,height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!==h?h:1003;this.generateMipmaps=this.flipY=!1}function Rc(a){B.call(this); +this.type="WireframeGeometry";var b=[],c,d,e,f=[0,0],g={},h=["a","b","c"];if(a&&a.isGeometry){var l=a.faces;var m=0;for(d=l.length;mc;c++){var p=t[h[c]];var k=t[h[(c+1)%3]];f[0]=Math.min(p,k);f[1]=Math.max(p,k);p=f[0]+","+f[1];void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]})}}for(p in g)m=g[p],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){l=a.attributes.position;t=a.index;var r= +a.groups;0===r.length&&(r=[{start:0,count:t.count,materialIndex:0}]);a=0;for(e=r.length;ac;c++)p=t.getX(m+c),k=t.getX(m+(c+1)%3),f[0]=Math.min(p,k),f[1]=Math.max(p,k),p=f[0]+","+f[1],void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]});for(p in g)m=g[p],h.fromBufferAttribute(l,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(l,m.index2),b.push(h.x,h.y,h.z)}else for(l=a.attributes.position,m=0,d=l.count/3;mc;c++)g=3* +m+c,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(l,g),b.push(h.x,h.y,h.z);this.setAttribute("position",new A(b,3))}function Vd(a,b,c){N.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Sc(a,b,c));this.mergeVertices()}function Sc(a,b,c){B.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,l=new n,m=new n,t=new n,p=new n,k,r;3> +a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.");var q=b+1;for(k=0;k<=c;k++){var v=k/c;for(r=0;r<=b;r++){var C=r/b;a(C,v,l);e.push(l.x,l.y,l.z);0<=C-1E-5?(a(C-1E-5,v,m),t.subVectors(l,m)):(a(C+1E-5,v,m),t.subVectors(m,l));0<=v-1E-5?(a(C,v-1E-5,m),p.subVectors(l,m)):(a(C,v+1E-5,m),p.subVectors(m,l));h.crossVectors(t,p).normalize();f.push(h.x,h.y,h.z);g.push(C,v)}}for(k=0;kd&&1===a.x&&(l[b]=a.x-1);0===c.x&& +0===c.z&&(l[b]=d/2/Math.PI+.5)}B.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],l=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(l[a+0]+=1),.2>c&&(l[a+2]+=1),.2>d&&(l[a+4]+=1))})();this.setAttribute("position",new A(h,3));this.setAttribute("normal", +new A(h.slice(),3));this.setAttribute("uv",new A(l,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Xd(a,b){N.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Tc(a,b));this.mergeVertices()}function Tc(a,b){Ga.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Yd(a,b){N.call(this);this.type="OctahedronGeometry";this.parameters= +{radius:a,detail:b};this.fromBufferGeometry(new cc(a,b));this.mergeVertices()}function cc(a,b){Ga.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Zd(a,b){N.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Uc(a,b));this.mergeVertices()}function Uc(a,b){var c=(1+Math.sqrt(5))/2;Ga.call(this,[-1,c,0,1,c,0, +-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function $d(a,b){N.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Vc(a,b));this.mergeVertices()}function Vc(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;Ga.call(this, +[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function ae(a, +b,c,d,e,f){N.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new dc(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function dc(a,b,c,d,e){function f(e){t=a.getPointAt(e/b,t);var f=g.normals[e];e=g.binormals[e];for(x=0;x<=d;x++){var m=x/d*Math.PI*2,k=Math.sin(m);m=-Math.cos(m); +l.x=m*f.x+k*e.x;l.y=m*f.y+k*e.y;l.z=m*f.z+k*e.z;l.normalize();q.push(l.x,l.y,l.z);h.x=t.x+c*l.x;h.y=t.y+c*l.y;h.z=t.z+c*l.z;r.push(h.x,h.y,h.z)}}B.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,l=new n,m=new u,t=new n,k,x,r=[],q=[],v=[],C=[];for(k=0;k=b;e-=d)f=di(e,a[e],a[e+1],f);f&&ec(f,f.next)&&(de(f),f=f.next);return f}function ee(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!ec(a,a.next)&&0!==xa(a.prev,a,a.next))a=a.next;else{de(a);a=b=a.prev; +if(a===a.next)break;c=!0}}while(c||a!==b);return b}function fe(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,l=h;do null===l.z&&(l.z=tg(l.x,l.y,d,e,f)),l.prevZ=l.prev,l=l.nextZ=l.next;while(l!==h);l.prevZ.nextZ=null;l.prevZ=null;h=l;var m,k,p,x,r=1;do{l=h;var q=h=null;for(k=0;l;){k++;var n=l;for(m=p=0;mn!==q.next.y>n&&q.next.y!==q.y&&p<(q.next.x-q.x)*(n-q.y)/(q.next.y-q.y)+q.x&&(k=!k),q=q.next;while(q!==l);q=k}l=q}if(l){a=fi(g,h);g=ee(g,g.next);a=ee(a, +a.next);fe(g,b,c,d,e,f);fe(a,b,c,d,e,f);break a}h=h.next}g=g.next}while(g!==a)}break}}}}function Kk(a,b,c,d){var e=a.prev,f=a.next;if(0<=xa(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,l=tg(e.x=l&&d&&d.z<=b;){if(c!==a.prev&&c!==a.next&&Yc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=xa(c.prev,c,c.next))return!1;c=c.prevZ; +if(d!==a.prev&&d!==a.next&&Yc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=xa(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=l;){if(c!==a.prev&&c!==a.next&&Yc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=xa(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&Yc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=xa(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function Lk(a,b){return a.x-b.x}function Mk(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)* +(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f=g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&Yc(eh.x)&&ge(c,a)&&(h=c,m=k)}c=c.next}return h}function tg(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135; +a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b|b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function Nk(a){var b=a,c=a;do{if(b.xxa(a.prev,a,a.next)?0<=xa(a,b,a.next)&&0<=xa(a,a.prev,b):0>xa(a,b,a.prev)||0>xa(a,a.next,b)}function fi(a,b){var c=new ug(a.i,a.x,a.y),d=new ug(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function di(a,b,c,d){a=new ug(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function de(a){a.next.prev= +a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ=a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function ug(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function gi(a){var b=a.length;2Number.EPSILON){var l=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/l;b=b.y+d/l;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new u(f,d);e=Math.sqrt(e/2)}else a=!1,d>Number.EPSILON?f>Number.EPSILON&&(a=!0):d<-Number.EPSILON? +f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new u(f/e,d/e)}function h(a,b){for(J=a.length;0<=--J;){var c=J;var f=J-1;0>f&&(f=a.length-1);var g,h=F+2*A;for(g=0;gk;k++){var p=m[f[k]];var n=m[f[(k+1)%3]];d[0]=Math.min(p,n);d[1]=Math.max(p,n);p=d[0]+","+d[1];void 0===e[p]?e[p]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[p].face2=h}for(p in e)if(d=e[p],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.setAttribute("position",new A(c,3))}function jc(a,b,c,d, +e,f,g,h){N.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new tb(a,b,c,d,e,f,g,h));this.mergeVertices()}function tb(a,b,c,d,e,f,g,h){function l(c){var e,f=new u,l=new n,t=0,v=!0===c?a:b,F=!0===c?1:-1;var z=q;for(e=1;e<=d;e++)p.push(0,C*F,0),x.push(0,F,0),r.push(.5,.5),q++;var A=q;for(e=0;e<=d;e++){var B=e/d*h+g,D=Math.cos(B);B=Math.sin(B);l.x=v*B;l.y=C*F; +l.z=v*D;p.push(l.x,l.y,l.z);x.push(0,F,0);f.x=.5*D+.5;f.y=.5*B*F+.5;r.push(f.x,f.y);q++}for(e=0;ethis.duration&&this.resetDuration()}function Pk(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return dd;case "vector":case "vector2":case "vector3":case "vector4":return ed;case "color":return $e;case "quaternion":return pe;case "bool":case "boolean":return Ze;case "string":return bf}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function Qk(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse"); +var b=Pk(a.type);if(void 0===a.times){var c=[],d=[];R.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)}function vg(a,b,c){var d=this,e=!1,f=0,g=0,h=void 0,l=[];this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()}; +this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this};this.addHandler=function(a,b){l.push(a,b);return this};this.removeHandler=function(a){a=l.indexOf(a);-1!==a&&l.splice(a,2);return this};this.getHandler=function(a){for(var b=0,c=l.length;ba;a++)this.coefficients.push(new n)}function ab(a,b){ea.call(this,void 0,b);this.sh=void 0!==a?a:new uf}function Eg(a,b,c){ab.call(this,void 0,c);a=(new z).set(a);c=(new z).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)}function Fg(a,b){ab.call(this,void 0,b);a=(new z).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))} +function mi(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new ba;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new ba;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1;this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}function Gg(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function Hg(){E.call(this);this.type="AudioListener";this.context=Ig.getContext(); +this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0;this._clock=new Gg}function id(a){E.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.loopEnd=this.loopStart=0;this.duration=void 0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this._pausedAt= +this._startedAt=0;this.filters=[]}function Jg(a){id.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function Kg(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function Lg(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a= +Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function ni(a,b,c){c=c||ya.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function ya(a,b,c){this.path=b;this.parsedPath=c||ya.parseTrackName(b);this.node=ya.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function oi(){this.uuid=L.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_= +0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function pi(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400}, +e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart= +!0}function Mg(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function vf(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Ng(a,b,c){rb.call(this,a,b);this.meshPerAttribute=c||1}function Og(a,b,c,d){this.ray=new Vb(a,b);this.near=c||0;this.far=d||Infinity;this.camera=null;this.layers=new Ie;this.params={Mesh:{},Line:{threshold:1},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params, +{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})}function qi(a,b){return a.distance-b.distance}function Pg(a,b,c,d){a.layers.test(b.layers)&&a.raycast(b,c);if(!0===d){a=a.children;d=0;for(var e=a.length;dc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.setAttribute("position",new A(b,3));b=new la({fog:!1});this.cone=new ma(a,b);this.add(this.cone);this.update()}function ti(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;cr;++r){var q=r/k;q=Math.exp(-q*q/2);e.push(q);0==r?n+=q:r\n\nvec4 inputTexelToLinear(vec4 value){\n\tif(inputEncoding == 0){\n\t\treturn value;\n\t}else if(inputEncoding == 1){\n\t\treturn sRGBToLinear(value);\n\t}else if(inputEncoding == 2){\n\t\treturn RGBEToLinear(value);\n\t}else if(inputEncoding == 3){\n\t\treturn RGBMToLinear(value, 7.0);\n\t}else if(inputEncoding == 4){\n\t\treturn RGBMToLinear(value, 16.0);\n\t}else if(inputEncoding == 5){\n\t\treturn RGBDToLinear(value, 256.0);\n\t}else{\n\t\treturn GammaToLinear(value, 2.2);\n\t}\n}\n\nvec4 linearToOutputTexel(vec4 value){\n\tif(outputEncoding == 0){\n\t\treturn value;\n\t}else if(outputEncoding == 1){\n\t\treturn LinearTosRGB(value);\n\t}else if(outputEncoding == 2){\n\t\treturn LinearToRGBE(value);\n\t}else if(outputEncoding == 3){\n\t\treturn LinearToRGBM(value, 7.0);\n\t}else if(outputEncoding == 4){\n\t\treturn LinearToRGBM(value, 16.0);\n\t}else if(outputEncoding == 5){\n\t\treturn LinearToRGBD(value, 256.0);\n\t}else{\n\t\treturn LinearToGamma(value, 2.2);\n\t}\n}\n\nvec4 envMapTexelToLinear(vec4 color) {\n\treturn inputTexelToLinear(color);\n}\n\t"} +function Fi(a){console.warn("THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.");pa.call(this,a);this.type="catmullrom";this.closed=!0}function Gi(a){console.warn("THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.");pa.call(this,a);this.type="catmullrom"}function $g(a){console.warn("THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.");pa.call(this,a);this.type="catmullrom"}void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2, +-52));void 0===Number.isInteger&&(Number.isInteger=function(a){return"number"===typeof a&&isFinite(a)&&Math.floor(a)===a});void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0ye;ye++)ta[ye]=(16>ye?"0":"")+ye.toString(16);var L={DEG2RAD:Math.PI/180,RAD2DEG:180/Math.PI,generateUUID:function(){var a=4294967295*Math.random()|0,b=4294967295*Math.random()|0,c=4294967295*Math.random()| +0,d=4294967295*Math.random()|0;return(ta[a&255]+ta[a>>8&255]+ta[a>>16&255]+ta[a>>24&255]+"-"+ta[b&255]+ta[b>>8&255]+"-"+ta[b>>16&15|64]+ta[b>>24&255]+"-"+ta[c&63|128]+ta[c>>8&255]+"-"+ta[c>>16&255]+ta[c>>24&255]+ta[d&255]+ta[d>>8&255]+ta[d>>16&255]+ta[d>>24&255]).toUpperCase()},clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,b,c){return(1-c)*a+c*b},smoothstep:function(a, +b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(a){return a*L.DEG2RAD},radToDeg:function(a){return a*L.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2, +Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))},setQuaternionFromProperEuler:function(a,b,c,d,e){var f=Math.cos,g=Math.sin,h=f(c/2);c=g(c/2);var l=f((b+d)/2),m=g((b+d)/2),k=f((b-d)/2),p=g((b-d)/2);f=f((d-b)/2);b=g((d-b)/2);"XYX"===e?a.set(h*m,c*k,c*p,h*l):"YZY"===e?a.set(c*p,h*m,c*k,h*l):"ZXZ"===e?a.set(c*k,c*p,h*m,h*l):"XZX"===e?a.set(h*m,c*b,c*f,h*l):"YXY"===e?a.set(c*f,h*m,c*b,h*l):"ZYZ"===e?a.set(c*b,c*f,h*m,h*l):console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order.")}}; +Object.defineProperties(u.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(u.prototype,{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+ +a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this}, +addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*= +a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y=a[1]*b+a[4]*c+a[7];return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a, +b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x= +Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+ +Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},angle:function(){return Math.atan2(-this.y,-this.x)+Math.PI},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this}, +lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a, +b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(wa.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,l){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=l;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]= +a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},extractBasis:function(a,b,c){a.setFromMatrix3Column(this,0);b.setFromMatrix3Column(this,1);c.setFromMatrix3Column(this,2);return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},multiply:function(a){return this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements; +a=c[0];var e=c[3],f=c[6],g=c[1],h=c[4],l=c[7],m=c[2],k=c[5];c=c[8];var p=d[0],n=d[3],r=d[6],q=d[1],v=d[4],C=d[7],w=d[2],u=d[5];d=d[8];b[0]=a*p+e*q+f*w;b[3]=a*n+e*v+f*u;b[6]=a*r+e*C+f*d;b[1]=g*p+h*q+l*w;b[4]=g*n+h*v+l*u;b[7]=g*r+h*C+l*d;b[2]=m*p+k*q+c*w;b[5]=m*n+k*v+c*u;b[8]=m*r+k*C+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[3]*=a;b[6]*=a;b[1]*=a;b[4]*=a;b[7]*=a;b[2]*=a;b[5]*=a;b[8]*=a;return this},determinant:function(){var a=this.elements,b=a[0],c=a[1],d=a[2],e=a[3], +f=a[4],g=a[5],h=a[6],l=a[7];a=a[8];return b*f*a-b*g*l-c*e*a+c*g*h+d*e*l-d*f*h},getInverse:function(a,b){a&&a.isMatrix4&&console.error("THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument.");var c=a.elements;a=this.elements;var d=c[0],e=c[1],f=c[2],g=c[3],h=c[4],l=c[5],m=c[6],k=c[7];c=c[8];var p=c*h-l*k,n=l*m-c*g,r=k*g-h*m,q=d*p+e*n+f*r;if(0===q){if(!0===b)throw Error("THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0");console.warn("THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"); +return this.identity()}b=1/q;a[0]=p*b;a[1]=(f*k-c*e)*b;a[2]=(l*e-f*h)*b;a[3]=n*b;a[4]=(c*d-f*m)*b;a[5]=(f*g-l*d)*b;a[6]=r*b;a[7]=(e*m-k*d)*b;a[8]=(h*d-e*g)*b;return this},transpose:function(){var a=this.elements;var b=a[1];a[1]=a[3];a[3]=b;b=a[2];a[2]=a[6];a[6]=b;b=a[5];a[5]=a[7];a[7]=b;return this},getNormalMatrix:function(a){return this.setFromMatrix4(a).getInverse(this).transpose()},transposeIntoArray:function(a){var b=this.elements;a[0]=b[0];a[1]=b[3];a[2]=b[6];a[3]=b[1];a[4]=b[4];a[5]=b[7];a[6]= +b[2];a[7]=b[5];a[8]=b[8];return this},setUvTransform:function(a,b,c,d,e,f,g){var h=Math.cos(e);e=Math.sin(e);this.set(c*h,c*e,-c*(h*f+e*g)+f+a,-d*e,d*h,-d*(-e*f+h*g)+g+b,0,0,1)},scale:function(a,b){var c=this.elements;c[0]*=a;c[3]*=a;c[6]*=a;c[1]*=b;c[4]*=b;c[7]*=b;return this},rotate:function(a){var b=Math.cos(a);a=Math.sin(a);var c=this.elements,d=c[0],e=c[3],f=c[6],g=c[1],h=c[4],l=c[7];c[0]=b*d+a*g;c[3]=b*e+a*h;c[6]=b*f+a*l;c[1]=-a*d+b*g;c[4]=-a*e+b*h;c[7]=-a*f+b*l;return this},translate:function(a, +b){var c=this.elements;c[0]+=a*c[2];c[3]+=a*c[5];c[6]+=a*c[8];c[1]+=b*c[2];c[4]+=b*c[5];c[7]+=b*c[8];return this},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;9>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8]; +return a}});var nd,Lb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===nd&&(nd=document.createElementNS("http://www.w3.org/1999/xhtml","canvas"));nd.width=a.width;nd.height=a.height;var b=nd.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=nd}return 2048 +a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(W.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(ka.prototype, +{width:{get:function(){return this.z},set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(ka.prototype,{isVector4:!0,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x= +b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!== +b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."), +this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]* +c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){a=a.elements;var b=a[0];var c=a[4];var d=a[8],e=a[1],f=a[5],g=a[9];var h=a[2];var l=a[6];var m=a[10];if(.01>Math.abs(c-e)&&.01>Math.abs(d-h)&&.01>Math.abs(g- +l)){if(.1>Math.abs(c+e)&&.1>Math.abs(d+h)&&.1>Math.abs(g+l)&&.1>Math.abs(b+f+m-3))return this.set(1,0,0,0),this;a=Math.PI;b=(b+1)/2;f=(f+1)/2;m=(m+1)/2;c=(c+e)/4;d=(d+h)/4;g=(g+l)/4;b>f&&b>m?.01>b?(l=0,c=h=.707106781):(l=Math.sqrt(b),h=c/l,c=d/l):f>m?.01>f?(l=.707106781,h=0,c=.707106781):(h=Math.sqrt(f),l=c/h,c=g/h):.01>m?(h=l=.707106781,c=0):(c=Math.sqrt(m),l=d/c,h=g/c);this.set(l,h,c,a);return this}a=Math.sqrt((l-g)*(l-g)+(d-h)*(d-h)+(e-c)*(e-c));.001>Math.abs(a)&&(a=1);this.x=(l-g)/a;this.y=(d- +h)/a;this.z=(e-c)/a;this.w=Math.acos((b+f+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w, +Math.min(b.w,this.w));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a,Math.min(b,this.z));this.w=Math.max(a,Math.min(b,this.w));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x= +Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x= +-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)}, +lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]= +this.w;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});Ha.prototype=Object.assign(Object.create(Ea.prototype),{constructor:Ha,isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.texture.image.width=a,this.texture.image.height=b,this.dispose();this.viewport.set(0,0, +a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Zf.prototype=Object.assign(Object.create(Ha.prototype),{constructor:Zf,isWebGLMultisampleRenderTarget:!0,copy:function(a){Ha.prototype.copy.call(this, +a);this.samples=a.samples;return this}});Object.assign(Aa,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h=c[d+0],l=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var k=e[f+1],p=e[f+2];e=e[f+3];if(c!==e||h!==d||l!==k||m!==p){f=1-g;var n=h*d+l*k+m*p+c*e,r=0<=n?1:-1,q=1-n*n;q>Number.EPSILON&&(q=Math.sqrt(q),n=Math.atan2(q,n*r),f=Math.sin(f*n)/q,g=Math.sin(g*n)/q);r*=g;h=h*f+d*r;l=l*f+k*r;m=m*f+p*r;c=c*f+e*r;f===1-g&&(g=1/Math.sqrt(h*h+l*l+m*m+c*c),h*=g,l*=g,m*=g,c*=g)}a[b]= +h;a[b+1]=l;a[b+2]=m;a[b+3]=c}});Object.defineProperties(Aa.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(Aa.prototype,{isQuaternion:!0,set:function(a,b,c,d){this._x=a;this._y= +b;this._z=c;this._w=d;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z;this._w=a.w;this._onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),l=f(d/2);f=f(e/2);c=g(c/2);d=g(d/ +2);e=g(e/2);"XYZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"YXZ"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f-c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f+c*d*e):"ZXY"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f-c*d*e):"ZYX"===a?(this._x=c*l*f-h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f+c*d*e):"YZX"===a?(this._x=c*l*f+h*d*e,this._y=h*d*f+c*l*e,this._z=h*l*e-c*d*f,this._w=h*l*f-c*d*e):"XZY"===a&&(this._x=c*l*f-h*d* +e,this._y=h*d*f-c*l*e,this._z=h*l*e+c*d*f,this._w=h*l*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b);this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);this._onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],l=b[6];b=b[10];var m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+ +c-f-b),this._w=(l-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+l)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+l)/c,this._z=.25*c);this._onChangeCallback();return this},setFromUnitVectors:function(a,b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z= +a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(L.clamp(this.dot(a),-1,1)))},rotateTowards:function(a,b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this._onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+ +this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this._onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a, +b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w;var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;this._onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x= +-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g*f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;this._onChangeCallback();return this},equals:function(a){return a._x=== +this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});var ah=new n,Hi=new Aa;Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x= +a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+ +a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a, +b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."), +this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(a){a&&a.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(Hi.setFromEuler(a))},applyAxisAngle:function(a,b){return this.applyQuaternion(Hi.setFromAxisAngle(a, +b))},applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyNormalMatrix:function(a){return this.applyMatrix3(a).normalize()},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b= +this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,l=a*c+g*b-e*d,m=a*d+e*c-f*b;b=-e*b-f*c-g*d;this.x=h*a+b*-e+l*-g-m*-f;this.y=l*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-l*-e;return this},project:function(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+ +a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x)); +this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a,Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x= +Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y* +a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a, +b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this,a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.lengthSq();if(0===b)return this.set(0,0,0);b=a.dot(this)/b;return this.copy(a).multiplyScalar(b)}, +projectOnPlane:function(a){ah.copy(this).projectOnVector(a);return this.sub(ah)},reflect:function(a){return this.sub(ah.copy(a).multiplyScalar(2*this.dot(a)))},angleTo:function(a){var b=Math.sqrt(this.lengthSq()*a.lengthSq());if(0===b)return Math.PI/2;a=this.dot(a)/b;return Math.acos(L.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},manhattanDistanceTo:function(a){return Math.abs(this.x- +a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)*a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta,a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a= +a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,4*b)},setFromMatrix3Column:function(a,b){return this.fromArray(a.elements,3*b)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0=== +b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});var od=new n,Y=new P,Rk=new n(0,0,0),Sk=new n(1,1,1),Mb=new n,Df=new n,qa=new n;Object.assign(P.prototype,{isMatrix4:!0,set:function(a, +b,c,d,e,f,g,h,l,m,k,p,n,r,q,v){var t=this.elements;t[0]=a;t[4]=b;t[8]=c;t[12]=d;t[1]=e;t[5]=f;t[9]=g;t[13]=h;t[2]=l;t[6]=m;t[10]=k;t[14]=p;t[3]=n;t[7]=r;t[11]=q;t[15]=v;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new P).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]= +a[13];b[14]=a[14];b[15]=a[15];return this},copyPosition:function(a){var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(a){var b=this.elements,c=a.elements,d=1/od.setFromMatrixColumn(a,0).length(),e=1/od.setFromMatrixColumn(a, +1).length();a=1/od.setFromMatrixColumn(a,2).length();b[0]=c[0]*d;b[1]=c[1]*d;b[2]=c[2]*d;b[3]=0;b[4]=c[4]*e;b[5]=c[5]*e;b[6]=c[6]*e;b[7]=0;b[8]=c[8]*a;b[9]=c[9]*a;b[10]=c[10]*a;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d);d=Math.sin(d);var h= +Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a=f*h;var l=f*e,m=c*h,k=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=l+m*d;b[5]=a-k*d;b[9]=-c*g;b[2]=k-a*d;b[6]=m+l*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a+k*c,b[4]=m*c-l,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=l*c-m,b[6]=k+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,l=g*e,m=d*h,k=d*e,b[0]=a-k*c,b[4]=-f*e,b[8]=m+l*c,b[1]=l+m*c,b[5]=f*h,b[9]=k-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,l=f*e,m=c*h,k=c*e,b[0]=g*h,b[4]=m*d-l,b[8]=a*d+ +k,b[1]=g*e,b[5]=k*d+a,b[9]=l*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=k-a*e,b[8]=m*e+l,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=l*e+m,b[10]=a-k*e):"XZY"===a.order&&(a=f*g,l=f*d,m=c*g,k=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+k,b[5]=f*h,b[9]=l*e-m,b[2]=m*e-l,b[6]=c*h,b[10]=k*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(a){return this.compose(Rk,a,Sk)},lookAt:function(a,b,c){var d=this.elements; +qa.subVectors(a,b);0===qa.lengthSq()&&(qa.z=1);qa.normalize();Mb.crossVectors(c,qa);0===Mb.lengthSq()&&(1===Math.abs(c.z)?qa.x+=1E-4:qa.z+=1E-4,qa.normalize(),Mb.crossVectors(c,qa));Mb.normalize();Df.crossVectors(qa,Mb);d[0]=Mb.x;d[4]=Df.x;d[8]=qa.x;d[1]=Mb.y;d[5]=Df.y;d[9]=qa.y;d[2]=Mb.z;d[6]=Df.z;d[10]=qa.z;return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(a, +b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],l=c[5],m=c[9],k=c[13],p=c[2],n=c[6],r=c[10],q=c[14],v=c[3],C=c[7],w=c[11];c=c[15];var u=d[0],z=d[4],B=d[8],A=d[12],y=d[1],D=d[5],E=d[9],G=d[13],K=d[2],H=d[6],L=d[10],M=d[14],N=d[3],O=d[7],P=d[11];d=d[15];b[0]=a*u+e*y+f*K+g*N;b[4]=a*z+e*D+f*H+g*O;b[8]=a*B+e*E+f*L+g*P;b[12]=a*A+e*G+f*M+g* +d;b[1]=h*u+l*y+m*K+k*N;b[5]=h*z+l*D+m*H+k*O;b[9]=h*B+l*E+m*L+k*P;b[13]=h*A+l*G+m*M+k*d;b[2]=p*u+n*y+r*K+q*N;b[6]=p*z+n*D+r*H+q*O;b[10]=p*B+n*E+r*L+q*P;b[14]=p*A+n*G+r*M+q*d;b[3]=v*u+C*y+w*K+c*N;b[7]=v*z+C*D+w*H+c*O;b[11]=v*B+C*E+w*L+c*P;b[15]=v*A+C*G+w*M+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},determinant:function(){var a=this.elements, +b=a[0],c=a[4],d=a[8],e=a[12],f=a[1],g=a[5],h=a[9],l=a[13],m=a[2],k=a[6],p=a[10],n=a[14];return a[3]*(+e*h*k-d*l*k-e*g*p+c*l*p+d*g*n-c*h*n)+a[7]*(+b*h*n-b*l*p+e*f*p-d*f*n+d*l*m-e*h*m)+a[11]*(+b*l*k-b*g*n-e*f*k+c*f*n+e*g*m-c*l*m)+a[15]*(-d*g*m-b*h*k+b*g*p+d*f*k-c*f*p+c*h*m)},transpose:function(){var a=this.elements;var b=a[1];a[1]=a[4];a[4]=b;b=a[2];a[2]=a[8];a[8]=b;b=a[6];a[6]=a[9];a[9]=b;b=a[3];a[3]=a[12];a[12]=b;b=a[7];a[7]=a[13];a[13]=b;b=a[11];a[11]=a[14];a[14]=b;return this},setPosition:function(a, +b,c){var d=this.elements;a.isVector3?(d[12]=a.x,d[13]=a.y,d[14]=a.z):(d[12]=a,d[13]=b,d[14]=c);return this},getInverse:function(a,b){var c=this.elements,d=a.elements;a=d[0];var e=d[1],f=d[2],g=d[3],h=d[4],l=d[5],m=d[6],k=d[7],p=d[8],n=d[9],r=d[10],q=d[11],v=d[12],u=d[13],w=d[14];d=d[15];var F=n*w*k-u*r*k+u*m*q-l*w*q-n*m*d+l*r*d,z=v*r*k-p*w*k-v*m*q+h*w*q+p*m*d-h*r*d,B=p*u*k-v*n*k+v*l*q-h*u*q-p*l*d+h*n*d,A=v*n*m-p*u*m-v*l*r+h*u*r+p*l*w-h*n*w,y=a*F+e*z+f*B+g*A;if(0===y){if(!0===b)throw Error("THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0"); +console.warn("THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0");return this.identity()}b=1/y;c[0]=F*b;c[1]=(u*r*g-n*w*g-u*f*q+e*w*q+n*f*d-e*r*d)*b;c[2]=(l*w*g-u*m*g+u*f*k-e*w*k-l*f*d+e*m*d)*b;c[3]=(n*m*g-l*r*g-n*f*k+e*r*k+l*f*q-e*m*q)*b;c[4]=z*b;c[5]=(p*w*g-v*r*g+v*f*q-a*w*q-p*f*d+a*r*d)*b;c[6]=(v*m*g-h*w*g-v*f*k+a*w*k+h*f*d-a*m*d)*b;c[7]=(h*r*g-p*m*g+p*f*k-a*r*k-h*f*q+a*m*q)*b;c[8]=B*b;c[9]=(v*n*g-p*u*g-v*e*q+a*u*q+p*e*d-a*n*d)*b;c[10]=(h*u*g-v*l*g+v*e*k-a*u*k-h*e*d+a*l*d)*b;c[11]= +(p*l*g-h*n*g-p*e*k+a*n*k+h*e*q-a*l*q)*b;c[12]=A*b;c[13]=(p*u*f-v*n*f+v*e*r-a*u*r-p*e*w+a*n*w)*b;c[14]=(v*l*f-h*u*f-v*e*m+a*u*m+h*e*w-a*l*w)*b;c[15]=(h*n*f-p*l*f+p*e*m-a*n*m-h*e*r+a*l*r)*b;return this},scale:function(a){var b=this.elements,c=a.x,d=a.y;a=a.z;b[0]*=c;b[4]*=d;b[8]*=a;b[1]*=c;b[5]*=d;b[9]*=a;b[2]*=c;b[6]*=d;b[10]*=a;b[3]*=c;b[7]*=d;b[11]*=a;return this},getMaxScaleOnAxis:function(){var a=this.elements;return Math.sqrt(Math.max(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],a[4]*a[4]+a[5]*a[5]+a[6]*a[6], +a[8]*a[8]+a[9]*a[9]+a[10]*a[10]))},makeTranslation:function(a,b,c){this.set(1,0,0,a,0,1,0,b,0,0,1,c,0,0,0,1);return this},makeRotationX:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(1,0,0,0,0,b,-a,0,0,a,b,0,0,0,0,1);return this},makeRotationY:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,0,a,0,0,1,0,0,-a,0,b,0,0,0,0,1);return this},makeRotationZ:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,-a,0,0,a,b,0,0,0,0,1,0,0,0,0,1);return this},makeRotationAxis:function(a,b){var c= +Math.cos(b);b=Math.sin(b);var d=1-c,e=a.x,f=a.y;a=a.z;var g=d*e,h=d*f;this.set(g*e+c,g*f-b*a,g*a+b*f,0,g*f+b*a,h*f+c,h*a-b*e,0,g*a-b*f,h*a+b*e,d*a*a+c,0,0,0,0,1);return this},makeScale:function(a,b,c){this.set(a,0,0,0,0,b,0,0,0,0,c,0,0,0,0,1);return this},makeShear:function(a,b,c){this.set(1,b,c,0,a,1,c,0,a,b,1,0,0,0,0,1);return this},compose:function(a,b,c){var d=this.elements,e=b._x,f=b._y,g=b._z,h=b._w,l=e+e,m=f+f,k=g+g;b=e*l;var p=e*m;e*=k;var n=f*m;f*=k;g*=k;l*=h;m*=h;h*=k;k=c.x;var r=c.y;c= +c.z;d[0]=(1-(n+g))*k;d[1]=(p+h)*k;d[2]=(e-m)*k;d[3]=0;d[4]=(p-h)*r;d[5]=(1-(b+g))*r;d[6]=(f+l)*r;d[7]=0;d[8]=(e+m)*c;d[9]=(f-l)*c;d[10]=(1-(b+n))*c;d[11]=0;d[12]=a.x;d[13]=a.y;d[14]=a.z;d[15]=1;return this},decompose:function(a,b,c){var d=this.elements,e=od.set(d[0],d[1],d[2]).length(),f=od.set(d[4],d[5],d[6]).length(),g=od.set(d[8],d[9],d[10]).length();0>this.determinant()&&(e=-e);a.x=d[12];a.y=d[13];a.z=d[14];Y.copy(this);a=1/e;d=1/f;var h=1/g;Y.elements[0]*=a;Y.elements[1]*=a;Y.elements[2]*=a; +Y.elements[4]*=d;Y.elements[5]*=d;Y.elements[6]*=d;Y.elements[8]*=h;Y.elements[9]*=h;Y.elements[10]*=h;b.setFromRotationMatrix(Y);c.x=e;c.y=f;c.z=g;return this},makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.");var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0; +g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),l=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*l;g[9]=0;g[13]=-((c+d)*l);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a, +b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}});var Ii=new P,Ji=new Aa;Tb.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");Tb.DefaultOrder="XYZ";Object.defineProperties(Tb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y}, +set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(Tb.prototype,{isEuler:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this._onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(a){this._x= +a._x;this._y=a._y;this._z=a._z;this._order=a._order;this._onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=L.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],l=e[5],m=e[9],k=e[2],p=e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.9999999>Math.abs(g)?(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(p,l),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.9999999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,l)): +(this._y=Math.atan2(-k,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.9999999>Math.abs(p)?(this._y=Math.atan2(-k,e),this._z=Math.atan2(-f,l)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(k,-1,1)),.9999999>Math.abs(k)?(this._x=Math.atan2(p,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,l))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.9999999>Math.abs(h)?(this._x=Math.atan2(-m,l),this._y=Math.atan2(-k,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z= +Math.asin(-d(f,-1,1)),.9999999>Math.abs(f)?(this._x=Math.atan2(p,l),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(a,b,c){Ii.makeRotationFromQuaternion(a);return this.setFromRotationMatrix(Ii,b,c)},setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(a){Ji.setFromEuler(this);return this.setFromQuaternion(Ji, +a)},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this._onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback= +a;return this},_onChangeCallback:function(){}});Object.assign(Ie.prototype,{set:function(a){this.mask=1<e&&(e=m);k>f&&(f=k);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,l=a.count;he&&(e=m);k>f&&(f=k);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x|| +a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(a){this.clampPoint(a.center,Ae);return Ae.distanceToSquared(a.center)<=a.radius*a.radius},intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(a){if(this.isEmpty())return!1;this.getCenter(Be);Ff.subVectors(this.max,Be);qd.subVectors(a.a,Be);rd.subVectors(a.b,Be);sd.subVectors(a.c,Be);Nb.subVectors(rd,qd);Ob.subVectors(sd,rd);sc.subVectors(qd,sd);a=[0,-Nb.z,Nb.y,0,-Ob.z,Ob.y,0,-sc.z,sc.y,Nb.z,0,-Nb.x,Ob.z,0,-Ob.x,sc.z,0,-sc.x,-Nb.y,Nb.x,0,-Ob.y,Ob.x,0,-sc.y,sc.x,0];if(!$f(a,qd,rd,sd,Ff))return!1; +a=[1,0,0,0,1,0,0,0,1];if(!$f(a,qd,rd,sd,Ff))return!1;Gf.crossVectors(Nb,Ob);a=[Gf.x,Gf.y,Gf.z];return $f(a,qd,rd,sd,Ff)},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return Ae.copy(a).clamp(this.min,this.max).sub(a).length()},getBoundingSphere:function(a){void 0===a&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(a.center); +a.radius=.5*this.getSize(Ae).length();return a},intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(a){if(this.isEmpty())return this;zb[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(a);zb[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(a);zb[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(a);zb[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(a); +zb[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(a);zb[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(a);zb[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(a);zb[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(a);this.setFromPoints(zb);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var Xk=new Sa;Object.assign(pb.prototype,{set:function(a,b){this.center.copy(a);this.radius= +b;return this},setFromPoints:function(a,b){var c=this.center;void 0!==b?c.copy(b):Xk.setFromPoints(a).getCenter(c);for(var d=b=0,e=a.length;d=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)- +this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a);void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center)); +return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new Sa);a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}});var Ab=new n,ch=new n,Hf=new n,Pb=new n,dh=new n,If=new n,eh=new n; +Object.assign(Vb.prototype,{set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"),b=new n);return b.copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(a){this.origin.copy(this.at(a, +Ab));return this},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"),b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(a){var b=Ab.subVectors(a,this.origin).dot(this.direction);if(0>b)return this.origin.distanceToSquared(a);Ab.copy(this.direction).multiplyScalar(b).add(this.origin); +return Ab.distanceToSquared(a)},distanceSqToSegment:function(a,b,c,d){ch.copy(a).add(b).multiplyScalar(.5);Hf.copy(b).sub(a).normalize();Pb.copy(this.origin).sub(ch);var e=.5*a.distanceTo(b),f=-this.direction.dot(Hf),g=Pb.dot(this.direction),h=-Pb.dot(Hf),l=Pb.lengthSq(),m=Math.abs(1-f*f);if(0=-k?b<=k?(e=1/m,a*=e,b*=e,f=a*(a+f*b+2*g)+b*(f*a+b+2*h)+l):(b=e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):(b=-e,a=Math.max(0,-(f*b+g)),f=-a*a+b*(b+2*h)+l):b<=-k?(a=Math.max(0, +-(-f*e+g)),b=0a)return null;a=Math.sqrt(a-d);d=c-a;c+=a;return 0>d&&0>c?null:0>d?this.at(c,b):this.at(d,b)},intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){a=this.distanceToPlane(a);return null===a?null:this.at(a,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin); +return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y-f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null; +if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(a){return null!==this.intersectBox(a,Ab)},intersectTriangle:function(a,b,c,d,e){dh.subVectors(b,a);If.subVectors(c,a);eh.crossVectors(dh,If);b=this.direction.dot(eh);if(0b)d=-1,b=-b;else return null;Pb.subVectors(this.origin,a);a=d*this.direction.dot(If.crossVectors(Pb,If));if(0>a)return null;c=d*this.direction.dot(dh.cross(Pb));if(0>c||a+c>b)return null;a=-d*Pb.dot(eh); +return 0>a?null:this.at(a/b,e)},applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});var fh=new n,Yk=new n,Zk=new wa;Object.assign(Ta.prototype,{isPlane:!0,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a); +this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(a,b,c){b=fh.subVectors(c,b).cross(Yk.subVectors(a,b)).normalize();this.setFromNormalAndCoplanarPoint(b,a);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate(); +return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(a,b){void 0===b&&(console.warn("THREE.Plane: .intersectLine() target is now required"),b=new n);var c=a.delta(fh),d=this.normal.dot(c); +if(0===d){if(0===this.distanceToPoint(a.start))return b.copy(a.start)}else if(d=-(a.start.dot(this.normal)+this.constant)/d,!(0>d||1b&&0a&&0=Cb.x+Cb.y},getUV:function(a,b,c,d,e,f,g,h){this.getBarycoord(a,b,c,d,Cb);h.set(0,0);h.addScaledVector(e,Cb.x);h.addScaledVector(f,Cb.y);h.addScaledVector(g,Cb.z);return h},isFrontFacing:function(a,b,c,d){bb.subVectors(c,b);Bb.subVectors(a,b);return 0>bb.cross(Bb).dot(d)?!0:!1}});Object.assign(oa.prototype,{set:function(a, +b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},getArea:function(){bb.subVectors(this.c,this.b);Bb.subVectors(this.a,this.b);return.5*bb.cross(Bb).length()},getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"), +a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return oa.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new Ta);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return oa.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return oa.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return oa.containsPoint(a, +this.a,this.b,this.c)},isFrontFacing:function(a){return oa.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),b=new n);var c=this.a,d=this.b,e=this.c;td.subVectors(d,c);ud.subVectors(e,c);hh.subVectors(a,c);var f=td.dot(hh),g=ud.dot(hh);if(0>=f&&0>=g)return b.copy(c);ih.subVectors(a,d);var h=td.dot(ih),l=ud.dot(ih);if(0<=h&&l<= +h)return b.copy(d);var m=f*l-h*g;if(0>=m&&0<=f&&0>=h)return d=f/(f-h),b.copy(c).addScaledVector(td,d);jh.subVectors(a,e);a=td.dot(jh);var k=ud.dot(jh);if(0<=k&&a<=k)return b.copy(e);f=a*g-f*k;if(0>=f&&0<=g&&0>=k)return m=g/(g-k),b.copy(c).addScaledVector(ud,m);g=h*k-a*l;if(0>=g&&0<=l-h&&0<=a-k)return Oi.subVectors(e,d),m=(l-h)/(l-h+(a-k)),b.copy(d).addScaledVector(Oi,m);e=1/(g+f+m);d=f*e;m*=e;return b.copy(c).addScaledVector(td,d).addScaledVector(ud,m)},equals:function(a){return a.a.equals(this.a)&& +a.b.equals(this.b)&&a.c.equals(this.c)}});var Pi={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017, darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504, green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734, lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734, palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407, -steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},xa={h:0,s:0,l:0},uf={h:0,s:0,l:0};Object.assign(K.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a); -this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=O.euclideanModulo(a,1);b=O.clamp(b,0,1);c=O.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=Pf(c,b,a+1/3),this.g=Pf(c,b,a),this.b=Pf(c,b,a-1/3));return this},setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c= +steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},za={h:0,s:0,l:0},Jf={h:0,s:0,l:0};Object.assign(z.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a); +this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=L.euclideanModulo(a,1);b=L.clamp(b,0,1);c=L.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=ag(c,b,a+1/3),this.g=ag(c,b,a),this.b=ag(c,b,a-1/3));return this},setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c= /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100, parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){d=parseFloat(c[1])/360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r= -parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0=h?l/(e+f):l/(2-e-f);switch(e){case b:g=(c- -d)/l+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;d.stencilWrite=this.stencilWrite;d.stencilFunc= -this.stencilFunc;d.stencilRef=this.stencilRef;d.stencilMask=this.stencilMask;d.stencilFail=this.stencilFail;d.stencilZFail=this.stencilZFail;d.stencilZPass=this.stencilZPass;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&1!==this.linewidth&&(d.linewidth=this.linewidth); -void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize);void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}", -fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}",side:1,blending:0});d.uniforms.tEquirect.value=b;b=new da(new Cb(5, -5,5),d);c.add(b);d=new Fc(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};$b.prototype=Object.create(Y.prototype);$b.prototype.constructor=$b;$b.prototype.isDataTexture=!0;var Sg=new n,tk=new n,uk=new sa;Object.assign(db.prototype,{isPlane:!0,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a, -b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(a,b,c){b=Sg.subVectors(c,b).cross(tk.subVectors(a,b)).normalize();this.setFromNormalAndCoplanarPoint(b,a);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*= --1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(a,b){void 0===b&&(console.warn("THREE.Plane: .intersectLine() target is now required"),b=new n);var c= -a.delta(Sg),d=this.normal.dot(c);if(0===d){if(0===this.distanceToPoint(a.start))return b.copy(a.start)}else if(d=-(a.start.dot(this.normal)+this.constant)/d,!(0>d||1b&&0a&&0c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],l=c[6],m=c[7],k=c[8],n=c[9],u=c[10],q=c[11],p=c[12],x=c[13],v=c[14];c=c[15];b[0].setComponents(f-a,m-g,q-k,c-p).normalize();b[1].setComponents(f+a,m+g,q+k,c+p).normalize();b[2].setComponents(f+ -d,m+h,q+n,c+x).normalize();b[3].setComponents(f-d,m-h,q-n,c-x).normalize();b[4].setComponents(f-e,m-l,q-u,c-v).normalize();b[5].setComponents(f+e,m+l,q+u,c+v).normalize();return this},intersectsObject:function(a){var b=a.geometry;null===b.boundingSphere&&b.computeBoundingSphere();ud.copy(b.boundingSphere).applyMatrix4(a.matrixWorld);return this.intersectsSphere(ud)},intersectsSprite:function(a){ud.center.set(0,0,0);ud.radius=.7071067811865476;ud.applyMatrix4(a.matrixWorld);return this.intersectsSphere(ud)}, -intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)c;c++){var d=b[c];xf.x=0d.distanceToPoint(xf))return!1}return!0},containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}});var P={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif", -alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif", -aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}", +parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}return a&&0=h?l/(e+f):l/(2-e-f);switch(e){case b:g=(c-d)/l+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;d.stencilWrite=this.stencilWrite;d.stencilWriteMask=this.stencilWriteMask;d.stencilFunc=this.stencilFunc;d.stencilRef=this.stencilRef;d.stencilFuncMask=this.stencilFuncMask;d.stencilFail= +this.stencilFail;d.stencilZFail=this.stencilZFail;d.stencilZPass=this.stencilZPass;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&1!==this.linewidth&&(d.linewidth=this.linewidth);void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize); +void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}",fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}", +side:1,blending:0});d.uniforms.tEquirect.value=b;b=new S(new Jd(5,5,5),d);c.add(b);d=new Gc(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};ac.prototype=Object.create(W.prototype);ac.prototype.constructor=ac;ac.prototype.isDataTexture=!0;var wd=new pb,Lf=new n;Object.assign(Hc.prototype,{set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f); +return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromProjectionMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],l=c[6],m=c[7],k=c[8],p=c[9],n=c[10],r=c[11],q=c[12],v=c[13],u=c[14];c=c[15];b[0].setComponents(f-a,m-g,r-k,c-q).normalize();b[1].setComponents(f+a,m+g,r+k,c+q).normalize();b[2].setComponents(f+d,m+h,r+p,c+v).normalize();b[3].setComponents(f- +d,m-h,r-p,c-v).normalize();b[4].setComponents(f-e,m-l,r-n,c-u).normalize();b[5].setComponents(f+e,m+l,r+n,c+u).normalize();return this},intersectsObject:function(a){var b=a.geometry;null===b.boundingSphere&&b.computeBoundingSphere();wd.copy(b.boundingSphere).applyMatrix4(a.matrixWorld);return this.intersectsSphere(wd)},intersectsSprite:function(a){wd.center.set(0,0,0);wd.radius=.7071067811865476;wd.applyMatrix4(a.matrixWorld);return this.intersectsSphere(wd)},intersectsSphere:function(a){var b=this.planes, +c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)c;c++){var d=b[c];Lf.x=0d.distanceToPoint(Lf))return!1}return!0},containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}});var D={common:{diffuse:{value:new z(15658734)},opacity:{value:1},map:{value:null}, +uvTransform:{value:new wa},uv2Transform:{value:new wa},alphaMap:{value:null}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98},maxMipLevel:{value:0}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalScale:{value:new u(1, +1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:2.5E-4},fogNear:{value:1},fogFar:{value:2E3},fogColor:{value:new z(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{}}},directionalLightShadows:{value:[],properties:{shadowBias:{}, +shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{}}},spotLightShadows:{value:[],properties:{shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{}}},pointLightShadows:{value:[],properties:{shadowBias:{},shadowRadius:{}, +shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}},pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new z(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},uvTransform:{value:new wa}},sprite:{diffuse:{value:new z(15658734)},opacity:{value:1},center:{value:new u(.5, +.5)},rotation:{value:0},map:{value:null},alphaMap:{value:null},uvTransform:{value:new wa}}};Id.prototype=Object.create(N.prototype);Id.prototype.constructor=Id;bc.prototype=Object.create(B.prototype);bc.prototype.constructor=bc;var O={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif", +aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif",aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif", +begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif", bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif", -clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif", -clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif", -color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n\tvec3 clearCoatNormal;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}", -cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif", -defaultnormal_vertex:"vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif", -emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}", -envmap_fragment:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif", -envmap_pars_fragment:"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif", -envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif", -envmap_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif", -fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", -gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif", -lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif", -lights_pars_begin:"uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif", -lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)", -lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif", -lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat ccDotNL = saturate( dot( geometry.clearCoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearCoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifndef STANDARD\n\t\tfloat ccDotNV = saturate( dot( geometry.clearCoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearCoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\tfloat clearCoatInv = 1.0 - clearCoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;\n\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}", -lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tgeometry.clearCoatNormal = clearCoatNormal;\n#else\n\tgeometry.clearCoatNormal = geometryNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif", -lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearCoatNormal, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif", -lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, irradiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif", -logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif",map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif", -map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif", -metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif", -morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif", -normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;", -normal_fragment_maps:"#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy = normalScale * mapN.xy;\n\t\t\tnormal = normalize( vTBN * mapN );\n\t\t#else\n\t\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t\t#endif\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif", -normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#endif\n#endif\n#if ( defined ( USE_NORMALMAP ) && !defined ( OBJECTSPACE_NORMALMAP )) || defined ( USE_CLEARCOAT_NORMALMAP )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvec3 NfromST = cross( S, T );\n\t\t\tif( dot( NfromST, N ) > 0.0 ) {\n\t\t\t\tS *= -1.0;\n\t\t\t\tT *= -1.0;\n\t\t\t}\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif", -clearcoat_normal_fragment_begin:"#ifdef USE_CLEARCOAT_NORMALMAP\n vec3 clearCoatNormal = geometryNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearCoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearCoatNormalScale * mapN.xy;\n\t\tclearCoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearCoatNormal = perturbNormal2Arb( - vViewPosition, clearCoatNormal, clearCoatNormalScale, clearCoatNormalMap );\n\t#endif\n#endif", -clearcoat_normalmap_pars_fragment:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearCoatNormalMap;\n\tuniform vec2 clearCoatNormalScale;\n#endif",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}", -premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", -roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", +clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif", +clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\tvViewPosition = - mvPosition.xyz;\n#endif", +color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}", +cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_maxMipLevel 8.0\n#define cubeUV_minMipLevel 4.0\n#define cubeUV_maxTileSize 256.0\n#define cubeUV_minTileSize 16.0\nfloat getFace(vec3 direction) {\n vec3 absDirection = abs(direction);\n float face = -1.0;\n if (absDirection.x > absDirection.z) {\n if (absDirection.x > absDirection.y)\n face = direction.x > 0.0 ? 0.0 : 3.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n } else {\n if (absDirection.z > absDirection.y)\n face = direction.z > 0.0 ? 2.0 : 5.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n }\n return face;\n}\nvec2 getUV(vec3 direction, float face) {\n vec2 uv;\n if (face == 0.0) {\n uv = vec2(-direction.z, direction.y) / abs(direction.x);\n } else if (face == 1.0) {\n uv = vec2(direction.x, -direction.z) / abs(direction.y);\n } else if (face == 2.0) {\n uv = direction.xy / abs(direction.z);\n } else if (face == 3.0) {\n uv = vec2(direction.z, direction.y) / abs(direction.x);\n } else if (face == 4.0) {\n uv = direction.xz / abs(direction.y);\n } else {\n uv = vec2(-direction.x, direction.y) / abs(direction.z);\n }\n return 0.5 * (uv + 1.0);\n}\nvec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n float face = getFace(direction);\n float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n mipInt = max(mipInt, cubeUV_minMipLevel);\n float faceSize = exp2(mipInt);\n float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n vec2 uv = getUV(direction, face) * (faceSize - 1.0);\n vec2 f = fract(uv);\n uv += 0.5 - f;\n if (face > 2.0) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize;\n if(mipInt < cubeUV_maxMipLevel){\n uv.y += 2.0 * cubeUV_maxTileSize;\n }\n uv.y += filterInt * 2.0 * cubeUV_minTileSize;\n uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n uv *= texelSize;\n vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x += texelSize;\n vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.y += texelSize;\n vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x -= texelSize;\n vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n vec3 tm = mix(tl, tr, f.x);\n vec3 bm = mix(bl, br, f.x);\n return mix(tm, bm, f.y);\n}\n#define r0 1.0\n#define v0 0.339\n#define m0 -2.0\n#define r1 0.8\n#define v1 0.276\n#define m1 -1.0\n#define r4 0.4\n#define v4 0.046\n#define m4 2.0\n#define r5 0.305\n#define v5 0.016\n#define m5 3.0\n#define r6 0.21\n#define v6 0.0038\n#define m6 4.0\nfloat roughnessToMip(float roughness) {\n float mip = 0.0;\n if (roughness >= r1) {\n mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n } else if (roughness >= r4) {\n mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n } else if (roughness >= r5) {\n mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n } else if (roughness >= r6) {\n mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n } else {\n mip = -2.0 * log2(1.16 * roughness); }\n return mip;\n}\nvec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {\n float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);\n float mipF = fract(mip);\n float mipInt = floor(mip);\n vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);\n if (mipF == 0.0) {\n return vec4(color0, 1.0);\n } else {\n vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);\n return vec4(mix(color0, color1, mipF), 1.0);\n }\n}\n#endif", +defaultnormal_vertex:"vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif", +displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif", +emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",encodings_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}", +envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\t\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif", +envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif", +envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif", +envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) { \n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif", +fog_vertex:"#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif", +gradientmap_pars_fragment:"#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif", +lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif", +lights_pars_begin:"uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif", +lights_toon_fragment:"ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_toon_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)", +lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)", +lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif", +lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}", +lights_fragment_begin:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif", +lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif", +lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif", +logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif", +map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif", +map_particle_pars_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif", +morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif", +morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif", +normal_fragment_begin:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;", +normal_fragment_maps:"#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif", +normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif", +clearcoat_normal_fragment_begin:"#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif",clearcoat_pars_fragment:"#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif", +packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}", +premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", +roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif", -shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif", -shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}", +shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif", +shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}", skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif", skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif", -specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}", -uv_pars_fragment:"#ifdef USE_UV\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#ifdef USE_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif",uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif", -worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}", -cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}", -depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}", -depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}", +uv_pars_fragment:"#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif",uv_vertex:"#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif", +uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif",background_frag:"uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}", +background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}",cube_frag:"#include \nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include \n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}", +cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}", +depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}", distanceRGBA_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}", distanceRGBA_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}", equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}", -equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}", -meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}", -meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}", +meshtoon_frag:"#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshtoon_vert:"#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", +meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshphysical_frag:"#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", -meshphysical_vert:"#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", -normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", -normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", -points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", -points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}", -shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}",shadow_vert:"#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", -sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}", -sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"}, -J={common:{diffuse:{value:new K(15658734)},opacity:{value:1},map:{value:null},uvTransform:{value:new sa},alphaMap:{value:null}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98},maxMipLevel:{value:0}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null}, -normalScale:{value:new y(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:2.5E-4},fogNear:{value:1},fogFar:{value:2E3},fogColor:{value:new K(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{}, -shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}}, -pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new K(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},uvTransform:{value:new sa}},sprite:{diffuse:{value:new K(15658734)},opacity:{value:1},center:{value:new y(.5,.5)},rotation:{value:0},map:{value:null},uvTransform:{value:new sa}}}, -eb={basic:{uniforms:ka([J.common,J.specularmap,J.envmap,J.aomap,J.lightmap,J.fog]),vertexShader:P.meshbasic_vert,fragmentShader:P.meshbasic_frag},lambert:{uniforms:ka([J.common,J.specularmap,J.envmap,J.aomap,J.lightmap,J.emissivemap,J.fog,J.lights,{emissive:{value:new K(0)}}]),vertexShader:P.meshlambert_vert,fragmentShader:P.meshlambert_frag},phong:{uniforms:ka([J.common,J.specularmap,J.envmap,J.aomap,J.lightmap,J.emissivemap,J.bumpmap,J.normalmap,J.displacementmap,J.gradientmap,J.fog,J.lights,{emissive:{value:new K(0)}, -specular:{value:new K(1118481)},shininess:{value:30}}]),vertexShader:P.meshphong_vert,fragmentShader:P.meshphong_frag},standard:{uniforms:ka([J.common,J.envmap,J.aomap,J.lightmap,J.emissivemap,J.bumpmap,J.normalmap,J.displacementmap,J.roughnessmap,J.metalnessmap,J.fog,J.lights,{emissive:{value:new K(0)},roughness:{value:.5},metalness:{value:.5},envMapIntensity:{value:1}}]),vertexShader:P.meshphysical_vert,fragmentShader:P.meshphysical_frag},matcap:{uniforms:ka([J.common,J.bumpmap,J.normalmap,J.displacementmap, -J.fog,{matcap:{value:null}}]),vertexShader:P.meshmatcap_vert,fragmentShader:P.meshmatcap_frag},points:{uniforms:ka([J.points,J.fog]),vertexShader:P.points_vert,fragmentShader:P.points_frag},dashed:{uniforms:ka([J.common,J.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:P.linedashed_vert,fragmentShader:P.linedashed_frag},depth:{uniforms:ka([J.common,J.displacementmap]),vertexShader:P.depth_vert,fragmentShader:P.depth_frag},normal:{uniforms:ka([J.common,J.bumpmap,J.normalmap, -J.displacementmap,{opacity:{value:1}}]),vertexShader:P.normal_vert,fragmentShader:P.normal_frag},sprite:{uniforms:ka([J.sprite,J.fog]),vertexShader:P.sprite_vert,fragmentShader:P.sprite_frag},background:{uniforms:{uvTransform:{value:new sa},t2D:{value:null}},vertexShader:P.background_vert,fragmentShader:P.background_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:P.cube_vert,fragmentShader:P.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:P.equirect_vert, -fragmentShader:P.equirect_frag},distanceRGBA:{uniforms:ka([J.common,J.displacementmap,{referencePosition:{value:new n},nearDistance:{value:1},farDistance:{value:1E3}}]),vertexShader:P.distanceRGBA_vert,fragmentShader:P.distanceRGBA_frag},shadow:{uniforms:ka([J.lights,J.fog,{color:{value:new K(0)},opacity:{value:1}}]),vertexShader:P.shadow_vert,fragmentShader:P.shadow_frag}};eb.physical={uniforms:ka([eb.standard.uniforms,{clearCoat:{value:0},clearCoatRoughness:{value:0},clearCoatNormalScale:{value:new y(1, -1)},clearCoatNormalMap:{value:null}}]),vertexShader:P.meshphysical_vert,fragmentShader:P.meshphysical_frag};Fd.prototype=Object.create(F.prototype);Fd.prototype.constructor=Fd;ac.prototype=Object.create(D.prototype);ac.prototype.constructor=ac;qb.prototype=Object.create(Y.prototype);qb.prototype.constructor=qb;qb.prototype.isCubeTexture=!0;Object.defineProperty(qb.prototype,"images",{get:function(){return this.image},set:function(a){this.image=a}});Gc.prototype=Object.create(Y.prototype);Gc.prototype.constructor= -Gc;Gc.prototype.isDataTexture2DArray=!0;Hc.prototype=Object.create(Y.prototype);Hc.prototype.constructor=Hc;Hc.prototype.isDataTexture3D=!0;var ph=new Y,nj=new Gc,pj=new Hc,qh=new qb,jh=[],lh=[],oh=new Float32Array(16),nh=new Float32Array(9),mh=new Float32Array(4);rh.prototype.updateCache=function(a){var b=this.cache;a instanceof Float32Array&&b.length!==a.length&&(this.cache=new Float32Array(a.length));Ha(b,a)};sh.prototype.setValue=function(a,b,c){for(var d=this.seq,e=0,f=d.length;e!==f;++e){var g= -d[e];g.setValue(a,b[g.id],c)}};var Xf=/([\w\d_]+)(\])?(\[|\.)?/g;Eb.prototype.setValue=function(a,b,c,d){b=this.map[b];void 0!==b&&b.setValue(a,c,d)};Eb.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};Eb.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e],h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};Eb.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in b&&c.push(f)}return c};var Qj=0,Zj=0;Fb.prototype=Object.create(Q.prototype); -Fb.prototype.constructor=Fb;Fb.prototype.isMeshDepthMaterial=!0;Fb.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};Gb.prototype=Object.create(Q.prototype); -Gb.prototype.constructor=Gb;Gb.prototype.isMeshDistanceMaterial=!0;Gb.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.referencePosition.copy(a.referencePosition);this.nearDistance=a.nearDistance;this.farDistance=a.farDistance;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;return this};Jc.prototype=Object.assign(Object.create(C.prototype), -{constructor:Jc,isGroup:!0});Jd.prototype=Object.assign(Object.create(la.prototype),{constructor:Jd,isArrayCamera:!0});var Fh=new n,Gh=new n;Object.assign($f.prototype,ma.prototype);Object.assign(Hh.prototype,ma.prototype);Object.assign(Le.prototype,{isFogExp2:!0,clone:function(){return new Le(this.color,this.density)},toJSON:function(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}});Object.assign(Me.prototype,{isFog:!0,clone:function(){return new Me(this.color,this.near, -this.far)},toJSON:function(){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}}});Object.defineProperty(bc.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(bc.prototype,{isInterleavedBuffer:!0,onUploadCallback:function(){},setArray:function(a){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.count=void 0!==a?a.length/this.stride:0;this.array=a;return this},setDynamic:function(a){this.dynamic= -a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.count=a.count;this.stride=a.stride;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d=0,e=this.stride;da.far||b.push({distance:e, -point:Be.clone(),uv:ta.getUV(Be,yf,Ce,zf,qi,Tg,ri,new y),face:null,object:this})},clone:function(){return(new this.constructor(this.material)).copy(this)},copy:function(a){C.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});var Af=new n,si=new n;Nd.prototype=Object.assign(Object.create(C.prototype),{constructor:Nd,isLOD:!0,copy:function(a){C.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=b[c].distance)b[c-1].object.visible=!1,b[c].object.visible=!0;else break;for(;cc||(h.applyMatrix4(this.matrixWorld),u=a.ray.origin.distanceTo(h),ua.far||b.push({distance:u,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}}else for(d=0,t=r.length/3-1;dc||(h.applyMatrix4(this.matrixWorld),u=a.ray.origin.distanceTo(h),ua.far||b.push({distance:u,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null, -object:this}))}else if(d.isGeometry)for(f=d.vertices,g=f.length,d=0;dc||(h.applyMatrix4(this.matrixWorld),u=a.ray.origin.distanceTo(h),ua.far||b.push({distance:u,point:e.clone().applyMatrix4(this.matrixWorld),index:d,face:null,faceIndex:null,object:this}))}},clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});var Cf=new n,Df=new n;aa.prototype=Object.assign(Object.create(ia.prototype),{constructor:aa, -isLineSegments:!0,computeLineDistances:function(){var a=this.geometry;if(a.isBufferGeometry)if(null===a.index){for(var b=a.attributes.position,c=[],d=0,e=b.count;d=a.HAVE_CURRENT_DATA&& -(this.needsUpdate=!0)}});Nc.prototype=Object.create(Y.prototype);Nc.prototype.constructor=Nc;Nc.prototype.isCompressedTexture=!0;Pd.prototype=Object.create(Y.prototype);Pd.prototype.constructor=Pd;Pd.prototype.isCanvasTexture=!0;Qd.prototype=Object.create(Y.prototype);Qd.prototype.constructor=Qd;Qd.prototype.isDepthTexture=!0;Oc.prototype=Object.create(D.prototype);Oc.prototype.constructor=Oc;Rd.prototype=Object.create(F.prototype);Rd.prototype.constructor=Rd;Pc.prototype=Object.create(D.prototype); -Pc.prototype.constructor=Pc;Sd.prototype=Object.create(F.prototype);Sd.prototype.constructor=Sd;pa.prototype=Object.create(D.prototype);pa.prototype.constructor=pa;Td.prototype=Object.create(F.prototype);Td.prototype.constructor=Td;Qc.prototype=Object.create(pa.prototype);Qc.prototype.constructor=Qc;Ud.prototype=Object.create(F.prototype);Ud.prototype.constructor=Ud;cc.prototype=Object.create(pa.prototype);cc.prototype.constructor=cc;Vd.prototype=Object.create(F.prototype);Vd.prototype.constructor= -Vd;Rc.prototype=Object.create(pa.prototype);Rc.prototype.constructor=Rc;Wd.prototype=Object.create(F.prototype);Wd.prototype.constructor=Wd;Sc.prototype=Object.create(pa.prototype);Sc.prototype.constructor=Sc;Xd.prototype=Object.create(F.prototype);Xd.prototype.constructor=Xd;dc.prototype=Object.create(D.prototype);dc.prototype.constructor=dc;dc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON();return a};Yd.prototype=Object.create(F.prototype);Yd.prototype.constructor= -Yd;Tc.prototype=Object.create(D.prototype);Tc.prototype.constructor=Tc;Zd.prototype=Object.create(F.prototype);Zd.prototype.constructor=Zd;Uc.prototype=Object.create(D.prototype);Uc.prototype.constructor=Uc;var wk={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=Kh(a,0,e,c,!0),g=[];if(!f||f.next===f.prev)return g;var h;if(d){var l=c;d=[];var k;var n=0;for(k=b.length;n80*c){var q=h=a[0];var p=d=a[1];for(l=c;lh&&(h=n),b>d&&(d=b);h=Math.max(h-q,d-p);h=0!==h?1/h:0}be(f,g,c,q,p,h);return g}},rb={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;erb.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];Oh(a);Ph(c,a);var f=a.length;b.forEach(Oh); -for(a=0;aMath.abs(g-l)?[new y(a,1-c),new y(h,1-d),new y(k,1-e),new y(t,1-b)]:[new y(g,1-c),new y(l,1-d),new y(n,1-e),new y(u,1-b)]}};de.prototype=Object.create(F.prototype); -de.prototype.constructor=de;Wc.prototype=Object.create(fb.prototype);Wc.prototype.constructor=Wc;ee.prototype=Object.create(F.prototype);ee.prototype.constructor=ee;Jb.prototype=Object.create(D.prototype);Jb.prototype.constructor=Jb;fe.prototype=Object.create(F.prototype);fe.prototype.constructor=fe;Xc.prototype=Object.create(D.prototype);Xc.prototype.constructor=Xc;ge.prototype=Object.create(F.prototype);ge.prototype.constructor=ge;Yc.prototype=Object.create(D.prototype);Yc.prototype.constructor= -Yc;gc.prototype=Object.create(F.prototype);gc.prototype.constructor=gc;gc.prototype.toJSON=function(){var a=F.prototype.toJSON.call(this);return Rh(this.parameters.shapes,a)};hc.prototype=Object.create(D.prototype);hc.prototype.constructor=hc;hc.prototype.toJSON=function(){var a=D.prototype.toJSON.call(this);return Rh(this.parameters.shapes,a)};Zc.prototype=Object.create(D.prototype);Zc.prototype.constructor=Zc;ic.prototype=Object.create(F.prototype);ic.prototype.constructor=ic;sb.prototype=Object.create(D.prototype); -sb.prototype.constructor=sb;he.prototype=Object.create(ic.prototype);he.prototype.constructor=he;ie.prototype=Object.create(sb.prototype);ie.prototype.constructor=ie;je.prototype=Object.create(F.prototype);je.prototype.constructor=je;$c.prototype=Object.create(D.prototype);$c.prototype.constructor=$c;var Ba=Object.freeze({WireframeGeometry:Oc,ParametricGeometry:Rd,ParametricBufferGeometry:Pc,TetrahedronGeometry:Td,TetrahedronBufferGeometry:Qc,OctahedronGeometry:Ud,OctahedronBufferGeometry:cc,IcosahedronGeometry:Vd, -IcosahedronBufferGeometry:Rc,DodecahedronGeometry:Wd,DodecahedronBufferGeometry:Sc,PolyhedronGeometry:Sd,PolyhedronBufferGeometry:pa,TubeGeometry:Xd,TubeBufferGeometry:dc,TorusKnotGeometry:Yd,TorusKnotBufferGeometry:Tc,TorusGeometry:Zd,TorusBufferGeometry:Uc,TextGeometry:de,TextBufferGeometry:Wc,SphereGeometry:ee,SphereBufferGeometry:Jb,RingGeometry:fe,RingBufferGeometry:Xc,PlaneGeometry:Fd,PlaneBufferGeometry:ac,LatheGeometry:ge,LatheBufferGeometry:Yc,ShapeGeometry:gc,ShapeBufferGeometry:hc,ExtrudeGeometry:fc, -ExtrudeBufferGeometry:fb,EdgesGeometry:Zc,ConeGeometry:he,ConeBufferGeometry:ie,CylinderGeometry:ic,CylinderBufferGeometry:sb,CircleGeometry:je,CircleBufferGeometry:$c,BoxGeometry:Ec,BoxBufferGeometry:Cb});jc.prototype=Object.create(Q.prototype);jc.prototype.constructor=jc;jc.prototype.isShadowMaterial=!0;jc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);return this};ad.prototype=Object.create(ya.prototype);ad.prototype.constructor=ad;ad.prototype.isRawShaderMaterial= -!0;gb.prototype=Object.create(Q.prototype);gb.prototype.constructor=gb;gb.prototype.isMeshStandardMaterial=!0;gb.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity; -this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth= -a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};kc.prototype=Object.create(gb.prototype);kc.prototype.constructor=kc;kc.prototype.isMeshPhysicalMaterial=!0;kc.prototype.copy=function(a){gb.prototype.copy.call(this,a);this.defines={PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearCoat=a.clearCoat;this.clearCoatRoughness=a.clearCoatRoughness; -this.clearCoatNormalMap=a.clearCoatNormalMap;this.clearCoatNormalScale.copy(a.clearCoatNormalScale);return this};Qa.prototype=Object.create(Q.prototype);Qa.prototype.constructor=Qa;Qa.prototype.isMeshPhongMaterial=!0;Qa.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive); -this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio; -this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};lc.prototype=Object.create(Qa.prototype);lc.prototype.constructor=lc;lc.prototype.isMeshToonMaterial=!0;lc.prototype.copy=function(a){Qa.prototype.copy.call(this,a);this.gradientMap=a.gradientMap;return this};mc.prototype=Object.create(Q.prototype); -mc.prototype.constructor=mc;mc.prototype.isMeshNormalMaterial=!0;mc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets= -a.morphTargets;this.morphNormals=a.morphNormals;return this};nc.prototype=Object.create(Q.prototype);nc.prototype.constructor=nc;nc.prototype.isMeshLambertMaterial=!0;nc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap= -a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};oc.prototype=Object.create(Q.prototype);oc.prototype.constructor=oc;oc.prototype.isMeshMatcapMaterial= -!0;oc.prototype.copy=function(a){Q.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map=a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets; -this.morphNormals=a.morphNormals;return this};pc.prototype=Object.create(S.prototype);pc.prototype.constructor=pc;pc.prototype.isLineDashedMaterial=!0;pc.prototype.copy=function(a){S.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var xk=Object.freeze({ShadowMaterial:jc,SpriteMaterial:Ib,RawShaderMaterial:ad,ShaderMaterial:ya,PointsMaterial:Pa,MeshPhysicalMaterial:kc,MeshStandardMaterial:gb,MeshPhongMaterial:Qa,MeshToonMaterial:lc,MeshNormalMaterial:mc, -MeshLambertMaterial:nc,MeshDepthMaterial:Fb,MeshDistanceMaterial:Gb,MeshBasicMaterial:Fa,MeshMatcapMaterial:oc,LineDashedMaterial:pc,LineBasicMaterial:S,Material:Q}),ba={arraySlice:function(a,b,c){return ba.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&&a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof -DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,l=0;l!==b;++l)e[g++]=a[h+l];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!== -f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}}};Object.assign(Ia.prototype,{evaluate:function(a){var b=this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f, -1),e=f-1),a=this.getValueSize(),this.times=ba.arraySlice(c,e,f),this.values=ba.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times;b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrack: Time is not a valid number.", -this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&ba.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: Value is not a valid number.",this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(O.clamp(d[l-1].dot(d[l]),-1,1)),e[l].applyMatrix4(h.makeRotationAxis(g,c))),f[l].crossVectors(d[l],e[l]);if(!0===b)for(c=Math.acos(O.clamp(e[0].dot(e[a]),-1,1)),c/=a,0 -d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>l&&(l=e);Ug.initNonuniformCatmullRom(f.x, -g.x,h.x,c.x,d,e,l);Vg.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,l);Wg.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d,e,l)}else"catmullrom"===this.curveType&&(Ug.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),Vg.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),Wg.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(Ug.calc(a),Vg.calc(a),Wg.calc(a));return b};wa.prototype.copy=function(a){H.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length- -2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(Uh(d,e.x,f.x,g.x,c.x),Uh(d,e.y,f.y,g.y,c.y));return b};Va.prototype.copy=function(a){H.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths();return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths; -for(var a=[],b=0,c=0,d=this.curves.length;cNumber.EPSILON){if(0>k&&(g=b[f],l=-l,h=b[e],k=-k),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e= -k*(a.x-g.x)-l*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d}var e=rb.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new Kb;h.curves=g.curves;b.push(h);return b}var l=!e(f[0].getPoints());l=a?!l:l;h=[];var k=[],n=[],t=0;k[t]=void 0;n[t]=[];for(var u=0,q=f.length;ue.opacity&&(e.transparent=!0);Ai.setTextures(d);return Ai.parse(e)}});var Gf,vg={getContext:function(){void 0===Gf&&(Gf=new (window.AudioContext||window.webkitAudioContext));return Gf},setContext:function(a){Gf=a}};Object.assign(qg.prototype,{load:function(a,b,c,d){var e=new Ra(this.manager);e.setResponseType("arraybuffer");e.setPath(this.path);e.load(a,function(a){a=a.slice(0);vg.getContext().decodeAudioData(a,function(a){b(a)})},c,d)},setPath:function(a){this.path=a; -return this}});Object.assign(hf.prototype,{isSphericalHarmonics3:!0,set:function(a){for(var b=0;9>b;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0,0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.282095);b.addScale(e[1],.488603*d);b.addScale(e[2],.488603*a);b.addScale(e[3],.488603*c);b.addScale(e[4],1.092548*c*d);b.addScale(e[5],1.092548*d*a);b.addScale(e[6],.315392*(3* -a*a-1));b.addScale(e[7],1.092548*c*a);b.addScale(e[8],.546274*(c*c-d*d));return b},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.886227);b.addScale(e[1],1.023328*d);b.addScale(e[2],1.023328*a);b.addScale(e[3],1.023328*c);b.addScale(e[4],.858086*c*d);b.addScale(e[5],.858086*d*a);b.addScale(e[6],.743125*a*a-.247708);b.addScale(e[7],.858086*c*a);b.addScale(e[8],.429043*(c*c-d*d));return b},add:function(a){for(var b=0;9>b;b++)this.coefficients[b].add(a.coefficients[b]); -return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c],b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0},copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a){for(var b=this.coefficients,c=0;9>c;c++)b[c].fromArray(a,3*c); -return this},toArray:function(){for(var a=[],b=this.coefficients,c=0;9>c;c++)b[c].toArray(a,3*c);return a}});Object.assign(hf,{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d;b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});Xa.prototype=Object.assign(Object.create(T.prototype),{constructor:Xa,isLightProbe:!0,copy:function(a){T.prototype.copy.call(this,a);this.sh.copy(a.sh);this.intensity= -a.intensity;return this},toJSON:function(a){return T.prototype.toJSON.call(this,a)}});rg.prototype=Object.assign(Object.create(Xa.prototype),{constructor:rg,isHemisphereLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this,a)}});sg.prototype=Object.assign(Object.create(Xa.prototype),{constructor:sg,isAmbientLightProbe:!0,copy:function(a){Xa.prototype.copy.call(this,a);return this},toJSON:function(a){return Xa.prototype.toJSON.call(this, -a)}});var Bi=new M,Ci=new M;Object.assign(Xh.prototype,{update:function(a){var b=this._cache;if(b.focus!==a.focus||b.fov!==a.fov||b.aspect!==a.aspect*this.aspect||b.near!==a.near||b.far!==a.far||b.zoom!==a.zoom||b.eyeSep!==this.eyeSep){b.focus=a.focus;b.fov=a.fov;b.aspect=a.aspect*this.aspect;b.near=a.near;b.far=a.far;b.zoom=a.zoom;b.eyeSep=this.eyeSep;var c=a.projectionMatrix.clone(),d=b.eyeSep/2,e=d*b.near/b.focus,f=b.near*Math.tan(O.DEG2RAD*b.fov*.5)/b.zoom;Ci.elements[12]=-d;Bi.elements[12]=d; -d=-f*b.aspect+e;var g=f*b.aspect+e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraL.projectionMatrix.copy(c);d=-f*b.aspect-e;g=f*b.aspect-e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraR.projectionMatrix.copy(c)}this.cameraL.matrixWorld.copy(a.matrixWorld).multiply(Ci);this.cameraR.matrixWorld.copy(a.matrixWorld).multiply(Bi)}});Object.assign(tg.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now(); -this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});var wc=new n,Di=new na,Ak=new n,xc=new n;ug.prototype=Object.assign(Object.create(C.prototype), -{constructor:ug,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter); -this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this},updateMatrixWorld:function(a){C.prototype.updateMatrixWorld.call(this,a);a=this.context.listener;var b=this.up;this.timeDelta=this._clock.getDelta();this.matrixWorld.decompose(wc,Di,Ak);xc.set(0,0,-1).applyQuaternion(Di);if(a.positionX){var c=this.context.currentTime+this.timeDelta; -a.positionX.linearRampToValueAtTime(wc.x,c);a.positionY.linearRampToValueAtTime(wc.y,c);a.positionZ.linearRampToValueAtTime(wc.z,c);a.forwardX.linearRampToValueAtTime(xc.x,c);a.forwardY.linearRampToValueAtTime(xc.y,c);a.forwardZ.linearRampToValueAtTime(xc.z,c);a.upX.linearRampToValueAtTime(b.x,c);a.upY.linearRampToValueAtTime(b.y,c);a.upZ.linearRampToValueAtTime(b.z,c)}else a.setPosition(wc.x,wc.y,wc.z),a.setOrientation(xc.x,xc.y,xc.z,b.x,b.y,b.z)}});ed.prototype=Object.assign(Object.create(C.prototype), -{constructor:ed,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this},setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},play:function(){if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing."); -else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else{var a=this.context.createBufferSource();a.buffer=this.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);this.startTime=this.context.currentTime;a.start(this.startTime,this.offset);this.isPlaying=!0;this.source=a;this.setDetune(this.detune);this.setPlaybackRate(this.playbackRate);return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control."); -else return!0===this.isPlaying&&(this.source.stop(),this.source.onended=null,this.offset+=(this.context.currentTime-this.startTime)*this.playbackRate,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.source.stop(),this.source.onended=null,this.offset=0,this.isPlaying=!1,this},connect:function(){if(0\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}", +normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", +normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", +points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}", +points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}", +shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n\t#include \n\t#include \n}",shadow_vert:"#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", +sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}", +sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"}, +eb={basic:{uniforms:va([D.common,D.specularmap,D.envmap,D.aomap,D.lightmap,D.fog]),vertexShader:O.meshbasic_vert,fragmentShader:O.meshbasic_frag},lambert:{uniforms:va([D.common,D.specularmap,D.envmap,D.aomap,D.lightmap,D.emissivemap,D.fog,D.lights,{emissive:{value:new z(0)}}]),vertexShader:O.meshlambert_vert,fragmentShader:O.meshlambert_frag},phong:{uniforms:va([D.common,D.specularmap,D.envmap,D.aomap,D.lightmap,D.emissivemap,D.bumpmap,D.normalmap,D.displacementmap,D.fog,D.lights,{emissive:{value:new z(0)}, +specular:{value:new z(1118481)},shininess:{value:30}}]),vertexShader:O.meshphong_vert,fragmentShader:O.meshphong_frag},standard:{uniforms:va([D.common,D.envmap,D.aomap,D.lightmap,D.emissivemap,D.bumpmap,D.normalmap,D.displacementmap,D.roughnessmap,D.metalnessmap,D.fog,D.lights,{emissive:{value:new z(0)},roughness:{value:.5},metalness:{value:.5},envMapIntensity:{value:1}}]),vertexShader:O.meshphysical_vert,fragmentShader:O.meshphysical_frag},toon:{uniforms:va([D.common,D.specularmap,D.aomap,D.lightmap, +D.emissivemap,D.bumpmap,D.normalmap,D.displacementmap,D.gradientmap,D.fog,D.lights,{emissive:{value:new z(0)},specular:{value:new z(1118481)},shininess:{value:30}}]),vertexShader:O.meshtoon_vert,fragmentShader:O.meshtoon_frag},matcap:{uniforms:va([D.common,D.bumpmap,D.normalmap,D.displacementmap,D.fog,{matcap:{value:null}}]),vertexShader:O.meshmatcap_vert,fragmentShader:O.meshmatcap_frag},points:{uniforms:va([D.points,D.fog]),vertexShader:O.points_vert,fragmentShader:O.points_frag},dashed:{uniforms:va([D.common, +D.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:O.linedashed_vert,fragmentShader:O.linedashed_frag},depth:{uniforms:va([D.common,D.displacementmap]),vertexShader:O.depth_vert,fragmentShader:O.depth_frag},normal:{uniforms:va([D.common,D.bumpmap,D.normalmap,D.displacementmap,{opacity:{value:1}}]),vertexShader:O.normal_vert,fragmentShader:O.normal_frag},sprite:{uniforms:va([D.sprite,D.fog]),vertexShader:O.sprite_vert,fragmentShader:O.sprite_frag},background:{uniforms:{uvTransform:{value:new wa}, +t2D:{value:null}},vertexShader:O.background_vert,fragmentShader:O.background_frag},cube:{uniforms:va([D.envmap,{opacity:{value:1}}]),vertexShader:O.cube_vert,fragmentShader:O.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:O.equirect_vert,fragmentShader:O.equirect_frag},distanceRGBA:{uniforms:va([D.common,D.displacementmap,{referencePosition:{value:new n},nearDistance:{value:1},farDistance:{value:1E3}}]),vertexShader:O.distanceRGBA_vert,fragmentShader:O.distanceRGBA_frag},shadow:{uniforms:va([D.lights, +D.fog,{color:{value:new z(0)},opacity:{value:1}}]),vertexShader:O.shadow_vert,fragmentShader:O.shadow_frag}};eb.physical={uniforms:va([eb.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatNormalScale:{value:new u(1,1)},clearcoatNormalMap:{value:null},sheen:{value:new z(0)},transparency:{value:0}}]),vertexShader:O.meshphysical_vert,fragmentShader:O.meshphysical_frag};qb.prototype=Object.create(W.prototype);qb.prototype.constructor= +qb;qb.prototype.isCubeTexture=!0;Object.defineProperty(qb.prototype,"images",{get:function(){return this.image},set:function(a){this.image=a}});Ic.prototype=Object.create(W.prototype);Ic.prototype.constructor=Ic;Ic.prototype.isDataTexture2DArray=!0;Jc.prototype=Object.create(W.prototype);Jc.prototype.constructor=Jc;Jc.prototype.isDataTexture3D=!0;var Hh=new W,Pj=new Ic,Rj=new Jc,Ih=new qb,Bh=[],Dh=[],Gh=new Float32Array(16),Fh=new Float32Array(9),Eh=new Float32Array(4);Jh.prototype.updateCache=function(a){var b= +this.cache;a instanceof Float32Array&&b.length!==a.length&&(this.cache=new Float32Array(a.length));Ia(b,a)};Kh.prototype.setValue=function(a,b,c){for(var d=this.seq,e=0,f=d.length;e!==f;++e){var g=d[e];g.setValue(a,b[g.id],c)}};var gg=/([\w\d_]+)(\])?(\[|\.)?/g;Eb.prototype.setValue=function(a,b,c,d){b=this.map[b];void 0!==b&&b.setValue(a,c,d)};Eb.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};Eb.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e], +h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};Eb.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in b&&c.push(f)}return c};var wk=0,ig=/^[ \t]*#include +<([\w\d./]+)>/gm,Th=/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,Sh=/#pragma unroll_loop_start[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g,Gk=0;Fb.prototype=Object.create(K.prototype);Fb.prototype.constructor= +Fb;Fb.prototype.isMeshDepthMaterial=!0;Fb.prototype.copy=function(a){K.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};Gb.prototype=Object.create(K.prototype);Gb.prototype.constructor= +Gb;Gb.prototype.isMeshDistanceMaterial=!0;Gb.prototype.copy=function(a){K.prototype.copy.call(this,a);this.referencePosition.copy(a.referencePosition);this.nearDistance=a.nearDistance;this.farDistance=a.farDistance;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;return this};Qe.prototype=Object.assign(Object.create(ba.prototype), +{constructor:Qe,isArrayCamera:!0});Mc.prototype=Object.assign(Object.create(E.prototype),{constructor:Mc,isGroup:!0});Object.assign($h.prototype,Ea.prototype);Object.assign(Re.prototype,{isFogExp2:!0,clone:function(){return new Re(this.color,this.density)},toJSON:function(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}});Object.assign(Se.prototype,{isFog:!0,clone:function(){return new Se(this.color,this.near,this.far)},toJSON:function(){return{type:"Fog",color:this.color.getHex(), +near:this.near,far:this.far}}});Object.defineProperty(rb.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(rb.prototype,{isInterleavedBuffer:!0,onUploadCallback:function(){},setUsage:function(a){this.usage=a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.count=a.count;this.stride=a.stride;this.usage=a.usage;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d=0,e=this.stride;da.far||b.push({distance:e,point:De.clone(),uv:oa.getUV(De,Mf,Ee,Nf,Ri,oh, +Si,new u),face:null,object:this})},clone:function(){return(new this.constructor(this.material)).copy(this)},copy:function(a){E.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});var Of=new n,Ti=new n;Rd.prototype=Object.assign(Object.create(E.prototype),{constructor:Rd,isLOD:!0,copy:function(a){E.prototype.copy.call(this,a,!1);for(var b=a.levels,c=0,d=b.length;c=b[c].distance)b[c-1].object.visible=!1,b[c].object.visible=!0;else break;for(this._currentLevel=c-1;cd||(h.applyMatrix4(this.matrixWorld),x=a.ray.origin.distanceTo(h),xa.far||b.push({distance:x,point:e.clone().applyMatrix4(this.matrixWorld),index:c,face:null,faceIndex:null,object:this}))}}else for(c=0,p=t.length/3-1;cd||(h.applyMatrix4(this.matrixWorld),x=a.ray.origin.distanceTo(h),xa.far||b.push({distance:x,point:e.clone().applyMatrix4(this.matrixWorld),index:c,face:null,faceIndex:null,object:this}))}else if(c.isGeometry)for(f=c.vertices,g=f.length,c=0;cd||(h.applyMatrix4(this.matrixWorld),x=a.ray.origin.distanceTo(h),xa.far||b.push({distance:x,point:e.clone().applyMatrix4(this.matrixWorld), +index:c,face:null,faceIndex:null,object:this}))}},clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});var Qf=new n,Rf=new n;ma.prototype=Object.assign(Object.create(Ka.prototype),{constructor:ma,isLineSegments:!0,computeLineDistances:function(){var a=this.geometry;if(a.isBufferGeometry)if(null===a.index){for(var b=a.attributes.position,c=[],d=0,e=b.count;d=a.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}});Qc.prototype=Object.create(W.prototype);Qc.prototype.constructor=Qc;Qc.prototype.isCompressedTexture=!0;Td.prototype=Object.create(W.prototype);Td.prototype.constructor=Td;Td.prototype.isCanvasTexture=!0;Ud.prototype=Object.create(W.prototype);Ud.prototype.constructor=Ud;Ud.prototype.isDepthTexture= +!0;Rc.prototype=Object.create(B.prototype);Rc.prototype.constructor=Rc;Vd.prototype=Object.create(N.prototype);Vd.prototype.constructor=Vd;Sc.prototype=Object.create(B.prototype);Sc.prototype.constructor=Sc;Wd.prototype=Object.create(N.prototype);Wd.prototype.constructor=Wd;Ga.prototype=Object.create(B.prototype);Ga.prototype.constructor=Ga;Xd.prototype=Object.create(N.prototype);Xd.prototype.constructor=Xd;Tc.prototype=Object.create(Ga.prototype);Tc.prototype.constructor=Tc;Yd.prototype=Object.create(N.prototype); +Yd.prototype.constructor=Yd;cc.prototype=Object.create(Ga.prototype);cc.prototype.constructor=cc;Zd.prototype=Object.create(N.prototype);Zd.prototype.constructor=Zd;Uc.prototype=Object.create(Ga.prototype);Uc.prototype.constructor=Uc;$d.prototype=Object.create(N.prototype);$d.prototype.constructor=$d;Vc.prototype=Object.create(Ga.prototype);Vc.prototype.constructor=Vc;ae.prototype=Object.create(N.prototype);ae.prototype.constructor=ae;dc.prototype=Object.create(B.prototype);dc.prototype.constructor= +dc;dc.prototype.toJSON=function(){var a=B.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON();return a};be.prototype=Object.create(N.prototype);be.prototype.constructor=be;Wc.prototype=Object.create(B.prototype);Wc.prototype.constructor=Wc;ce.prototype=Object.create(N.prototype);ce.prototype.constructor=ce;Xc.prototype=Object.create(B.prototype);Xc.prototype.constructor=Xc;var al={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=ci(a,0,e,c,!0),g=[];if(!f||f.next=== +f.prev)return g;var h;if(d){var l=c;d=[];var k;var n=0;for(k=b.length;n80*c){var r=h=a[0];var q=d=a[1];for(l=c;lh&&(h=n),b>d&&(d=b);h=Math.max(h-r,d-q);h=0!==h?1/h:0}fe(f,g,c,r,q,h);return g}},sb={area:function(a){for(var b=a.length,c= +0,d=b-1,e=0;esb.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];gi(a);hi(c,a);var f=a.length;b.forEach(gi);for(a=0;aMath.abs(g-l)?[new u(a,1-c),new u(h,1-d),new u(k,1-e),new u(p,1-b)]:[new u(g,1-c),new u(l,1-d),new u(n,1-e),new u(x,1-b)]}};he.prototype=Object.create(N.prototype);he.prototype.constructor=he;Zc.prototype=Object.create(fb.prototype);Zc.prototype.constructor=Zc;ie.prototype=Object.create(N.prototype);ie.prototype.constructor=ie;gc.prototype=Object.create(B.prototype);gc.prototype.constructor=gc;je.prototype=Object.create(N.prototype);je.prototype.constructor= +je;$c.prototype=Object.create(B.prototype);$c.prototype.constructor=$c;ke.prototype=Object.create(N.prototype);ke.prototype.constructor=ke;ad.prototype=Object.create(B.prototype);ad.prototype.constructor=ad;hc.prototype=Object.create(N.prototype);hc.prototype.constructor=hc;hc.prototype.toJSON=function(){var a=N.prototype.toJSON.call(this);return ji(this.parameters.shapes,a)};ic.prototype=Object.create(B.prototype);ic.prototype.constructor=ic;ic.prototype.toJSON=function(){var a=B.prototype.toJSON.call(this); +return ji(this.parameters.shapes,a)};bd.prototype=Object.create(B.prototype);bd.prototype.constructor=bd;jc.prototype=Object.create(N.prototype);jc.prototype.constructor=jc;tb.prototype=Object.create(B.prototype);tb.prototype.constructor=tb;le.prototype=Object.create(jc.prototype);le.prototype.constructor=le;me.prototype=Object.create(tb.prototype);me.prototype.constructor=me;ne.prototype=Object.create(N.prototype);ne.prototype.constructor=ne;cd.prototype=Object.create(B.prototype);cd.prototype.constructor= +cd;var ua=Object.freeze({__proto__:null,WireframeGeometry:Rc,ParametricGeometry:Vd,ParametricBufferGeometry:Sc,TetrahedronGeometry:Xd,TetrahedronBufferGeometry:Tc,OctahedronGeometry:Yd,OctahedronBufferGeometry:cc,IcosahedronGeometry:Zd,IcosahedronBufferGeometry:Uc,DodecahedronGeometry:$d,DodecahedronBufferGeometry:Vc,PolyhedronGeometry:Wd,PolyhedronBufferGeometry:Ga,TubeGeometry:ae,TubeBufferGeometry:dc,TorusKnotGeometry:be,TorusKnotBufferGeometry:Wc,TorusGeometry:ce,TorusBufferGeometry:Xc,TextGeometry:he, +TextBufferGeometry:Zc,SphereGeometry:ie,SphereBufferGeometry:gc,RingGeometry:je,RingBufferGeometry:$c,PlaneGeometry:Id,PlaneBufferGeometry:bc,LatheGeometry:ke,LatheBufferGeometry:ad,ShapeGeometry:hc,ShapeBufferGeometry:ic,ExtrudeGeometry:fc,ExtrudeBufferGeometry:fb,EdgesGeometry:bd,ConeGeometry:le,ConeBufferGeometry:me,CylinderGeometry:jc,CylinderBufferGeometry:tb,CircleGeometry:ne,CircleBufferGeometry:cd,BoxGeometry:nh,BoxBufferGeometry:Jd});kc.prototype=Object.create(K.prototype);kc.prototype.constructor= +kc;kc.prototype.isShadowMaterial=!0;kc.prototype.copy=function(a){K.prototype.copy.call(this,a);this.color.copy(a.color);return this};ub.prototype=Object.create(Ba.prototype);ub.prototype.constructor=ub;ub.prototype.isRawShaderMaterial=!0;gb.prototype=Object.create(K.prototype);gb.prototype.constructor=gb;gb.prototype.isMeshStandardMaterial=!0;gb.prototype.copy=function(a){K.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness; +this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias; +this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;this.vertexTangents=a.vertexTangents;return this};lc.prototype=Object.create(gb.prototype); +lc.prototype.constructor=lc;lc.prototype.isMeshPhysicalMaterial=!0;lc.prototype.copy=function(a){gb.prototype.copy.call(this,a);this.defines={STANDARD:"",PHYSICAL:""};this.clearcoat=a.clearcoat;this.clearcoatMap=a.clearcoatMap;this.clearcoatRoughness=a.clearcoatRoughness;this.clearcoatRoughnessMap=a.clearcoatRoughnessMap;this.clearcoatNormalMap=a.clearcoatNormalMap;this.clearcoatNormalScale.copy(a.clearcoatNormalScale);this.reflectivity=a.reflectivity;this.sheen=a.sheen?(this.sheen||new z).copy(a.sheen): +null;this.transparency=a.transparency;return this};Jb.prototype=Object.create(K.prototype);Jb.prototype.constructor=Jb;Jb.prototype.isMeshPhongMaterial=!0;Jb.prototype.copy=function(a){K.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity= +a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth= +a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};mc.prototype=Object.create(K.prototype);mc.prototype.constructor=mc;mc.prototype.isMeshToonMaterial=!0;mc.prototype.copy=function(a){K.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.gradientMap=a.gradientMap; +this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias; +this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};nc.prototype=Object.create(K.prototype);nc.prototype.constructor=nc;nc.prototype.isMeshNormalMaterial=!0;nc.prototype.copy=function(a){K.prototype.copy.call(this,a);this.bumpMap=a.bumpMap; +this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};oc.prototype=Object.create(K.prototype);oc.prototype.constructor=oc;oc.prototype.isMeshLambertMaterial= +!0;oc.prototype.copy=function(a){K.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio; +this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};pc.prototype=Object.create(K.prototype);pc.prototype.constructor=pc;pc.prototype.isMeshMatcapMaterial=!0;pc.prototype.copy=function(a){K.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map= +a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};qc.prototype=Object.create(la.prototype);qc.prototype.constructor=qc;qc.prototype.isLineDashedMaterial= +!0;qc.prototype.copy=function(a){la.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var bl=Object.freeze({__proto__:null,ShadowMaterial:kc,SpriteMaterial:Ib,RawShaderMaterial:ub,ShaderMaterial:Ba,PointsMaterial:Va,MeshPhysicalMaterial:lc,MeshStandardMaterial:gb,MeshPhongMaterial:Jb,MeshToonMaterial:mc,MeshNormalMaterial:nc,MeshLambertMaterial:oc,MeshDepthMaterial:Fb,MeshDistanceMaterial:Gb,MeshBasicMaterial:Oa,MeshMatcapMaterial:pc,LineDashedMaterial:qc, +LineBasicMaterial:la,Material:K}),R={arraySlice:function(a,b,c){return R.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&&a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c}, +sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,l=0;l!==b;++l)e[g++]=a[h+l];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d], +void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}},subclip:function(a,b,c,d,e){e=e||30;a=a.clone();a.name=b;var f=[];for(b=0;b=d))for(l.push(g.times[n]),p=0;p +a.tracks[b].times[0]&&(c=a.tracks[b].times[0]);for(b=0;b=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=R.arraySlice(c, +e,f),this.values=R.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times;b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!== +e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&R.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: Value is not a valid number.",this,f,d);a=!1;break}return a},optimize:function(){for(var a=R.arraySlice(this.times),b=R.arraySlice(this.values),c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(), +c=Math.acos(L.clamp(d[l-1].dot(d[l]),-1,1)),e[l].applyMatrix4(h.makeRotationAxis(g,c))),f[l].crossVectors(d[l],e[l]);if(!0===b)for(c=Math.acos(L.clamp(e[0].dot(e[a]),-1,1)),c/=a,0d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>l&&(l=e);ph.initNonuniformCatmullRom(f.x,g.x,h.x, +c.x,d,e,l);qh.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,l);rh.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d,e,l)}else"catmullrom"===this.curveType&&(ph.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),qh.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),rh.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(ph.calc(a),qh.calc(a),rh.calc(a));return b};pa.prototype.copy=function(a){G.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length- +2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(li(d,e.x,f.x,g.x,c.x),li(d,e.y,f.y,g.y,c.y));return b};Za.prototype.copy=function(a){G.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths();return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},getCurveLengths:function(){if(this.cacheLengths&& +this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;cNumber.EPSILON){if(0>l&&(g=b[f],k=-k,h=b[e],l=-l),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=l*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d} +var e=sb.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new Kb;h.curves=g.curves;b.push(h);return b}var l=!e(f[0].getPoints());l=a?!l:l;h=[];var k=[],n=[],p=0;k[p]=void 0;n[p]=[];for(var u=0,r=f.length;ub;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0,0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.282095); +b.addScale(e[1],.488603*d);b.addScale(e[2],.488603*a);b.addScale(e[3],.488603*c);b.addScale(e[4],1.092548*c*d);b.addScale(e[5],1.092548*d*a);b.addScale(e[6],.315392*(3*a*a-1));b.addScale(e[7],1.092548*c*a);b.addScale(e[8],.546274*(c*c-d*d));return b},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.886227);b.addScale(e[1],1.023328*d);b.addScale(e[2],1.023328*a);b.addScale(e[3],1.023328*c);b.addScale(e[4],.858086*c*d);b.addScale(e[5],.858086* +d*a);b.addScale(e[6],.743125*a*a-.247708);b.addScale(e[7],.858086*c*a);b.addScale(e[8],.429043*(c*c-d*d));return b},add:function(a){for(var b=0;9>b;b++)this.coefficients[b].add(a.coefficients[b]);return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c],b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0}, +copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a,b){void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].fromArray(a,b+3*d);return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);for(var c=this.coefficients,d=0;9>d;d++)c[d].toArray(a,b+3*d);return a}});Object.assign(uf,{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d; +b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});ab.prototype=Object.assign(Object.create(ea.prototype),{constructor:ab,isLightProbe:!0,copy:function(a){ea.prototype.copy.call(this,a);this.sh.copy(a.sh);this.intensity=a.intensity;return this},toJSON:function(a){return ea.prototype.toJSON.call(this,a)}});Eg.prototype=Object.assign(Object.create(ab.prototype),{constructor:Eg,isHemisphereLightProbe:!0,copy:function(a){ab.prototype.copy.call(this,a);return this},toJSON:function(a){return ab.prototype.toJSON.call(this, +a)}});Fg.prototype=Object.assign(Object.create(ab.prototype),{constructor:Fg,isAmbientLightProbe:!0,copy:function(a){ab.prototype.copy.call(this,a);return this},toJSON:function(a){return ab.prototype.toJSON.call(this,a)}});var cj=new P,dj=new P;Object.assign(mi.prototype,{update:function(a){var b=this._cache;if(b.focus!==a.focus||b.fov!==a.fov||b.aspect!==a.aspect*this.aspect||b.near!==a.near||b.far!==a.far||b.zoom!==a.zoom||b.eyeSep!==this.eyeSep){b.focus=a.focus;b.fov=a.fov;b.aspect=a.aspect*this.aspect; +b.near=a.near;b.far=a.far;b.zoom=a.zoom;b.eyeSep=this.eyeSep;var c=a.projectionMatrix.clone(),d=b.eyeSep/2,e=d*b.near/b.focus,f=b.near*Math.tan(L.DEG2RAD*b.fov*.5)/b.zoom;dj.elements[12]=-d;cj.elements[12]=d;d=-f*b.aspect+e;var g=f*b.aspect+e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraL.projectionMatrix.copy(c);d=-f*b.aspect-e;g=f*b.aspect-e;c.elements[0]=2*b.near/(g-d);c.elements[8]=(g+d)/(g-d);this.cameraR.projectionMatrix.copy(c)}this.cameraL.matrixWorld.copy(a.matrixWorld).multiply(dj); +this.cameraR.matrixWorld.copy(a.matrixWorld).multiply(cj)}});Object.assign(Gg.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance? +Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});var wc=new n,ej=new Aa,dl=new n,xc=new n;Hg.prototype=Object.assign(Object.create(E.prototype),{constructor:Hg,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!== +this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this},updateMatrixWorld:function(a){E.prototype.updateMatrixWorld.call(this,a);a=this.context.listener; +var b=this.up;this.timeDelta=this._clock.getDelta();this.matrixWorld.decompose(wc,ej,dl);xc.set(0,0,-1).applyQuaternion(ej);if(a.positionX){var c=this.context.currentTime+this.timeDelta;a.positionX.linearRampToValueAtTime(wc.x,c);a.positionY.linearRampToValueAtTime(wc.y,c);a.positionZ.linearRampToValueAtTime(wc.z,c);a.forwardX.linearRampToValueAtTime(xc.x,c);a.forwardY.linearRampToValueAtTime(xc.y,c);a.forwardZ.linearRampToValueAtTime(xc.z,c);a.upX.linearRampToValueAtTime(b.x,c);a.upY.linearRampToValueAtTime(b.y, +c);a.upZ.linearRampToValueAtTime(b.z,c)}else a.setPosition(wc.x,wc.y,wc.z),a.setOrientation(xc.x,xc.y,xc.z,b.x,b.y,b.z)}});id.prototype=Object.assign(Object.create(E.prototype),{constructor:id,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this},setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect(); +return this},setMediaStreamSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaStreamNode";this.source=this.context.createMediaStreamSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},play:function(a){void 0===a&&(a=0);if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control."); +else return this._startedAt=this.context.currentTime+a,a=this.context.createBufferSource(),a.buffer=this.buffer,a.loop=this.loop,a.loopStart=this.loopStart,a.loopEnd=this.loopEnd,a.onended=this.onEnded.bind(this),a.start(this._startedAt,this._pausedAt+this.offset,this.duration),this.isPlaying=!0,this.source=a,this.setDetune(this.detune),this.setPlaybackRate(this.playbackRate),this.connect()},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control."); +else return!0===this.isPlaying&&(this._pausedAt+=Math.max(this.context.currentTime-this._startedAt,0)*this.playbackRate,this.source.stop(),this.source.onended=null,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this._pausedAt=0,this.source.stop(),this.source.onended=null,this.isPlaying=!1,this},connect:function(){if(0d&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a, -b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){na.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});var Ck=/[\[\]\.:\/]/g,Dk="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",Ek=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]"),Fk=/(WCOD+)?/.source.replace("WCOD",Dk),Gk=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC","[^\\[\\]\\.:\\/]"),Hk=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"), -Ik=new RegExp("^"+Ek+Fk+Gk+Hk+"$"),Jk=["material","materials","bones"];Object.assign(Yh.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_, -c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(ra,{Composite:Yh,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new ra.Composite(a,b,c):new ra(a,b,c)},sanitizeNodeName:function(a){return a.replace(/\s/g,"_").replace(Ck,"")},parseTrackName:function(a){var b=Ik.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!== -c){var d=b.nodeName.substring(c+1);-1!==Jk.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName=d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b},findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var n=b++,t=a[n];c[t.uuid]=k;a[k]=t;c[l]=n;a[n]=h;h=0;for(l=e;h!==l;++h){t=d[h];var u=t[k];t[k]=t[n];t[n]=u}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var l=arguments[g].uuid,k=d[l];if(void 0!==k)if(delete d[l],kb||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){b=this.timeScale;var c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0]; -b*=d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a,c=this._clip.duration,d=this.loop,e=this._loopCount,f=2202===d;if(0===a)return-1===e?b:f&&1===(e&1)?c-b:b;if(2200===d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else{this.time=b;break a}this.clampWhenFinished?this.paused=!0:this.enabled=!1;this.time=b;this._mixer.dispatchEvent({type:"finished", -action:this,direction:0>a?-1:1})}else{-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,f)):this._setEndings(0===this.repetitions,!0,f));if(b>=c||0>b){d=Math.floor(b/c);b-=c*d;e+=Math.abs(d);var g=this.repetitions-e;0>=g?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f),this._loopCount=e,this.time=b,this._mixer.dispatchEvent({type:"loop", -action:this,loopDelta:d}))}else this.time=b;if(f&&1===(e&1))return c-b}return b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd=b?this.zeroSlopeAtEnd?2401:2400:2402)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]= -c;return this}});zg.prototype=Object.assign(Object.create(ma.prototype),{constructor:zg,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName,k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var m=d[h],n=m.name,t=k[n];if(void 0===t){t=f[h];if(void 0!==t){null===t._cacheIndex&&(++t.referenceCount,this._addInactiveBinding(t,g,n));continue}t=new yg(ra.create(c,n,b&&b._propertyBindings[h].binding.parsedPath), -m.ValueTypeName,m.getValueSize());++t.referenceCount;this._addInactiveBinding(t,g,n)}f[h]=t;a[h].resultBuffer=t.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}}, -_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions=[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length}, -get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}},_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&athis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"), -b=new y);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new y);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return Fi.copy(a).clamp(this.min,this.max).sub(a).length()},intersect:function(a){this.min.max(a.min); -this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var Gi=new n,Hf=new n;Object.assign(Dg.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0=== -a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b= -new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(a,b){Gi.subVectors(a,this.start);Hf.subVectors(this.end,this.start);a=Hf.dot(Hf);a=Hf.dot(Gi)/a;b&&(a=O.clamp(a,0,1));return a},closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new n);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a); -this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});re.prototype=Object.create(C.prototype);re.prototype.constructor=re;re.prototype.isImmediateRenderObject=!0;var nb=new n,Bb=new n,ah=new sa,Kk=["a","b","c"];se.prototype=Object.create(aa.prototype);se.prototype.constructor=se;se.prototype.update=function(){this.object.updateMatrixWorld(!0);ah.getNormalMatrix(this.object.matrixWorld);var a=this.object.matrixWorld,b=this.geometry.attributes.position, -c=this.object.geometry;if(c&&c.isGeometry)for(var d=c.vertices,e=c.faces,f=c=0,g=e.length;f -Math.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);C.prototype.updateMatrixWorld.call(this,a)};var Ni=new n,nf,Eg;vb.prototype=Object.create(C.prototype);vb.prototype.constructor=vb;vb.prototype.setDirection=function(a){.99999a.y?this.quaternion.set(1,0,0,0):(Ni.set(a.z,0,-a.x).normalize(),this.quaternion.setFromAxisAngle(Ni,Math.acos(a.y)))};vb.prototype.setLength=function(a, -b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};vb.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};vb.prototype.copy=function(a){C.prototype.copy.call(this,a,!1);this.line.copy(a.line);this.cone.copy(a.cone);return this};vb.prototype.clone=function(){return(new this.constructor).copy(this)};xe.prototype=Object.create(aa.prototype); -xe.prototype.constructor=xe;H.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(H.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(tb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); -a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new F,c=0,d=a.length;cd&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]= +a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){Aa.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});var fl=/[\[\]\.:\/]/g,gl="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",hl=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]"),il=/(WCOD+)?/.source.replace("WCOD",gl), +jl=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC","[^\\[\\]\\.:\\/]"),kl=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),ll=new RegExp("^"+hl+il+jl+kl+"$"),ml=["material","materials","bones"];Object.assign(ni.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a= +this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(ya,{Composite:ni,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new ya.Composite(a,b,c):new ya(a,b,c)},sanitizeNodeName:function(a){return a.replace(/\s/g,"_").replace(fl,"")},parseTrackName:function(a){var b=ll.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+ +a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!==c){var d=b.nodeName.substring(c+1);-1!==ml.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName=d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b},findNode:function(a,b){if(!b||""===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c= +a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var n=b++,p=a[n];c[p.uuid]=m;a[m]=p;c[k]=n;a[n]=h;h=0;for(k=e;h!==k;++h){p=d[h];var u=p[m];p[m]=p[n];p[n]=u}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k= +arguments[g].uuid,m=d[k];if(void 0!==m)if(delete d[k],mb||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){b=this.timeScale;var c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0];b*=d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a,c=this._clip.duration,d=this.loop,e=this._loopCount,f=2202===d;if(0===a)return-1=== +e?b:f&&1===(e&1)?c-b:b;if(2200===d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else{this.time=b;break a}this.clampWhenFinished?this.paused=!0:this.enabled=!1;this.time=b;this._mixer.dispatchEvent({type:"finished",action:this,direction:0>a?-1:1})}else{-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,f)):this._setEndings(0===this.repetitions,!0,f));if(b>=c||0>b){d=Math.floor(b/c);b-=c*d;e+=Math.abs(d);var g=this.repetitions-e;0>=g?(this.clampWhenFinished? +this.paused=!0:this.enabled=!1,this.time=b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f),this._loopCount=e,this.time=b,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:d}))}else this.time=b;if(f&&1===(e&1))return c-b}return b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd= +b?this.zeroSlopeAtEnd?2401:2400:2402)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]=c;return this}});Mg.prototype=Object.assign(Object.create(Ea.prototype),{constructor:Mg,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName, +k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var m=d[h],n=m.name,p=k[n];if(void 0===p){p=f[h];if(void 0!==p){null===p._cacheIndex&&(++p.referenceCount,this._addInactiveBinding(p,g,n));continue}p=new Lg(ya.create(c,n,b&&b._propertyBindings[h].binding.parsedPath),m.ValueTypeName,m.getValueSize());++p.referenceCount;this._addInactiveBinding(p,g,n)}f[h]=p;a[h].resultBuffer=p.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid, +c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}},_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions= +[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length},get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}}, +_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&athis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"),b=new u);return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.x< +this.min.x||a.min.x>this.max.x||a.max.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new u);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(a){return gj.copy(a).clamp(this.min,this.max).sub(a).length()},intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a); +this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var hj=new n,Vf=new n;Object.assign(Rg.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0===a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)}, +delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b=new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(a,b){hj.subVectors(a,this.start);Vf.subVectors(this.end, +this.start);a=Vf.dot(Vf);a=Vf.dot(hj)/a;b&&(a=L.clamp(a,0,1));return a},closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new n);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a);this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});se.prototype=Object.create(E.prototype); +se.prototype.constructor=se;se.prototype.isImmediateRenderObject=!0;var ij=new n;jd.prototype=Object.create(E.prototype);jd.prototype.constructor=jd;jd.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};jd.prototype.update=function(){this.light.updateMatrixWorld();var a=this.light.distance?this.light.distance:1E3,b=a*Math.tan(this.light.angle);this.cone.scale.set(b,b,a);ij.setFromMatrixPosition(this.light.target.matrixWorld);this.cone.lookAt(ij);void 0!==this.color? +this.cone.material.color.set(this.color):this.cone.material.color.copy(this.light.color)};var Qb=new n,Wf=new P,vh=new P;rc.prototype=Object.create(ma.prototype);rc.prototype.constructor=rc;rc.prototype.isSkeletonHelper=!0;rc.prototype.updateMatrixWorld=function(a){var b=this.bones,c=this.geometry,d=c.getAttribute("position");vh.getInverse(this.root.matrixWorld);for(var e=0,f=0;eMath.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);E.prototype.updateMatrixWorld.call(this,a)};var nj=new n,zf,Sg;xb.prototype=Object.create(E.prototype);xb.prototype.constructor=xb;xb.prototype.setDirection=function(a){.99999a.y?this.quaternion.set(1,0,0,0):(nj.set(a.z, +0,-a.x).normalize(),this.quaternion.setFromAxisAngle(nj,Math.acos(a.y)))};xb.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(1E-4,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};xb.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};xb.prototype.copy=function(a){E.prototype.copy.call(this,a,!1);this.line.copy(a.line);this.cone.copy(a.cone); +return this};xb.prototype.clone=function(){return(new this.constructor).copy(this)};we.prototype=Object.create(ma.prototype);we.prototype.constructor=we;var kb=Math.pow(2,8),oj=[.125,.215,.35,.446,.526,.582],yi=5+oj.length,lb={3E3:0,3001:1,3002:2,3004:3,3005:4,3006:5,3007:6},Wg=new hd,Af=function(a){var b=new Float32Array(a),c=new n(0,1,0);a=new ub({defines:{n:a},uniforms:{envMap:{value:null},samples:{value:1},weights:{value:b},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:c}, +inputEncoding:{value:lb[3E3]},outputEncoding:{value:lb[3E3]}},vertexShader:Yg(),fragmentShader:"\nprecision mediump float;\nprecision mediump int;\nvarying vec3 vOutputDirection;\nuniform sampler2D envMap;\nuniform int samples;\nuniform float weights[n];\nuniform bool latitudinal;\nuniform float dTheta;\nuniform float mipInt;\nuniform vec3 poleAxis;\n\n"+Zg()+"\n\n#define ENVMAP_TYPE_CUBE_UV\n#include \n\nvoid main() {\n\tgl_FragColor = vec4(0.0);\n\tfor (int i = 0; i < n; i++) {\n\t\tif (i >= samples)\n\t\t\tbreak;\n\t\tfor (int dir = -1; dir < 2; dir += 2) {\n\t\t\tif (i == 0 && dir == 1)\n\t\t\t\tcontinue;\n\t\t\tvec3 axis = latitudinal ? poleAxis : cross(poleAxis, vOutputDirection);\n\t\t\tif (all(equal(axis, vec3(0.0))))\n\t\t\t\taxis = cross(vec3(0.0, 1.0, 0.0), vOutputDirection);\n\t\t\taxis = normalize(axis);\n\t\t\tfloat theta = dTheta * float(dir * i);\n\t\t\tfloat cosTheta = cos(theta);\n\t\t\t// Rodrigues' axis-angle rotation\n\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross(axis, vOutputDirection) * sin(theta)\n\t\t\t\t\t+ axis * dot(axis, vOutputDirection) * (1.0 - cosTheta);\n\t\t\tgl_FragColor.rgb +=\n\t\t\t\t\tweights[i] * bilinearCubeUV(envMap, sampleDirection, mipInt);\n\t\t}\n\t}\n\tgl_FragColor = linearToOutputTexel(gl_FragColor);\n}\n\t\t", +blending:0,depthTest:!1,depthWrite:!1});a.type="SphericalGaussianBlur";return a}(20),Rb=null,Sb=null,wh=function(){for(var a=[],b=[],c=[],d=8,e=0;em;m++){var n=m%3*2/3-1,p=2p;p++)u=p%3,0==u?(c.up.set(0,d[p],0),c.lookAt(f[p],0,0)):1==u?(c.up.set(0,0,d[p]),c.lookAt(0,f[p],0)):(c.up.set(0,d[p],0),c.lookAt(0,0,f[p])),Xg(e,u*kb,2 0 ) { - x1 = src1[ srcOffset1 + 0 ], - y1 = src1[ srcOffset1 + 1 ], - z1 = src1[ srcOffset1 + 2 ], - w1 = src1[ srcOffset1 + 3 ]; + console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); - if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { + } - var s = 1 - t, +} - cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, +Object.assign( Matrix3.prototype, { - dir = ( cos >= 0 ? 1 : - 1 ), - sqrSin = 1 - cos * cos; + isMatrix3: true, - // Skip the Slerp for tiny steps to avoid numeric problems: - if ( sqrSin > Number.EPSILON ) { + set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { - var sin = Math.sqrt( sqrSin ), - len = Math.atan2( sin, cos * dir ); + var te = this.elements; - s = Math.sin( s * len ) / sin; - t = Math.sin( t * len ) / sin; + te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; + te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; + te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; - } + return this; - var tDir = t * dir; + }, - x0 = x0 * s + x1 * tDir; - y0 = y0 * s + y1 * tDir; - z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; + identity: function () { - // Normalize in case we just did a lerp: - if ( s === 1 - t ) { + this.set( - var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); + 1, 0, 0, + 0, 1, 0, + 0, 0, 1 - x0 *= f; - y0 *= f; - z0 *= f; - w0 *= f; + ); - } + return this; - } + }, - dst[ dstOffset ] = x0; - dst[ dstOffset + 1 ] = y0; - dst[ dstOffset + 2 ] = z0; - dst[ dstOffset + 3 ] = w0; + clone: function () { - } + return new this.constructor().fromArray( this.elements ); -} ); + }, -Object.defineProperties( Quaternion.prototype, { + copy: function ( m ) { - x: { + var te = this.elements; + var me = m.elements; - get: function () { + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; + te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; + te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; - return this._x; + return this; - }, + }, - set: function ( value ) { + extractBasis: function ( xAxis, yAxis, zAxis ) { - this._x = value; - this._onChangeCallback(); + xAxis.setFromMatrix3Column( this, 0 ); + yAxis.setFromMatrix3Column( this, 1 ); + zAxis.setFromMatrix3Column( this, 2 ); - } + return this; }, - y: { - - get: function () { + setFromMatrix4: function ( m ) { - return this._y; + var me = m.elements; - }, + this.set( - set: function ( value ) { + me[ 0 ], me[ 4 ], me[ 8 ], + me[ 1 ], me[ 5 ], me[ 9 ], + me[ 2 ], me[ 6 ], me[ 10 ] - this._y = value; - this._onChangeCallback(); + ); - } + return this; }, - z: { - - get: function () { - - return this._z; + multiply: function ( m ) { - }, + return this.multiplyMatrices( this, m ); - set: function ( value ) { + }, - this._z = value; - this._onChangeCallback(); + premultiply: function ( m ) { - } + return this.multiplyMatrices( m, this ); }, - w: { - - get: function () { - - return this._w; + multiplyMatrices: function ( a, b ) { - }, + var ae = a.elements; + var be = b.elements; + var te = this.elements; - set: function ( value ) { + var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; + var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; + var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; - this._w = value; - this._onChangeCallback(); + var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; + var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; + var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; - } + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; + te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; + te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; - } + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; + te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; + te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; -} ); + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; + te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; + te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; -Object.assign( Quaternion.prototype, { + return this; - isQuaternion: true, + }, - set: function ( x, y, z, w ) { + multiplyScalar: function ( s ) { - this._x = x; - this._y = y; - this._z = z; - this._w = w; + var te = this.elements; - this._onChangeCallback(); + te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; + te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; + te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; return this; }, - clone: function () { - - return new this.constructor( this._x, this._y, this._z, this._w ); - - }, - - copy: function ( quaternion ) { + determinant: function () { - this._x = quaternion.x; - this._y = quaternion.y; - this._z = quaternion.z; - this._w = quaternion.w; + var te = this.elements; - this._onChangeCallback(); + var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], + d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], + g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; - return this; + return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; }, - setFromEuler: function ( euler, update ) { + getInverse: function ( matrix, throwOnDegenerate ) { - if ( ! ( euler && euler.isEuler ) ) { + if ( matrix && matrix.isMatrix4 ) { - throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); + console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." ); } - var x = euler._x, y = euler._y, z = euler._z, order = euler.order; - - // http://www.mathworks.com/matlabcentral/fileexchange/ - // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ - // content/SpinCalc.m - - var cos = Math.cos; - var sin = Math.sin; + var me = matrix.elements, + te = this.elements, - var c1 = cos( x / 2 ); - var c2 = cos( y / 2 ); - var c3 = cos( z / 2 ); + n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], + n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], + n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], - var s1 = sin( x / 2 ); - var s2 = sin( y / 2 ); - var s3 = sin( z / 2 ); + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, - if ( order === 'XYZ' ) { + det = n11 * t11 + n21 * t12 + n31 * t13; - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + if ( det === 0 ) { - } else if ( order === 'YXZ' ) { + var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"; - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + if ( throwOnDegenerate === true ) { - } else if ( order === 'ZXY' ) { + throw new Error( msg ); - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + } else { - } else if ( order === 'ZYX' ) { + console.warn( msg ); - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + } - } else if ( order === 'YZX' ) { + return this.identity(); - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; + } - } else if ( order === 'XZY' ) { + var detInv = 1 / det; - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; + te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; - } + te[ 3 ] = t12 * detInv; + te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; + te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; - if ( update !== false ) this._onChangeCallback(); + te[ 6 ] = t13 * detInv; + te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; + te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; return this; }, - setFromAxisAngle: function ( axis, angle ) { + transpose: function () { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + var tmp, m = this.elements; - // assumes axis is normalized + tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; + tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; + tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; - var halfAngle = angle / 2, s = Math.sin( halfAngle ); + return this; - this._x = axis.x * s; - this._y = axis.y * s; - this._z = axis.z * s; - this._w = Math.cos( halfAngle ); + }, - this._onChangeCallback(); + getNormalMatrix: function ( matrix4 ) { - return this; + return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); }, - setFromRotationMatrix: function ( m ) { + transposeIntoArray: function ( r ) { - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + var m = this.elements; - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + r[ 0 ] = m[ 0 ]; + r[ 1 ] = m[ 3 ]; + r[ 2 ] = m[ 6 ]; + r[ 3 ] = m[ 1 ]; + r[ 4 ] = m[ 4 ]; + r[ 5 ] = m[ 7 ]; + r[ 6 ] = m[ 2 ]; + r[ 7 ] = m[ 5 ]; + r[ 8 ] = m[ 8 ]; - var te = m.elements, + return this; - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], + }, - trace = m11 + m22 + m33, - s; + setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { - if ( trace > 0 ) { + var c = Math.cos( rotation ); + var s = Math.sin( rotation ); - s = 0.5 / Math.sqrt( trace + 1.0 ); + this.set( + sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, + - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, + 0, 0, 1 + ); - this._w = 0.25 / s; - this._x = ( m32 - m23 ) * s; - this._y = ( m13 - m31 ) * s; - this._z = ( m21 - m12 ) * s; + }, - } else if ( m11 > m22 && m11 > m33 ) { + scale: function ( sx, sy ) { - s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); + var te = this.elements; - this._w = ( m32 - m23 ) / s; - this._x = 0.25 * s; - this._y = ( m12 + m21 ) / s; - this._z = ( m13 + m31 ) / s; + te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; + te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; - } else if ( m22 > m33 ) { + return this; - s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); + }, - this._w = ( m13 - m31 ) / s; - this._x = ( m12 + m21 ) / s; - this._y = 0.25 * s; - this._z = ( m23 + m32 ) / s; + rotate: function ( theta ) { - } else { + var c = Math.cos( theta ); + var s = Math.sin( theta ); - s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); + var te = this.elements; - this._w = ( m21 - m12 ) / s; - this._x = ( m13 + m31 ) / s; - this._y = ( m23 + m32 ) / s; - this._z = 0.25 * s; + var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; + var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; - } + te[ 0 ] = c * a11 + s * a21; + te[ 3 ] = c * a12 + s * a22; + te[ 6 ] = c * a13 + s * a23; - this._onChangeCallback(); + te[ 1 ] = - s * a11 + c * a21; + te[ 4 ] = - s * a12 + c * a22; + te[ 7 ] = - s * a13 + c * a23; return this; }, - setFromUnitVectors: function ( vFrom, vTo ) { + translate: function ( tx, ty ) { - // assumes direction vectors vFrom and vTo are normalized + var te = this.elements; - var EPS = 0.000001; + te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; + te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; - var r = vFrom.dot( vTo ) + 1; + return this; - if ( r < EPS ) { + }, - r = 0; + equals: function ( matrix ) { - if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { + var te = this.elements; + var me = matrix.elements; - this._x = - vFrom.y; - this._y = vFrom.x; - this._z = 0; - this._w = r; + for ( var i = 0; i < 9; i ++ ) { - } else { + if ( te[ i ] !== me[ i ] ) return false; - this._x = 0; - this._y = - vFrom.z; - this._z = vFrom.y; - this._w = r; + } - } + return true; - } else { + }, - // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + fromArray: function ( array, offset ) { - this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; - this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; - this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; - this._w = r; + if ( offset === undefined ) offset = 0; + + for ( var i = 0; i < 9; i ++ ) { + + this.elements[ i ] = array[ i + offset ]; } - return this.normalize(); + return this; }, - angleTo: function ( q ) { - - return 2 * Math.acos( Math.abs( _Math.clamp( this.dot( q ), - 1, 1 ) ) ); + toArray: function ( array, offset ) { - }, + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - rotateTowards: function ( q, step ) { + var te = this.elements; - var angle = this.angleTo( q ); + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; - if ( angle === 0 ) return this; + array[ offset + 3 ] = te[ 3 ]; + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; - var t = Math.min( 1, step / angle ); + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + array[ offset + 8 ] = te[ 8 ]; - this.slerp( q, t ); + return array; - return this; + } - }, +} ); - inverse: function () { +/** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + */ - // quaternion is assumed to have unit length +var _canvas; - return this.conjugate(); +var ImageUtils = { - }, + getDataURL: function ( image ) { - conjugate: function () { + var canvas; - this._x *= - 1; - this._y *= - 1; - this._z *= - 1; + if ( typeof HTMLCanvasElement == 'undefined' ) { - this._onChangeCallback(); + return image.src; - return this; + } else if ( image instanceof HTMLCanvasElement ) { - }, + canvas = image; - dot: function ( v ) { + } else { - return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; + if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); - }, + _canvas.width = image.width; + _canvas.height = image.height; - lengthSq: function () { + var context = _canvas.getContext( '2d' ); - return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; + if ( image instanceof ImageData ) { - }, + context.putImageData( image, 0, 0 ); - length: function () { + } else { - return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); + context.drawImage( image, 0, 0, image.width, image.height ); - }, + } - normalize: function () { + canvas = _canvas; - var l = this.length(); + } - if ( l === 0 ) { + if ( canvas.width > 2048 || canvas.height > 2048 ) { - this._x = 0; - this._y = 0; - this._z = 0; - this._w = 1; + return canvas.toDataURL( 'image/jpeg', 0.6 ); } else { - l = 1 / l; - - this._x = this._x * l; - this._y = this._y * l; - this._z = this._z * l; - this._w = this._w * l; + return canvas.toDataURL( 'image/png' ); } - this._onChangeCallback(); - - return this; - - }, + } - multiply: function ( q, p ) { +}; - if ( p !== undefined ) { +/** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author szimek / https://github.com/szimek/ + */ - console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); - return this.multiplyQuaternions( q, p ); +var textureId = 0; - } +function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { - return this.multiplyQuaternions( this, q ); + Object.defineProperty( this, 'id', { value: textureId ++ } ); - }, + this.uuid = MathUtils.generateUUID(); - premultiply: function ( q ) { + this.name = ''; - return this.multiplyQuaternions( q, this ); + this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; + this.mipmaps = []; - }, + this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; - multiplyQuaternions: function ( a, b ) { + this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; + this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; - // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; + this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter; - var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; - var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; + this.anisotropy = anisotropy !== undefined ? anisotropy : 1; - this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; - this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; - this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; - this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + this.format = format !== undefined ? format : RGBAFormat; + this.internalFormat = null; + this.type = type !== undefined ? type : UnsignedByteType; - this._onChangeCallback(); + this.offset = new Vector2( 0, 0 ); + this.repeat = new Vector2( 1, 1 ); + this.center = new Vector2( 0, 0 ); + this.rotation = 0; - return this; + this.matrixAutoUpdate = true; + this.matrix = new Matrix3(); - }, + this.generateMipmaps = true; + this.premultiplyAlpha = false; + this.flipY = true; + this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) - slerp: function ( qb, t ) { + // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. + // + // Also changing the encoding after already used by a Material will not automatically make the Material + // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. + this.encoding = encoding !== undefined ? encoding : LinearEncoding; - if ( t === 0 ) return this; - if ( t === 1 ) return this.copy( qb ); + this.version = 0; + this.onUpdate = null; - var x = this._x, y = this._y, z = this._z, w = this._w; +} - // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ +Texture.DEFAULT_IMAGE = undefined; +Texture.DEFAULT_MAPPING = UVMapping; - var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; +Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - if ( cosHalfTheta < 0 ) { + constructor: Texture, - this._w = - qb._w; - this._x = - qb._x; - this._y = - qb._y; - this._z = - qb._z; + isTexture: true, - cosHalfTheta = - cosHalfTheta; + updateMatrix: function () { - } else { + this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); - this.copy( qb ); + }, - } + clone: function () { - if ( cosHalfTheta >= 1.0 ) { + return new this.constructor().copy( this ); - this._w = w; - this._x = x; - this._y = y; - this._z = z; + }, - return this; + copy: function ( source ) { - } + this.name = source.name; - var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; + this.image = source.image; + this.mipmaps = source.mipmaps.slice( 0 ); - if ( sqrSinHalfTheta <= Number.EPSILON ) { + this.mapping = source.mapping; - var s = 1 - t; - this._w = s * w + t * this._w; - this._x = s * x + t * this._x; - this._y = s * y + t * this._y; - this._z = s * z + t * this._z; + this.wrapS = source.wrapS; + this.wrapT = source.wrapT; - this.normalize(); - this._onChangeCallback(); + this.magFilter = source.magFilter; + this.minFilter = source.minFilter; - return this; + this.anisotropy = source.anisotropy; - } + this.format = source.format; + this.internalFormat = source.internalFormat; + this.type = source.type; - var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); - var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); - var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, - ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; + this.offset.copy( source.offset ); + this.repeat.copy( source.repeat ); + this.center.copy( source.center ); + this.rotation = source.rotation; - this._w = ( w * ratioA + this._w * ratioB ); - this._x = ( x * ratioA + this._x * ratioB ); - this._y = ( y * ratioA + this._y * ratioB ); - this._z = ( z * ratioA + this._z * ratioB ); + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrix.copy( source.matrix ); - this._onChangeCallback(); + this.generateMipmaps = source.generateMipmaps; + this.premultiplyAlpha = source.premultiplyAlpha; + this.flipY = source.flipY; + this.unpackAlignment = source.unpackAlignment; + this.encoding = source.encoding; return this; }, - equals: function ( quaternion ) { + toJSON: function ( meta ) { - return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); + var isRootObject = ( meta === undefined || typeof meta === 'string' ); - }, + if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { - fromArray: function ( array, offset ) { + return meta.textures[ this.uuid ]; - if ( offset === undefined ) offset = 0; + } - this._x = array[ offset ]; - this._y = array[ offset + 1 ]; - this._z = array[ offset + 2 ]; - this._w = array[ offset + 3 ]; + var output = { - this._onChangeCallback(); + metadata: { + version: 4.5, + type: 'Texture', + generator: 'Texture.toJSON' + }, - return this; + uuid: this.uuid, + name: this.name, - }, + mapping: this.mapping, - toArray: function ( array, offset ) { + repeat: [ this.repeat.x, this.repeat.y ], + offset: [ this.offset.x, this.offset.y ], + center: [ this.center.x, this.center.y ], + rotation: this.rotation, - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + wrap: [ this.wrapS, this.wrapT ], - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._w; + format: this.format, + type: this.type, + encoding: this.encoding, - return array; + minFilter: this.minFilter, + magFilter: this.magFilter, + anisotropy: this.anisotropy, - }, + flipY: this.flipY, - _onChange: function ( callback ) { + premultiplyAlpha: this.premultiplyAlpha, + unpackAlignment: this.unpackAlignment - this._onChangeCallback = callback; + }; - return this; + if ( this.image !== undefined ) { - }, + // TODO: Move to THREE.Image - _onChangeCallback: function () {} + var image = this.image; -} ); + if ( image.uuid === undefined ) { -/** - * @author mrdoob / http://mrdoob.com/ - * @author kile / http://kile.stravaganza.org/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ + image.uuid = MathUtils.generateUUID(); // UGH -var _vector = new Vector3(); -var _quaternion = new Quaternion(); + } -function Vector3( x, y, z ) { + if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; + var url; -} + if ( Array.isArray( image ) ) { -Object.assign( Vector3.prototype, { + // process array of images e.g. CubeTexture - isVector3: true, + url = []; - set: function ( x, y, z ) { + for ( var i = 0, l = image.length; i < l; i ++ ) { - this.x = x; - this.y = y; - this.z = z; + url.push( ImageUtils.getDataURL( image[ i ] ) ); - return this; + } - }, + } else { - setScalar: function ( scalar ) { + // process single image - this.x = scalar; - this.y = scalar; - this.z = scalar; + url = ImageUtils.getDataURL( image ); - return this; + } - }, + meta.images[ image.uuid ] = { + uuid: image.uuid, + url: url + }; - setX: function ( x ) { + } - this.x = x; + output.image = image.uuid; - return this; + } - }, + if ( ! isRootObject ) { - setY: function ( y ) { + meta.textures[ this.uuid ] = output; - this.y = y; + } - return this; + return output; }, - setZ: function ( z ) { - - this.z = z; + dispose: function () { - return this; + this.dispatchEvent( { type: 'dispose' } ); }, - setComponent: function ( index, value ) { + transformUv: function ( uv ) { - switch ( index ) { + if ( this.mapping !== UVMapping ) return uv; - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - default: throw new Error( 'index is out of range: ' + index ); + uv.applyMatrix3( this.matrix ); - } + if ( uv.x < 0 || uv.x > 1 ) { - return this; + switch ( this.wrapS ) { - }, + case RepeatWrapping: - getComponent: function ( index ) { + uv.x = uv.x - Math.floor( uv.x ); + break; - switch ( index ) { + case ClampToEdgeWrapping: - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - default: throw new Error( 'index is out of range: ' + index ); + uv.x = uv.x < 0 ? 0 : 1; + break; - } + case MirroredRepeatWrapping: - }, + if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { - clone: function () { + uv.x = Math.ceil( uv.x ) - uv.x; - return new this.constructor( this.x, this.y, this.z ); + } else { - }, + uv.x = uv.x - Math.floor( uv.x ); - copy: function ( v ) { + } + break; - this.x = v.x; - this.y = v.y; - this.z = v.z; + } + + } + + if ( uv.y < 0 || uv.y > 1 ) { + + switch ( this.wrapT ) { + + case RepeatWrapping: + + uv.y = uv.y - Math.floor( uv.y ); + break; + + case ClampToEdgeWrapping: + + uv.y = uv.y < 0 ? 0 : 1; + break; + + case MirroredRepeatWrapping: + + if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { + + uv.y = Math.ceil( uv.y ) - uv.y; + + } else { + + uv.y = uv.y - Math.floor( uv.y ); + + } + break; + + } + + } + + if ( this.flipY ) { + + uv.y = 1 - uv.y; + + } + + return uv; + + } + +} ); + +Object.defineProperty( Texture.prototype, "needsUpdate", { + + set: function ( value ) { + + if ( value === true ) this.version ++; + + } + +} ); + +/** + * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author philogb / http://blog.thejit.org/ + * @author mikael emtinger / http://gomo.se/ + * @author egraether / http://egraether.com/ + * @author WestLangley / http://github.com/WestLangley + */ + +function Vector4( x, y, z, w ) { + + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = ( w !== undefined ) ? w : 1; + +} + +Object.defineProperties( Vector4.prototype, { + + "width": { + + get: function () { + + return this.z; + + }, + + set: function ( value ) { + + this.z = value; + + } + + }, + + "height": { + + get: function () { + + return this.w; + + }, + + set: function ( value ) { + + this.w = value; + + } + + } + +} ); + +Object.assign( Vector4.prototype, { + + isVector4: true, + + set: function ( x, y, z, w ) { + + this.x = x; + this.y = y; + this.z = z; + this.w = w; + + return this; + + }, + + setScalar: function ( scalar ) { + + this.x = scalar; + this.y = scalar; + this.z = scalar; + this.w = scalar; + + return this; + + }, + + setX: function ( x ) { + + this.x = x; + + return this; + + }, + + setY: function ( y ) { + + this.y = y; + + return this; + + }, + + setZ: function ( z ) { + + this.z = z; + + return this; + + }, + + setW: function ( w ) { + + this.w = w; + + return this; + + }, + + setComponent: function ( index, value ) { + + switch ( index ) { + + case 0: this.x = value; break; + case 1: this.y = value; break; + case 2: this.z = value; break; + case 3: this.w = value; break; + default: throw new Error( 'index is out of range: ' + index ); + + } + + return this; + + }, + + getComponent: function ( index ) { + + switch ( index ) { + + case 0: return this.x; + case 1: return this.y; + case 2: return this.z; + case 3: return this.w; + default: throw new Error( 'index is out of range: ' + index ); + + } + + }, + + clone: function () { + + return new this.constructor( this.x, this.y, this.z, this.w ); + + }, + + copy: function ( v ) { + + this.x = v.x; + this.y = v.y; + this.z = v.z; + this.w = ( v.w !== undefined ) ? v.w : 1; return this; @@ -1728,7 +1971,7 @@ Object.assign( Vector3.prototype, { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); return this.addVectors( v, w ); } @@ -1736,6 +1979,7 @@ Object.assign( Vector3.prototype, { this.x += v.x; this.y += v.y; this.z += v.z; + this.w += v.w; return this; @@ -1746,6 +1990,7 @@ Object.assign( Vector3.prototype, { this.x += s; this.y += s; this.z += s; + this.w += s; return this; @@ -1756,6 +2001,7 @@ Object.assign( Vector3.prototype, { this.x = a.x + b.x; this.y = a.y + b.y; this.z = a.z + b.z; + this.w = a.w + b.w; return this; @@ -1766,6 +2012,7 @@ Object.assign( Vector3.prototype, { this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; + this.w += v.w * s; return this; @@ -1775,7 +2022,7 @@ Object.assign( Vector3.prototype, { if ( w !== undefined ) { - console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); return this.subVectors( v, w ); } @@ -1783,6 +2030,7 @@ Object.assign( Vector3.prototype, { this.x -= v.x; this.y -= v.y; this.z -= v.z; + this.w -= v.w; return this; @@ -1793,6 +2041,7 @@ Object.assign( Vector3.prototype, { this.x -= s; this.y -= s; this.z -= s; + this.w -= s; return this; @@ -1803,157 +2052,198 @@ Object.assign( Vector3.prototype, { this.x = a.x - b.x; this.y = a.y - b.y; this.z = a.z - b.z; + this.w = a.w - b.w; return this; }, - multiply: function ( v, w ) { + multiplyScalar: function ( scalar ) { - if ( w !== undefined ) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + this.w *= scalar; - console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); - return this.multiplyVectors( v, w ); + return this; - } + }, - this.x *= v.x; - this.y *= v.y; - this.z *= v.z; + applyMatrix4: function ( m ) { + + var x = this.x, y = this.y, z = this.z, w = this.w; + var e = m.elements; + + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; + this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; return this; }, - multiplyScalar: function ( scalar ) { - - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; + divideScalar: function ( scalar ) { - return this; + return this.multiplyScalar( 1 / scalar ); }, - multiplyVectors: function ( a, b ) { + setAxisAngleFromQuaternion: function ( q ) { - this.x = a.x * b.x; - this.y = a.y * b.y; - this.z = a.z * b.z; + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm - return this; + // q is assumed to be normalized - }, + this.w = 2 * Math.acos( q.w ); - applyEuler: function ( euler ) { + var s = Math.sqrt( 1 - q.w * q.w ); - if ( ! ( euler && euler.isEuler ) ) { + if ( s < 0.0001 ) { - console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); + this.x = 1; + this.y = 0; + this.z = 0; + + } else { + + this.x = q.x / s; + this.y = q.y / s; + this.z = q.z / s; } - return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); + return this; }, - applyAxisAngle: function ( axis, angle ) { + setAxisAngleFromRotationMatrix: function ( m ) { - return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - }, + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - applyMatrix3: function ( m ) { + var angle, x, y, z, // variables for result + epsilon = 0.01, // margin to allow for rounding errors + epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + te = m.elements, - this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; - this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; - this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - return this; + if ( ( Math.abs( m12 - m21 ) < epsilon ) && + ( Math.abs( m13 - m31 ) < epsilon ) && + ( Math.abs( m23 - m32 ) < epsilon ) ) { - }, + // singularity found + // first check for identity matrix which must have +1 for all terms + // in leading diagonal and zero in other terms - applyMatrix4: function ( m ) { + if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && + ( Math.abs( m13 + m31 ) < epsilon2 ) && + ( Math.abs( m23 + m32 ) < epsilon2 ) && + ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + // this singularity is identity matrix so angle = 0 - var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); + this.set( 1, 0, 0, 0 ); - this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; - this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; - this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; + return this; // zero angle, arbitrary axis - return this; + } - }, + // otherwise this singularity is angle = 180 - applyQuaternion: function ( q ) { + angle = Math.PI; - var x = this.x, y = this.y, z = this.z; - var qx = q.x, qy = q.y, qz = q.z, qw = q.w; + var xx = ( m11 + 1 ) / 2; + var yy = ( m22 + 1 ) / 2; + var zz = ( m33 + 1 ) / 2; + var xy = ( m12 + m21 ) / 4; + var xz = ( m13 + m31 ) / 4; + var yz = ( m23 + m32 ) / 4; - // calculate quat * vector + if ( ( xx > yy ) && ( xx > zz ) ) { - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = - qx * x - qy * y - qz * z; + // m11 is the largest diagonal term - // calculate result * inverse quat + if ( xx < epsilon ) { - this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; - this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; - this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; + x = 0; + y = 0.707106781; + z = 0.707106781; - return this; + } else { - }, + x = Math.sqrt( xx ); + y = xy / x; + z = xz / x; - project: function ( camera ) { + } - return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); + } else if ( yy > zz ) { - }, + // m22 is the largest diagonal term - unproject: function ( camera ) { + if ( yy < epsilon ) { - return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); + x = 0.707106781; + y = 0; + z = 0.707106781; - }, + } else { - transformDirection: function ( m ) { + y = Math.sqrt( yy ); + x = xy / y; + z = yz / y; - // input: THREE.Matrix4 affine matrix - // vector interpreted as a direction + } - var x = this.x, y = this.y, z = this.z; - var e = m.elements; + } else { - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; + // m33 is the largest diagonal term so base result on this - return this.normalize(); + if ( zz < epsilon ) { - }, + x = 0.707106781; + y = 0.707106781; + z = 0; - divide: function ( v ) { + } else { - this.x /= v.x; - this.y /= v.y; - this.z /= v.z; + z = Math.sqrt( zz ); + x = xz / z; + y = yz / z; - return this; + } - }, + } - divideScalar: function ( scalar ) { + this.set( x, y, z, angle ); - return this.multiplyScalar( 1 / scalar ); + return this; // return 180 deg rotation + + } + + // as we have reached here there are no singularities so we can handle normally + + var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + + ( m13 - m31 ) * ( m13 - m31 ) + + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize + + if ( Math.abs( s ) < 0.001 ) s = 1; + + // prevent divide by zero, should not happen if matrix is orthogonal and should be + // caught by singularity test above, but I've left it in just in case + + this.x = ( m32 - m23 ) / s; + this.y = ( m13 - m31 ) / s; + this.z = ( m21 - m12 ) / s; + this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + + return this; }, @@ -1962,6 +2252,7 @@ Object.assign( Vector3.prototype, { this.x = Math.min( this.x, v.x ); this.y = Math.min( this.y, v.y ); this.z = Math.min( this.z, v.z ); + this.w = Math.min( this.w, v.w ); return this; @@ -1972,6 +2263,7 @@ Object.assign( Vector3.prototype, { this.x = Math.max( this.x, v.x ); this.y = Math.max( this.y, v.y ); this.z = Math.max( this.z, v.z ); + this.w = Math.max( this.w, v.w ); return this; @@ -1984,6 +2276,7 @@ Object.assign( Vector3.prototype, { this.x = Math.max( min.x, Math.min( max.x, this.x ) ); this.y = Math.max( min.y, Math.min( max.y, this.y ) ); this.z = Math.max( min.z, Math.min( max.z, this.z ) ); + this.w = Math.max( min.w, Math.min( max.w, this.w ) ); return this; @@ -1994,6 +2287,7 @@ Object.assign( Vector3.prototype, { this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); + this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); return this; @@ -2012,6 +2306,7 @@ Object.assign( Vector3.prototype, { this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); this.z = Math.floor( this.z ); + this.w = Math.floor( this.w ); return this; @@ -2022,6 +2317,7 @@ Object.assign( Vector3.prototype, { this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); this.z = Math.ceil( this.z ); + this.w = Math.ceil( this.w ); return this; @@ -2032,6 +2328,7 @@ Object.assign( Vector3.prototype, { this.x = Math.round( this.x ); this.y = Math.round( this.y ); this.z = Math.round( this.z ); + this.w = Math.round( this.w ); return this; @@ -2042,6 +2339,7 @@ Object.assign( Vector3.prototype, { this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); + this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); return this; @@ -2052,6 +2350,7 @@ Object.assign( Vector3.prototype, { this.x = - this.x; this.y = - this.y; this.z = - this.z; + this.w = - this.w; return this; @@ -2059,27 +2358,25 @@ Object.assign( Vector3.prototype, { dot: function ( v ) { - return this.x * v.x + this.y * v.y + this.z * v.z; + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; }, - // TODO lengthSquared? - lengthSq: function () { - return this.x * this.x + this.y * this.y + this.z * this.z; + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; }, length: function () { - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); }, manhattanLength: function () { - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); }, @@ -2100,6 +2397,7 @@ Object.assign( Vector3.prototype, { this.x += ( v.x - this.x ) * alpha; this.y += ( v.y - this.y ) * alpha; this.z += ( v.z - this.z ) * alpha; + this.w += ( v.w - this.w ) * alpha; return this; @@ -2111,1389 +2409,1163 @@ Object.assign( Vector3.prototype, { }, - cross: function ( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); - return this.crossVectors( v, w ); - - } + equals: function ( v ) { - return this.crossVectors( this, v ); + return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); }, - crossVectors: function ( a, b ) { + fromArray: function ( array, offset ) { - var ax = a.x, ay = a.y, az = a.z; - var bx = b.x, by = b.y, bz = b.z; + if ( offset === undefined ) offset = 0; - this.x = ay * bz - az * by; - this.y = az * bx - ax * bz; - this.z = ax * by - ay * bx; + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + this.w = array[ offset + 3 ]; return this; }, - projectOnVector: function ( vector ) { + toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - var scalar = vector.dot( this ) / vector.lengthSq(); + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + array[ offset + 3 ] = this.w; - return this.copy( vector ).multiplyScalar( scalar ); + return array; }, - projectOnPlane: function ( planeNormal ) { + fromBufferAttribute: function ( attribute, index, offset ) { - _vector.copy( this ).projectOnVector( planeNormal ); + if ( offset !== undefined ) { - return this.sub( _vector ); + console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); - }, + } - reflect: function ( normal ) { + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); + this.w = attribute.getW( index ); - // reflect incident vector off plane orthogonal to normal - // normal is assumed to have unit length + return this; - return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); + } - }, +} ); - angleTo: function ( v ) { +/** + * @author szimek / https://github.com/szimek/ + * @author alteredq / http://alteredqualia.com/ + * @author Marius Kintel / https://github.com/kintel + */ - var theta = this.dot( v ) / ( Math.sqrt( this.lengthSq() * v.lengthSq() ) ); +/* + In options, we can specify: + * Texture parameters for an auto-generated target texture + * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers +*/ +function WebGLRenderTarget( width, height, options ) { - // clamp, to handle numerical problems + this.width = width; + this.height = height; - return Math.acos( _Math.clamp( theta, - 1, 1 ) ); - - }, + this.scissor = new Vector4( 0, 0, width, height ); + this.scissorTest = false; - distanceTo: function ( v ) { + this.viewport = new Vector4( 0, 0, width, height ); - return Math.sqrt( this.distanceToSquared( v ) ); + options = options || {}; - }, + this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); - distanceToSquared: function ( v ) { + this.texture.image = {}; + this.texture.image.width = width; + this.texture.image.height = height; - var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; + this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; + this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; - return dx * dx + dy * dy + dz * dz; + this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; + this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; + this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; - }, +} - manhattanDistanceTo: function ( v ) { +WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); + constructor: WebGLRenderTarget, - }, + isWebGLRenderTarget: true, - setFromSpherical: function ( s ) { + setSize: function ( width, height ) { - return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); + if ( this.width !== width || this.height !== height ) { - }, + this.width = width; + this.height = height; - setFromSphericalCoords: function ( radius, phi, theta ) { + this.texture.image.width = width; + this.texture.image.height = height; - var sinPhiRadius = Math.sin( phi ) * radius; + this.dispose(); - this.x = sinPhiRadius * Math.sin( theta ); - this.y = Math.cos( phi ) * radius; - this.z = sinPhiRadius * Math.cos( theta ); + } - return this; + this.viewport.set( 0, 0, width, height ); + this.scissor.set( 0, 0, width, height ); }, - setFromCylindrical: function ( c ) { + clone: function () { - return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); + return new this.constructor().copy( this ); }, - setFromCylindricalCoords: function ( radius, theta, y ) { + copy: function ( source ) { - this.x = radius * Math.sin( theta ); - this.y = y; - this.z = radius * Math.cos( theta ); + this.width = source.width; + this.height = source.height; + + this.viewport.copy( source.viewport ); + + this.texture = source.texture.clone(); + + this.depthBuffer = source.depthBuffer; + this.stencilBuffer = source.stencilBuffer; + this.depthTexture = source.depthTexture; return this; }, - setFromMatrixPosition: function ( m ) { + dispose: function () { - var e = m.elements; + this.dispatchEvent( { type: 'dispose' } ); - this.x = e[ 12 ]; - this.y = e[ 13 ]; - this.z = e[ 14 ]; + } - return this; +} ); - }, +/** + * @author Mugen87 / https://github.com/Mugen87 + * @author Matt DesLauriers / @mattdesl + */ - setFromMatrixScale: function ( m ) { +function WebGLMultisampleRenderTarget( width, height, options ) { - var sx = this.setFromMatrixColumn( m, 0 ).length(); - var sy = this.setFromMatrixColumn( m, 1 ).length(); - var sz = this.setFromMatrixColumn( m, 2 ).length(); + WebGLRenderTarget.call( this, width, height, options ); - this.x = sx; - this.y = sy; - this.z = sz; + this.samples = 4; - return this; +} - }, +WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), { - setFromMatrixColumn: function ( m, index ) { + constructor: WebGLMultisampleRenderTarget, - return this.fromArray( m.elements, index * 4 ); + isWebGLMultisampleRenderTarget: true, - }, + copy: function ( source ) { - equals: function ( v ) { + WebGLRenderTarget.prototype.copy.call( this, source ); - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); + this.samples = source.samples; - }, + return this; - fromArray: function ( array, offset ) { + } - if ( offset === undefined ) offset = 0; +} ); - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; +/** + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author bhouston / http://clara.io + */ - return this; +function Quaternion( x, y, z, w ) { - }, + this._x = x || 0; + this._y = y || 0; + this._z = z || 0; + this._w = ( w !== undefined ) ? w : 1; - toArray: function ( array, offset ) { +} - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; +Object.assign( Quaternion, { - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; + slerp: function ( qa, qb, qm, t ) { - return array; + return qm.copy( qa ).slerp( qb, t ); }, - fromBufferAttribute: function ( attribute, index, offset ) { + slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { - if ( offset !== undefined ) { + // fuzz-free, array-based Quaternion SLERP operation - console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); + var x0 = src0[ srcOffset0 + 0 ], + y0 = src0[ srcOffset0 + 1 ], + z0 = src0[ srcOffset0 + 2 ], + w0 = src0[ srcOffset0 + 3 ], - } + x1 = src1[ srcOffset1 + 0 ], + y1 = src1[ srcOffset1 + 1 ], + z1 = src1[ srcOffset1 + 2 ], + w1 = src1[ srcOffset1 + 3 ]; - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); + if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { - return this; + var s = 1 - t, - } + cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, -} ); + dir = ( cos >= 0 ? 1 : - 1 ), + sqrSin = 1 - cos * cos; -/** - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://clara.io - * @author tschw - */ + // Skip the Slerp for tiny steps to avoid numeric problems: + if ( sqrSin > Number.EPSILON ) { -var _vector$1 = new Vector3(); + var sin = Math.sqrt( sqrSin ), + len = Math.atan2( sin, cos * dir ); -function Matrix3() { + s = Math.sin( s * len ) / sin; + t = Math.sin( t * len ) / sin; - this.elements = [ + } - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 + var tDir = t * dir; - ]; + x0 = x0 * s + x1 * tDir; + y0 = y0 * s + y1 * tDir; + z0 = z0 * s + z1 * tDir; + w0 = w0 * s + w1 * tDir; - if ( arguments.length > 0 ) { + // Normalize in case we just did a lerp: + if ( s === 1 - t ) { - console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); + var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); - } + x0 *= f; + y0 *= f; + z0 *= f; + w0 *= f; -} + } -Object.assign( Matrix3.prototype, { + } - isMatrix3: true, + dst[ dstOffset ] = x0; + dst[ dstOffset + 1 ] = y0; + dst[ dstOffset + 2 ] = z0; + dst[ dstOffset + 3 ] = w0; - set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { + } - var te = this.elements; +} ); - te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; - te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; - te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; +Object.defineProperties( Quaternion.prototype, { - return this; + x: { - }, + get: function () { - identity: function () { + return this._x; - this.set( + }, - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 + set: function ( value ) { - ); + this._x = value; + this._onChangeCallback(); - return this; + } }, - clone: function () { + y: { - return new this.constructor().fromArray( this.elements ); + get: function () { - }, + return this._y; - copy: function ( m ) { + }, - var te = this.elements; - var me = m.elements; + set: function ( value ) { - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; - te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; - te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; + this._y = value; + this._onChangeCallback(); - return this; + } }, - setFromMatrix4: function ( m ) { + z: { - var me = m.elements; + get: function () { - this.set( + return this._z; - me[ 0 ], me[ 4 ], me[ 8 ], - me[ 1 ], me[ 5 ], me[ 9 ], - me[ 2 ], me[ 6 ], me[ 10 ] + }, - ); + set: function ( value ) { - return this; + this._z = value; + this._onChangeCallback(); + + } }, - applyToBufferAttribute: function ( attribute ) { + w: { - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + get: function () { + + return this._w; - _vector$1.x = attribute.getX( i ); - _vector$1.y = attribute.getY( i ); - _vector$1.z = attribute.getZ( i ); + }, - _vector$1.applyMatrix3( this ); + set: function ( value ) { - attribute.setXYZ( i, _vector$1.x, _vector$1.y, _vector$1.z ); + this._w = value; + this._onChangeCallback(); } - return attribute; + } - }, +} ); - multiply: function ( m ) { +Object.assign( Quaternion.prototype, { - return this.multiplyMatrices( this, m ); + isQuaternion: true, - }, + set: function ( x, y, z, w ) { - premultiply: function ( m ) { + this._x = x; + this._y = y; + this._z = z; + this._w = w; - return this.multiplyMatrices( m, this ); + this._onChangeCallback(); - }, + return this; - multiplyMatrices: function ( a, b ) { + }, - var ae = a.elements; - var be = b.elements; - var te = this.elements; + clone: function () { - var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; - var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; - var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; + return new this.constructor( this._x, this._y, this._z, this._w ); - var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; - var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; - var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; + }, - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; - te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; - te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; + copy: function ( quaternion ) { - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; - te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; - te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; + this._x = quaternion.x; + this._y = quaternion.y; + this._z = quaternion.z; + this._w = quaternion.w; - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; - te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; - te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; + this._onChangeCallback(); return this; }, - multiplyScalar: function ( s ) { + setFromEuler: function ( euler, update ) { - var te = this.elements; + if ( ! ( euler && euler.isEuler ) ) { - te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; - te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; - te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; + throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - return this; + } - }, + var x = euler._x, y = euler._y, z = euler._z, order = euler.order; - determinant: function () { + // http://www.mathworks.com/matlabcentral/fileexchange/ + // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ + // content/SpinCalc.m - var te = this.elements; + var cos = Math.cos; + var sin = Math.sin; - var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], - d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], - g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; + var c1 = cos( x / 2 ); + var c2 = cos( y / 2 ); + var c3 = cos( z / 2 ); - return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; + var s1 = sin( x / 2 ); + var s2 = sin( y / 2 ); + var s3 = sin( z / 2 ); - }, + if ( order === 'XYZ' ) { - getInverse: function ( matrix, throwOnDegenerate ) { + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - if ( matrix && matrix.isMatrix4 ) { + } else if ( order === 'YXZ' ) { - console.error( "THREE.Matrix3: .getInverse() no longer takes a Matrix4 argument." ); + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - } + } else if ( order === 'ZXY' ) { - var me = matrix.elements, - te = this.elements, + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], - n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], - n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], + } else if ( order === 'ZYX' ) { - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - det = n11 * t11 + n21 * t12 + n31 * t13; + } else if ( order === 'YZX' ) { - if ( det === 0 ) { + this._x = s1 * c2 * c3 + c1 * s2 * s3; + this._y = c1 * s2 * c3 + s1 * c2 * s3; + this._z = c1 * c2 * s3 - s1 * s2 * c3; + this._w = c1 * c2 * c3 - s1 * s2 * s3; - var msg = "THREE.Matrix3: .getInverse() can't invert matrix, determinant is 0"; + } else if ( order === 'XZY' ) { - if ( throwOnDegenerate === true ) { + this._x = s1 * c2 * c3 - c1 * s2 * s3; + this._y = c1 * s2 * c3 - s1 * c2 * s3; + this._z = c1 * c2 * s3 + s1 * s2 * c3; + this._w = c1 * c2 * c3 + s1 * s2 * s3; - throw new Error( msg ); + } - } else { + if ( update !== false ) this._onChangeCallback(); - console.warn( msg ); + return this; - } + }, - return this.identity(); + setFromAxisAngle: function ( axis, angle ) { - } + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm - var detInv = 1 / det; + // assumes axis is normalized - te[ 0 ] = t11 * detInv; - te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; - te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; + var halfAngle = angle / 2, s = Math.sin( halfAngle ); - te[ 3 ] = t12 * detInv; - te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; - te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; + this._x = axis.x * s; + this._y = axis.y * s; + this._z = axis.z * s; + this._w = Math.cos( halfAngle ); - te[ 6 ] = t13 * detInv; - te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; - te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; + this._onChangeCallback(); return this; }, - transpose: function () { + setFromRotationMatrix: function ( m ) { - var tmp, m = this.elements; + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; - tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; - tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - return this; + var te = m.elements, - }, + m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], + m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], + m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], - getNormalMatrix: function ( matrix4 ) { + trace = m11 + m22 + m33, + s; - return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); + if ( trace > 0 ) { - }, + s = 0.5 / Math.sqrt( trace + 1.0 ); - transposeIntoArray: function ( r ) { + this._w = 0.25 / s; + this._x = ( m32 - m23 ) * s; + this._y = ( m13 - m31 ) * s; + this._z = ( m21 - m12 ) * s; - var m = this.elements; + } else if ( m11 > m22 && m11 > m33 ) { - r[ 0 ] = m[ 0 ]; - r[ 1 ] = m[ 3 ]; - r[ 2 ] = m[ 6 ]; - r[ 3 ] = m[ 1 ]; - r[ 4 ] = m[ 4 ]; - r[ 5 ] = m[ 7 ]; - r[ 6 ] = m[ 2 ]; - r[ 7 ] = m[ 5 ]; - r[ 8 ] = m[ 8 ]; + s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); - return this; + this._w = ( m32 - m23 ) / s; + this._x = 0.25 * s; + this._y = ( m12 + m21 ) / s; + this._z = ( m13 + m31 ) / s; - }, + } else if ( m22 > m33 ) { - setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) { + s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); - var c = Math.cos( rotation ); - var s = Math.sin( rotation ); + this._w = ( m13 - m31 ) / s; + this._x = ( m12 + m21 ) / s; + this._y = 0.25 * s; + this._z = ( m23 + m32 ) / s; - this.set( - sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, - - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, - 0, 0, 1 - ); + } else { - }, + s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); - scale: function ( sx, sy ) { + this._w = ( m21 - m12 ) / s; + this._x = ( m13 + m31 ) / s; + this._y = ( m23 + m32 ) / s; + this._z = 0.25 * s; - var te = this.elements; + } - te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; - te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; + this._onChangeCallback(); return this; }, - rotate: function ( theta ) { + setFromUnitVectors: function ( vFrom, vTo ) { - var c = Math.cos( theta ); - var s = Math.sin( theta ); + // assumes direction vectors vFrom and vTo are normalized - var te = this.elements; + var EPS = 0.000001; - var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; - var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; + var r = vFrom.dot( vTo ) + 1; - te[ 0 ] = c * a11 + s * a21; - te[ 3 ] = c * a12 + s * a22; - te[ 6 ] = c * a13 + s * a23; + if ( r < EPS ) { - te[ 1 ] = - s * a11 + c * a21; - te[ 4 ] = - s * a12 + c * a22; - te[ 7 ] = - s * a13 + c * a23; + r = 0; - return this; + if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { - }, + this._x = - vFrom.y; + this._y = vFrom.x; + this._z = 0; + this._w = r; - translate: function ( tx, ty ) { + } else { - var te = this.elements; + this._x = 0; + this._y = - vFrom.z; + this._z = vFrom.y; + this._w = r; - te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; - te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; + } - return this; + } else { - }, + // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 - equals: function ( matrix ) { + this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; + this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; + this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; + this._w = r; - var te = this.elements; - var me = matrix.elements; + } - for ( var i = 0; i < 9; i ++ ) { + return this.normalize(); - if ( te[ i ] !== me[ i ] ) return false; + }, - } + angleTo: function ( q ) { - return true; + return 2 * Math.acos( Math.abs( MathUtils.clamp( this.dot( q ), - 1, 1 ) ) ); }, - fromArray: function ( array, offset ) { + rotateTowards: function ( q, step ) { - if ( offset === undefined ) offset = 0; + var angle = this.angleTo( q ); - for ( var i = 0; i < 9; i ++ ) { + if ( angle === 0 ) return this; - this.elements[ i ] = array[ i + offset ]; + var t = Math.min( 1, step / angle ); - } + this.slerp( q, t ); return this; }, - toArray: function ( array, offset ) { + inverse: function () { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + // quaternion is assumed to have unit length - var te = this.elements; + return this.conjugate(); - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; + }, - array[ offset + 3 ] = te[ 3 ]; - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; + conjugate: function () { - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; - array[ offset + 8 ] = te[ 8 ]; + this._x *= - 1; + this._y *= - 1; + this._z *= - 1; - return array; + this._onChangeCallback(); - } + return this; -} ); + }, -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ + dot: function ( v ) { -var _canvas; + return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; -var ImageUtils = { + }, - getDataURL: function ( image ) { + lengthSq: function () { - var canvas; + return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; - if ( typeof HTMLCanvasElement == 'undefined' ) { + }, - return image.src; + length: function () { - } else if ( image instanceof HTMLCanvasElement ) { + return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); - canvas = image; + }, + + normalize: function () { + + var l = this.length(); + + if ( l === 0 ) { + + this._x = 0; + this._y = 0; + this._z = 0; + this._w = 1; } else { - if ( _canvas === undefined ) _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); + l = 1 / l; - _canvas.width = image.width; - _canvas.height = image.height; + this._x = this._x * l; + this._y = this._y * l; + this._z = this._z * l; + this._w = this._w * l; - var context = _canvas.getContext( '2d' ); + } - if ( image instanceof ImageData ) { + this._onChangeCallback(); - context.putImageData( image, 0, 0 ); + return this; - } else { + }, - context.drawImage( image, 0, 0, image.width, image.height ); + multiply: function ( q, p ) { - } + if ( p !== undefined ) { - canvas = _canvas; + console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); + return this.multiplyQuaternions( q, p ); } - if ( canvas.width > 2048 || canvas.height > 2048 ) { - - return canvas.toDataURL( 'image/jpeg', 0.6 ); + return this.multiplyQuaternions( this, q ); - } else { + }, - return canvas.toDataURL( 'image/png' ); + premultiply: function ( q ) { - } + return this.multiplyQuaternions( q, this ); - } + }, -}; + multiplyQuaternions: function ( a, b ) { -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author szimek / https://github.com/szimek/ - */ + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm -var textureId = 0; + var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; + var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; -function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - Object.defineProperty( this, 'id', { value: textureId ++ } ); + this._onChangeCallback(); - this.uuid = _Math.generateUUID(); + return this; - this.name = ''; + }, - this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE; - this.mipmaps = []; + slerp: function ( qb, t ) { - this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING; + if ( t === 0 ) return this; + if ( t === 1 ) return this.copy( qb ); - this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping; - this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping; + var x = this._x, y = this._y, z = this._z, w = this._w; - this.magFilter = magFilter !== undefined ? magFilter : LinearFilter; - this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter; + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ - this.anisotropy = anisotropy !== undefined ? anisotropy : 1; + var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; - this.format = format !== undefined ? format : RGBAFormat; - this.type = type !== undefined ? type : UnsignedByteType; + if ( cosHalfTheta < 0 ) { - this.offset = new Vector2( 0, 0 ); - this.repeat = new Vector2( 1, 1 ); - this.center = new Vector2( 0, 0 ); - this.rotation = 0; + this._w = - qb._w; + this._x = - qb._x; + this._y = - qb._y; + this._z = - qb._z; - this.matrixAutoUpdate = true; - this.matrix = new Matrix3(); + cosHalfTheta = - cosHalfTheta; - this.generateMipmaps = true; - this.premultiplyAlpha = false; - this.flipY = true; - this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + } else { - // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. - // - // Also changing the encoding after already used by a Material will not automatically make the Material - // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. - this.encoding = encoding !== undefined ? encoding : LinearEncoding; + this.copy( qb ); - this.version = 0; - this.onUpdate = null; + } -} + if ( cosHalfTheta >= 1.0 ) { -Texture.DEFAULT_IMAGE = undefined; -Texture.DEFAULT_MAPPING = UVMapping; + this._w = w; + this._x = x; + this._y = y; + this._z = z; -Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + return this; - constructor: Texture, + } - isTexture: true, + var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - updateMatrix: function () { + if ( sqrSinHalfTheta <= Number.EPSILON ) { - this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); + var s = 1 - t; + this._w = s * w + t * this._w; + this._x = s * x + t * this._x; + this._y = s * y + t * this._y; + this._z = s * z + t * this._z; - }, + this.normalize(); + this._onChangeCallback(); - clone: function () { + return this; - return new this.constructor().copy( this ); + } - }, + var sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); + var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); + var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, + ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; - copy: function ( source ) { + this._w = ( w * ratioA + this._w * ratioB ); + this._x = ( x * ratioA + this._x * ratioB ); + this._y = ( y * ratioA + this._y * ratioB ); + this._z = ( z * ratioA + this._z * ratioB ); - this.name = source.name; + this._onChangeCallback(); - this.image = source.image; - this.mipmaps = source.mipmaps.slice( 0 ); + return this; - this.mapping = source.mapping; + }, - this.wrapS = source.wrapS; - this.wrapT = source.wrapT; + equals: function ( quaternion ) { - this.magFilter = source.magFilter; - this.minFilter = source.minFilter; + return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); - this.anisotropy = source.anisotropy; + }, - this.format = source.format; - this.type = source.type; + fromArray: function ( array, offset ) { - this.offset.copy( source.offset ); - this.repeat.copy( source.repeat ); - this.center.copy( source.center ); - this.rotation = source.rotation; + if ( offset === undefined ) offset = 0; - this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrix.copy( source.matrix ); + this._x = array[ offset ]; + this._y = array[ offset + 1 ]; + this._z = array[ offset + 2 ]; + this._w = array[ offset + 3 ]; - this.generateMipmaps = source.generateMipmaps; - this.premultiplyAlpha = source.premultiplyAlpha; - this.flipY = source.flipY; - this.unpackAlignment = source.unpackAlignment; - this.encoding = source.encoding; + this._onChangeCallback(); return this; }, - toJSON: function ( meta ) { + toArray: function ( array, offset ) { - var isRootObject = ( meta === undefined || typeof meta === 'string' ); + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._w; - return meta.textures[ this.uuid ]; + return array; - } + }, - var output = { + _onChange: function ( callback ) { - metadata: { - version: 4.5, - type: 'Texture', - generator: 'Texture.toJSON' - }, + this._onChangeCallback = callback; - uuid: this.uuid, - name: this.name, + return this; - mapping: this.mapping, + }, - repeat: [ this.repeat.x, this.repeat.y ], - offset: [ this.offset.x, this.offset.y ], - center: [ this.center.x, this.center.y ], - rotation: this.rotation, + _onChangeCallback: function () {} - wrap: [ this.wrapS, this.wrapT ], +} ); - format: this.format, - type: this.type, - encoding: this.encoding, +/** + * @author mrdoob / http://mrdoob.com/ + * @author kile / http://kile.stravaganza.org/ + * @author philogb / http://blog.thejit.org/ + * @author mikael emtinger / http://gomo.se/ + * @author egraether / http://egraether.com/ + * @author WestLangley / http://github.com/WestLangley + */ - minFilter: this.minFilter, - magFilter: this.magFilter, - anisotropy: this.anisotropy, +var _vector = new Vector3(); +var _quaternion = new Quaternion(); - flipY: this.flipY, +function Vector3( x, y, z ) { - premultiplyAlpha: this.premultiplyAlpha, - unpackAlignment: this.unpackAlignment + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; - }; +} - if ( this.image !== undefined ) { +Object.assign( Vector3.prototype, { - // TODO: Move to THREE.Image + isVector3: true, - var image = this.image; + set: function ( x, y, z ) { - if ( image.uuid === undefined ) { + this.x = x; + this.y = y; + this.z = z; - image.uuid = _Math.generateUUID(); // UGH + return this; - } + }, - if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) { + setScalar: function ( scalar ) { - var url; + this.x = scalar; + this.y = scalar; + this.z = scalar; - if ( Array.isArray( image ) ) { + return this; - // process array of images e.g. CubeTexture + }, - url = []; + setX: function ( x ) { - for ( var i = 0, l = image.length; i < l; i ++ ) { + this.x = x; - url.push( ImageUtils.getDataURL( image[ i ] ) ); + return this; - } + }, - } else { + setY: function ( y ) { - // process single image + this.y = y; - url = ImageUtils.getDataURL( image ); + return this; - } + }, - meta.images[ image.uuid ] = { - uuid: image.uuid, - url: url - }; + setZ: function ( z ) { - } + this.z = z; - output.image = image.uuid; + return this; - } + }, - if ( ! isRootObject ) { + setComponent: function ( index, value ) { - meta.textures[ this.uuid ] = output; + switch ( index ) { + + case 0: this.x = value; break; + case 1: this.y = value; break; + case 2: this.z = value; break; + default: throw new Error( 'index is out of range: ' + index ); } - return output; + return this; }, - dispose: function () { + getComponent: function ( index ) { - this.dispatchEvent( { type: 'dispose' } ); + switch ( index ) { - }, + case 0: return this.x; + case 1: return this.y; + case 2: return this.z; + default: throw new Error( 'index is out of range: ' + index ); - transformUv: function ( uv ) { + } - if ( this.mapping !== UVMapping ) return uv; + }, - uv.applyMatrix3( this.matrix ); + clone: function () { - if ( uv.x < 0 || uv.x > 1 ) { + return new this.constructor( this.x, this.y, this.z ); - switch ( this.wrapS ) { + }, - case RepeatWrapping: + copy: function ( v ) { - uv.x = uv.x - Math.floor( uv.x ); - break; + this.x = v.x; + this.y = v.y; + this.z = v.z; - case ClampToEdgeWrapping: + return this; - uv.x = uv.x < 0 ? 0 : 1; - break; + }, - case MirroredRepeatWrapping: + add: function ( v, w ) { - if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { + if ( w !== undefined ) { - uv.x = Math.ceil( uv.x ) - uv.x; + console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); + return this.addVectors( v, w ); - } else { + } - uv.x = uv.x - Math.floor( uv.x ); + this.x += v.x; + this.y += v.y; + this.z += v.z; - } - break; + return this; - } + }, - } + addScalar: function ( s ) { - if ( uv.y < 0 || uv.y > 1 ) { + this.x += s; + this.y += s; + this.z += s; - switch ( this.wrapT ) { + return this; - case RepeatWrapping: + }, - uv.y = uv.y - Math.floor( uv.y ); - break; + addVectors: function ( a, b ) { - case ClampToEdgeWrapping: + this.x = a.x + b.x; + this.y = a.y + b.y; + this.z = a.z + b.z; - uv.y = uv.y < 0 ? 0 : 1; - break; + return this; - case MirroredRepeatWrapping: + }, - if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { + addScaledVector: function ( v, s ) { - uv.y = Math.ceil( uv.y ) - uv.y; + this.x += v.x * s; + this.y += v.y * s; + this.z += v.z * s; - } else { + return this; - uv.y = uv.y - Math.floor( uv.y ); + }, - } - break; + sub: function ( v, w ) { - } + if ( w !== undefined ) { + + console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); + return this.subVectors( v, w ); } - if ( this.flipY ) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; - uv.y = 1 - uv.y; + return this; - } + }, - return uv; + subScalar: function ( s ) { - } + this.x -= s; + this.y -= s; + this.z -= s; -} ); + return this; -Object.defineProperty( Texture.prototype, "needsUpdate", { + }, - set: function ( value ) { - - if ( value === true ) this.version ++; - - } - -} ); - -/** - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author philogb / http://blog.thejit.org/ - * @author mikael emtinger / http://gomo.se/ - * @author egraether / http://egraether.com/ - * @author WestLangley / http://github.com/WestLangley - */ - -function Vector4( x, y, z, w ) { - - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = ( w !== undefined ) ? w : 1; - -} - -Object.defineProperties( Vector4.prototype, { - - "width": { - - get: function () { - - return this.z; - - }, - - set: function ( value ) { - - this.z = value; - - } - - }, - - "height": { - - get: function () { - - return this.w; - - }, - - set: function ( value ) { - - this.w = value; - - } - - } - -} ); - -Object.assign( Vector4.prototype, { - - isVector4: true, - - set: function ( x, y, z, w ) { - - this.x = x; - this.y = y; - this.z = z; - this.w = w; - - return this; - - }, - - setScalar: function ( scalar ) { + subVectors: function ( a, b ) { - this.x = scalar; - this.y = scalar; - this.z = scalar; - this.w = scalar; + this.x = a.x - b.x; + this.y = a.y - b.y; + this.z = a.z - b.z; return this; }, - setX: function ( x ) { - - this.x = x; + multiply: function ( v, w ) { - return this; + if ( w !== undefined ) { - }, + console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); + return this.multiplyVectors( v, w ); - setY: function ( y ) { + } - this.y = y; + this.x *= v.x; + this.y *= v.y; + this.z *= v.z; return this; }, - setZ: function ( z ) { + multiplyScalar: function ( scalar ) { - this.z = z; + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; return this; }, - setW: function ( w ) { + multiplyVectors: function ( a, b ) { - this.w = w; + this.x = a.x * b.x; + this.y = a.y * b.y; + this.z = a.z * b.z; return this; }, - setComponent: function ( index, value ) { + applyEuler: function ( euler ) { - switch ( index ) { + if ( ! ( euler && euler.isEuler ) ) { - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - case 3: this.w = value; break; - default: throw new Error( 'index is out of range: ' + index ); + console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); } - return this; + return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); }, - getComponent: function ( index ) { - - switch ( index ) { - - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - case 3: return this.w; - default: throw new Error( 'index is out of range: ' + index ); + applyAxisAngle: function ( axis, angle ) { - } + return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); }, - clone: function () { - - return new this.constructor( this.x, this.y, this.z, this.w ); - - }, + applyMatrix3: function ( m ) { - copy: function ( v ) { + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - this.x = v.x; - this.y = v.y; - this.z = v.z; - this.w = ( v.w !== undefined ) ? v.w : 1; + this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; + this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; + this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; return this; }, - add: function ( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); - - } - - this.x += v.x; - this.y += v.y; - this.z += v.z; - this.w += v.w; + applyNormalMatrix: function ( m ) { - return this; + return this.applyMatrix3( m ).normalize(); }, - addScalar: function ( s ) { - - this.x += s; - this.y += s; - this.z += s; - this.w += s; - - return this; + applyMatrix4: function ( m ) { - }, + var x = this.x, y = this.y, z = this.z; + var e = m.elements; - addVectors: function ( a, b ) { + var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - this.w = a.w + b.w; + this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; + this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; + this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; return this; }, - addScaledVector: function ( v, s ) { - - this.x += v.x * s; - this.y += v.y * s; - this.z += v.z * s; - this.w += v.w * s; - - return this; - - }, + applyQuaternion: function ( q ) { - sub: function ( v, w ) { + var x = this.x, y = this.y, z = this.z; + var qx = q.x, qy = q.y, qz = q.z, qw = q.w; - if ( w !== undefined ) { + // calculate quat * vector - console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = - qx * x - qy * y - qz * z; - } + // calculate result * inverse quat - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - this.w -= v.w; + this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; + this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; + this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; return this; }, - subScalar: function ( s ) { - - this.x -= s; - this.y -= s; - this.z -= s; - this.w -= s; + project: function ( camera ) { - return this; + return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); }, - subVectors: function ( a, b ) { - - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; - this.w = a.w - b.w; + unproject: function ( camera ) { - return this; + return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); }, - multiplyScalar: function ( scalar ) { - - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; - this.w *= scalar; - - return this; - - }, + transformDirection: function ( m ) { - applyMatrix4: function ( m ) { + // input: THREE.Matrix4 affine matrix + // vector interpreted as a direction - var x = this.x, y = this.y, z = this.z, w = this.w; + var x = this.x, y = this.y, z = this.z; var e = m.elements; - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; - this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; - - return this; - - }, - - divideScalar: function ( scalar ) { + this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; + this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; + this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; - return this.multiplyScalar( 1 / scalar ); + return this.normalize(); }, - setAxisAngleFromQuaternion: function ( q ) { - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm - - // q is assumed to be normalized - - this.w = 2 * Math.acos( q.w ); - - var s = Math.sqrt( 1 - q.w * q.w ); - - if ( s < 0.0001 ) { - - this.x = 1; - this.y = 0; - this.z = 0; - - } else { - - this.x = q.x / s; - this.y = q.y / s; - this.z = q.z / s; + divide: function ( v ) { - } + this.x /= v.x; + this.y /= v.y; + this.z /= v.z; return this; }, - setAxisAngleFromRotationMatrix: function ( m ) { - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - - var angle, x, y, z, // variables for result - epsilon = 0.01, // margin to allow for rounding errors - epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees - - te = m.elements, - - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - - if ( ( Math.abs( m12 - m21 ) < epsilon ) && - ( Math.abs( m13 - m31 ) < epsilon ) && - ( Math.abs( m23 - m32 ) < epsilon ) ) { - - // singularity found - // first check for identity matrix which must have +1 for all terms - // in leading diagonal and zero in other terms - - if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && - ( Math.abs( m13 + m31 ) < epsilon2 ) && - ( Math.abs( m23 + m32 ) < epsilon2 ) && - ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { - - // this singularity is identity matrix so angle = 0 - - this.set( 1, 0, 0, 0 ); - - return this; // zero angle, arbitrary axis - - } - - // otherwise this singularity is angle = 180 - - angle = Math.PI; - - var xx = ( m11 + 1 ) / 2; - var yy = ( m22 + 1 ) / 2; - var zz = ( m33 + 1 ) / 2; - var xy = ( m12 + m21 ) / 4; - var xz = ( m13 + m31 ) / 4; - var yz = ( m23 + m32 ) / 4; - - if ( ( xx > yy ) && ( xx > zz ) ) { - - // m11 is the largest diagonal term - - if ( xx < epsilon ) { - - x = 0; - y = 0.707106781; - z = 0.707106781; - - } else { - - x = Math.sqrt( xx ); - y = xy / x; - z = xz / x; - - } - - } else if ( yy > zz ) { - - // m22 is the largest diagonal term - - if ( yy < epsilon ) { - - x = 0.707106781; - y = 0; - z = 0.707106781; - - } else { - - y = Math.sqrt( yy ); - x = xy / y; - z = yz / y; - - } - - } else { - - // m33 is the largest diagonal term so base result on this - - if ( zz < epsilon ) { - - x = 0.707106781; - y = 0.707106781; - z = 0; - - } else { - - z = Math.sqrt( zz ); - x = xz / z; - y = yz / z; - - } - - } - - this.set( x, y, z, angle ); - - return this; // return 180 deg rotation - - } - - // as we have reached here there are no singularities so we can handle normally - - var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + - ( m13 - m31 ) * ( m13 - m31 ) + - ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize - - if ( Math.abs( s ) < 0.001 ) s = 1; - - // prevent divide by zero, should not happen if matrix is orthogonal and should be - // caught by singularity test above, but I've left it in just in case - - this.x = ( m32 - m23 ) / s; - this.y = ( m13 - m31 ) / s; - this.z = ( m21 - m12 ) / s; - this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); + divideScalar: function ( scalar ) { - return this; + return this.multiplyScalar( 1 / scalar ); }, @@ -3502,7 +3574,6 @@ Object.assign( Vector4.prototype, { this.x = Math.min( this.x, v.x ); this.y = Math.min( this.y, v.y ); this.z = Math.min( this.z, v.z ); - this.w = Math.min( this.w, v.w ); return this; @@ -3513,7 +3584,6 @@ Object.assign( Vector4.prototype, { this.x = Math.max( this.x, v.x ); this.y = Math.max( this.y, v.y ); this.z = Math.max( this.z, v.z ); - this.w = Math.max( this.w, v.w ); return this; @@ -3526,7 +3596,6 @@ Object.assign( Vector4.prototype, { this.x = Math.max( min.x, Math.min( max.x, this.x ) ); this.y = Math.max( min.y, Math.min( max.y, this.y ) ); this.z = Math.max( min.z, Math.min( max.z, this.z ) ); - this.w = Math.max( min.w, Math.min( max.w, this.w ) ); return this; @@ -3537,7 +3606,6 @@ Object.assign( Vector4.prototype, { this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); - this.w = Math.max( minVal, Math.min( maxVal, this.w ) ); return this; @@ -3556,7 +3624,6 @@ Object.assign( Vector4.prototype, { this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); this.z = Math.floor( this.z ); - this.w = Math.floor( this.w ); return this; @@ -3567,7 +3634,6 @@ Object.assign( Vector4.prototype, { this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); this.z = Math.ceil( this.z ); - this.w = Math.ceil( this.w ); return this; @@ -3578,7 +3644,6 @@ Object.assign( Vector4.prototype, { this.x = Math.round( this.x ); this.y = Math.round( this.y ); this.z = Math.round( this.z ); - this.w = Math.round( this.w ); return this; @@ -3589,7 +3654,6 @@ Object.assign( Vector4.prototype, { this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w ); return this; @@ -3600,7 +3664,6 @@ Object.assign( Vector4.prototype, { this.x = - this.x; this.y = - this.y; this.z = - this.z; - this.w = - this.w; return this; @@ -3608,25 +3671,27 @@ Object.assign( Vector4.prototype, { dot: function ( v ) { - return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + return this.x * v.x + this.y * v.y + this.z * v.z; }, + // TODO lengthSquared? + lengthSq: function () { - return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + return this.x * this.x + this.y * this.y + this.z * this.z; }, length: function () { - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); + return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); }, manhattanLength: function () { - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); + return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); }, @@ -3647,7 +3712,6 @@ Object.assign( Vector4.prototype, { this.x += ( v.x - this.x ) * alpha; this.y += ( v.y - this.y ) * alpha; this.z += ( v.z - this.z ) * alpha; - this.w += ( v.w - this.w ) * alpha; return this; @@ -3659,176 +3723,209 @@ Object.assign( Vector4.prototype, { }, - equals: function ( v ) { + cross: function ( v, w ) { - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); + if ( w !== undefined ) { + + console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); + return this.crossVectors( v, w ); + + } + + return this.crossVectors( this, v ); }, - fromArray: function ( array, offset ) { + crossVectors: function ( a, b ) { - if ( offset === undefined ) offset = 0; + var ax = a.x, ay = a.y, az = a.z; + var bx = b.x, by = b.y, bz = b.z; - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; - this.w = array[ offset + 3 ]; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; return this; }, - toArray: function ( array, offset ) { + projectOnVector: function ( v ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + var denominator = v.lengthSq(); - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; - array[ offset + 3 ] = this.w; + if ( denominator === 0 ) return this.set( 0, 0, 0 ); - return array; + var scalar = v.dot( this ) / denominator; + + return this.copy( v ).multiplyScalar( scalar ); }, - fromBufferAttribute: function ( attribute, index, offset ) { + projectOnPlane: function ( planeNormal ) { - if ( offset !== undefined ) { + _vector.copy( this ).projectOnVector( planeNormal ); - console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' ); + return this.sub( _vector ); - } + }, - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); - this.w = attribute.getW( index ); + reflect: function ( normal ) { - return this; + // reflect incident vector off plane orthogonal to normal + // normal is assumed to have unit length - } + return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); -} ); + }, -/** - * @author szimek / https://github.com/szimek/ - * @author alteredq / http://alteredqualia.com/ - * @author Marius Kintel / https://github.com/kintel - */ + angleTo: function ( v ) { -/* - In options, we can specify: - * Texture parameters for an auto-generated target texture - * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers -*/ -function WebGLRenderTarget( width, height, options ) { + var denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); - this.width = width; - this.height = height; + if ( denominator === 0 ) return Math.PI / 2; - this.scissor = new Vector4( 0, 0, width, height ); - this.scissorTest = false; + var theta = this.dot( v ) / denominator; - this.viewport = new Vector4( 0, 0, width, height ); + // clamp, to handle numerical problems - options = options || {}; + return Math.acos( MathUtils.clamp( theta, - 1, 1 ) ); - this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); + }, - this.texture.image = {}; - this.texture.image.width = width; - this.texture.image.height = height; + distanceTo: function ( v ) { - this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; - this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; + return Math.sqrt( this.distanceToSquared( v ) ); - this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; - this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; - this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null; + }, -} + distanceToSquared: function ( v ) { -WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; - constructor: WebGLRenderTarget, + return dx * dx + dy * dy + dz * dz; - isWebGLRenderTarget: true, + }, - setSize: function ( width, height ) { + manhattanDistanceTo: function ( v ) { - if ( this.width !== width || this.height !== height ) { + return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); - this.width = width; - this.height = height; + }, - this.texture.image.width = width; - this.texture.image.height = height; + setFromSpherical: function ( s ) { - this.dispose(); + return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); - } + }, - this.viewport.set( 0, 0, width, height ); - this.scissor.set( 0, 0, width, height ); + setFromSphericalCoords: function ( radius, phi, theta ) { + + var sinPhiRadius = Math.sin( phi ) * radius; + + this.x = sinPhiRadius * Math.sin( theta ); + this.y = Math.cos( phi ) * radius; + this.z = sinPhiRadius * Math.cos( theta ); + + return this; }, - clone: function () { + setFromCylindrical: function ( c ) { - return new this.constructor().copy( this ); + return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); }, - copy: function ( source ) { + setFromCylindricalCoords: function ( radius, theta, y ) { - this.width = source.width; - this.height = source.height; + this.x = radius * Math.sin( theta ); + this.y = y; + this.z = radius * Math.cos( theta ); - this.viewport.copy( source.viewport ); + return this; - this.texture = source.texture.clone(); + }, - this.depthBuffer = source.depthBuffer; - this.stencilBuffer = source.stencilBuffer; - this.depthTexture = source.depthTexture; + setFromMatrixPosition: function ( m ) { + + var e = m.elements; + + this.x = e[ 12 ]; + this.y = e[ 13 ]; + this.z = e[ 14 ]; return this; }, - dispose: function () { + setFromMatrixScale: function ( m ) { - this.dispatchEvent( { type: 'dispose' } ); + var sx = this.setFromMatrixColumn( m, 0 ).length(); + var sy = this.setFromMatrixColumn( m, 1 ).length(); + var sz = this.setFromMatrixColumn( m, 2 ).length(); - } + this.x = sx; + this.y = sy; + this.z = sz; -} ); + return this; -/** - * @author Mugen87 / https://github.com/Mugen87 - * @author Matt DesLauriers / @mattdesl - */ + }, -function WebGLMultisampleRenderTarget( width, height, options ) { + setFromMatrixColumn: function ( m, index ) { - WebGLRenderTarget.call( this, width, height, options ); + return this.fromArray( m.elements, index * 4 ); - this.samples = 4; + }, -} + setFromMatrix3Column: function ( m, index ) { -WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), { + return this.fromArray( m.elements, index * 3 ); - constructor: WebGLMultisampleRenderTarget, + }, - isWebGLMultisampleRenderTarget: true, + equals: function ( v ) { - copy: function ( source ) { + return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); - WebGLRenderTarget.prototype.copy.call( this, source ); + }, - this.samples = source.samples; + fromArray: function ( array, offset ) { + + if ( offset === undefined ) offset = 0; + + this.x = array[ offset ]; + this.y = array[ offset + 1 ]; + this.z = array[ offset + 2 ]; + + return this; + + }, + + toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; + + array[ offset ] = this.x; + array[ offset + 1 ] = this.y; + array[ offset + 2 ] = this.z; + + return array; + + }, + + fromBufferAttribute: function ( attribute, index, offset ) { + + if ( offset !== undefined ) { + + console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); + + } + + this.x = attribute.getX( index ); + this.y = attribute.getY( index ); + this.z = attribute.getZ( index ); return this; @@ -4251,24 +4348,6 @@ Object.assign( Matrix4.prototype, { }, - applyToBufferAttribute: function ( attribute ) { - - for ( var i = 0, l = attribute.count; i < l; i ++ ) { - - _v1.x = attribute.getX( i ); - _v1.y = attribute.getY( i ); - _v1.z = attribute.getZ( i ); - - _v1.applyMatrix4( this ); - - attribute.setXYZ( i, _v1.x, _v1.y, _v1.z ); - - } - - return attribute; - - }, - determinant: function () { var te = this.elements; @@ -4886,7 +4965,7 @@ Object.assign( Euler.prototype, { setFromRotationMatrix: function ( m, order, update ) { - var clamp = _Math.clamp; + var clamp = MathUtils.clamp; // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) @@ -5114,6 +5193,12 @@ Object.assign( Layers.prototype, { }, + enableAll: function () { + + this.mask = 0xffffffff | 0; + + }, + toggle: function ( channel ) { this.mask ^= 1 << channel | 0; @@ -5126,6 +5211,12 @@ Object.assign( Layers.prototype, { }, + disableAll: function () { + + this.mask = 0; + + }, + test: function ( layers ) { return ( this.mask & layers.mask ) !== 0; @@ -5164,7 +5255,7 @@ function Object3D() { Object.defineProperty( this, 'id', { value: _object3DId ++ } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'Object3D'; @@ -5254,7 +5345,7 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), onBeforeRender: function () {}, onAfterRender: function () {}, - applyMatrix: function ( matrix ) { + applyMatrix4: function ( matrix ) { if ( this.matrixAutoUpdate ) this.updateMatrix(); @@ -5521,7 +5612,7 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), } - object.applyMatrix( _m1$1 ); + object.applyMatrix4( _m1$1 ); object.updateWorldMatrix( false, false ); @@ -5807,7 +5898,13 @@ Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), // object specific properties - if ( this.isMesh && this.drawMode !== TrianglesDrawMode ) object.drawMode = this.drawMode; + if ( this.isInstancedMesh ) { + + object.type = 'InstancedMesh'; + object.count = this.count; + object.instanceMatrix = this.instanceMatrix.toJSON(); + + } // @@ -5991,7 +6088,9 @@ function Scene() { this.type = 'Scene'; this.background = null; + this.environment = null; this.fog = null; + this.overrideMaterial = null; this.autoUpdate = true; // checked by the renderer @@ -6015,7 +6114,9 @@ Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { Object3D.prototype.copy.call( this, source, recursive ); if ( source.background !== null ) this.background = source.background.clone(); + if ( source.environment !== null ) this.environment = source.environment.clone(); if ( source.fog !== null ) this.fog = source.fog.clone(); + if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); this.autoUpdate = source.autoUpdate; @@ -6030,6 +6131,7 @@ Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { var data = Object3D.prototype.toJSON.call( this, meta ); if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); + if ( this.environment !== null ) data.object.environment = this.environment.toJSON( meta ); if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); return data; @@ -6054,7 +6156,10 @@ var _points = [ new Vector3(), new Vector3() ]; -var _vector$2 = new Vector3(); + +var _vector$1 = new Vector3(); + +var _box = new Box3(); // triangle centered vertices @@ -6085,6 +6190,7 @@ function Box3( min, max ) { } + Object.assign( Box3.prototype, { isBox3: true, @@ -6180,7 +6286,7 @@ Object.assign( Box3.prototype, { setFromCenterAndSize: function ( center, size ) { - var halfSize = _vector$2.copy( size ).multiplyScalar( 0.5 ); + var halfSize = _vector$1.copy( size ).multiplyScalar( 0.5 ); this.min.copy( center ).sub( halfSize ); this.max.copy( center ).add( halfSize ); @@ -6284,8 +6390,6 @@ Object.assign( Box3.prototype, { expandByObject: function ( object ) { - var i, l; - // Computes the world-axis-aligned bounding box of an object (including its children), // accounting for both the object's, and children's, world transforms @@ -6295,44 +6399,22 @@ Object.assign( Box3.prototype, { if ( geometry !== undefined ) { - if ( geometry.isGeometry ) { - - var vertices = geometry.vertices; - - for ( i = 0, l = vertices.length; i < l; i ++ ) { - - _vector$2.copy( vertices[ i ] ); - _vector$2.applyMatrix4( object.matrixWorld ); - - this.expandByPoint( _vector$2 ); - - } - - } else if ( geometry.isBufferGeometry ) { - - var attribute = geometry.attributes.position; - - if ( attribute !== undefined ) { - - for ( i = 0, l = attribute.count; i < l; i ++ ) { - - _vector$2.fromBufferAttribute( attribute, i ).applyMatrix4( object.matrixWorld ); + if ( geometry.boundingBox === null ) { - this.expandByPoint( _vector$2 ); + geometry.computeBoundingBox(); - } + } - } + _box.copy( geometry.boundingBox ); + _box.applyMatrix4( object.matrixWorld ); - } + this.union( _box ); } - // - var children = object.children; - for ( i = 0, l = children.length; i < l; i ++ ) { + for ( var i = 0, l = children.length; i < l; i ++ ) { this.expandByObject( children[ i ] ); @@ -6390,10 +6472,10 @@ Object.assign( Box3.prototype, { intersectsSphere: function ( sphere ) { // Find the point on the AABB closest to the sphere center. - this.clampPoint( sphere.center, _vector$2 ); + this.clampPoint( sphere.center, _vector$1 ); // If that point is inside the sphere, the AABB and sphere intersect. - return _vector$2.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); + return _vector$1.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); }, @@ -6512,7 +6594,7 @@ Object.assign( Box3.prototype, { distanceToPoint: function ( point ) { - var clampedPoint = _vector$2.copy( point ).clamp( this.min, this.max ); + var clampedPoint = _vector$1.copy( point ).clamp( this.min, this.max ); return clampedPoint.sub( point ).length(); @@ -6529,7 +6611,7 @@ Object.assign( Box3.prototype, { this.getCenter( target.center ); - target.radius = this.getSize( _vector$2 ).length() * 0.5; + target.radius = this.getSize( _vector$1 ).length() * 0.5; return target; @@ -6622,7 +6704,7 @@ function satForAxes( axes, v0, v1, v2, extents ) { } -var _box = new Box3(); +var _box$1 = new Box3(); /** * @author bhouston / http://clara.io @@ -6657,7 +6739,7 @@ Object.assign( Sphere.prototype, { } else { - _box.setFromPoints( points ).getCenter( center ); + _box$1.setFromPoints( points ).getCenter( center ); } @@ -6793,7 +6875,7 @@ Object.assign( Sphere.prototype, { } ); -var _vector$3 = new Vector3(); +var _vector$2 = new Vector3(); var _segCenter = new Vector3(); var _segDir = new Vector3(); var _diff = new Vector3(); @@ -6809,7 +6891,7 @@ var _normal = new Vector3(); function Ray( origin, direction ) { this.origin = ( origin !== undefined ) ? origin : new Vector3(); - this.direction = ( direction !== undefined ) ? direction : new Vector3(); + this.direction = ( direction !== undefined ) ? direction : new Vector3( 0, 0, - 1 ); } @@ -6862,7 +6944,7 @@ Object.assign( Ray.prototype, { recast: function ( t ) { - this.origin.copy( this.at( t, _vector$3 ) ); + this.origin.copy( this.at( t, _vector$2 ) ); return this; @@ -6899,7 +6981,7 @@ Object.assign( Ray.prototype, { distanceSqToPoint: function ( point ) { - var directionDistance = _vector$3.subVectors( point, this.origin ).dot( this.direction ); + var directionDistance = _vector$2.subVectors( point, this.origin ).dot( this.direction ); // point behind the ray @@ -6909,9 +6991,9 @@ Object.assign( Ray.prototype, { } - _vector$3.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + _vector$2.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - return _vector$3.distanceToSquared( point ); + return _vector$2.distanceToSquared( point ); }, @@ -7036,9 +7118,9 @@ Object.assign( Ray.prototype, { intersectSphere: function ( sphere, target ) { - _vector$3.subVectors( sphere.center, this.origin ); - var tca = _vector$3.dot( this.direction ); - var d2 = _vector$3.dot( _vector$3 ) - tca * tca; + _vector$2.subVectors( sphere.center, this.origin ); + var tca = _vector$2.dot( this.direction ); + var d2 = _vector$2.dot( _vector$2 ) - tca * tca; var radius2 = sphere.radius * sphere.radius; if ( d2 > radius2 ) return null; @@ -7208,7 +7290,7 @@ Object.assign( Ray.prototype, { intersectsBox: function ( box ) { - return this.intersectBox( box, _vector$3 ) !== null; + return this.intersectBox( box, _vector$2 ) !== null; }, @@ -7304,6 +7386,232 @@ Object.assign( Ray.prototype, { } ); +/** + * @author bhouston / http://clara.io + */ + +var _vector1 = new Vector3(); +var _vector2 = new Vector3(); +var _normalMatrix = new Matrix3(); + +function Plane( normal, constant ) { + + // normal is assumed to be normalized + + this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); + this.constant = ( constant !== undefined ) ? constant : 0; + +} + +Object.assign( Plane.prototype, { + + isPlane: true, + + set: function ( normal, constant ) { + + this.normal.copy( normal ); + this.constant = constant; + + return this; + + }, + + setComponents: function ( x, y, z, w ) { + + this.normal.set( x, y, z ); + this.constant = w; + + return this; + + }, + + setFromNormalAndCoplanarPoint: function ( normal, point ) { + + this.normal.copy( normal ); + this.constant = - point.dot( this.normal ); + + return this; + + }, + + setFromCoplanarPoints: function ( a, b, c ) { + + var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); + + // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? + + this.setFromNormalAndCoplanarPoint( normal, a ); + + return this; + + }, + + clone: function () { + + return new this.constructor().copy( this ); + + }, + + copy: function ( plane ) { + + this.normal.copy( plane.normal ); + this.constant = plane.constant; + + return this; + + }, + + normalize: function () { + + // Note: will lead to a divide by zero if the plane is invalid. + + var inverseNormalLength = 1.0 / this.normal.length(); + this.normal.multiplyScalar( inverseNormalLength ); + this.constant *= inverseNormalLength; + + return this; + + }, + + negate: function () { + + this.constant *= - 1; + this.normal.negate(); + + return this; + + }, + + distanceToPoint: function ( point ) { + + return this.normal.dot( point ) + this.constant; + + }, + + distanceToSphere: function ( sphere ) { + + return this.distanceToPoint( sphere.center ) - sphere.radius; + + }, + + projectPoint: function ( point, target ) { + + if ( target === undefined ) { + + console.warn( 'THREE.Plane: .projectPoint() target is now required' ); + target = new Vector3(); + + } + + return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); + + }, + + intersectLine: function ( line, target ) { + + if ( target === undefined ) { + + console.warn( 'THREE.Plane: .intersectLine() target is now required' ); + target = new Vector3(); + + } + + var direction = line.delta( _vector1 ); + + var denominator = this.normal.dot( direction ); + + if ( denominator === 0 ) { + + // line is coplanar, return origin + if ( this.distanceToPoint( line.start ) === 0 ) { + + return target.copy( line.start ); + + } + + // Unsure if this is the correct method to handle this case. + return undefined; + + } + + var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + + if ( t < 0 || t > 1 ) { + + return undefined; + + } + + return target.copy( direction ).multiplyScalar( t ).add( line.start ); + + }, + + intersectsLine: function ( line ) { + + // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + + var startSign = this.distanceToPoint( line.start ); + var endSign = this.distanceToPoint( line.end ); + + return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); + + }, + + intersectsBox: function ( box ) { + + return box.intersectsPlane( this ); + + }, + + intersectsSphere: function ( sphere ) { + + return sphere.intersectsPlane( this ); + + }, + + coplanarPoint: function ( target ) { + + if ( target === undefined ) { + + console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); + target = new Vector3(); + + } + + return target.copy( this.normal ).multiplyScalar( - this.constant ); + + }, + + applyMatrix4: function ( matrix, optionalNormalMatrix ) { + + var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); + + var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); + + var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); + + this.constant = - referencePoint.dot( normal ); + + return this; + + }, + + translate: function ( offset ) { + + this.constant -= offset.dot( this.normal ); + + return this; + + }, + + equals: function ( plane ) { + + return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); + + } + +} ); + /** * @author bhouston / http://clara.io * @author mrdoob / http://mrdoob.com/ @@ -7500,7 +7808,7 @@ Object.assign( Triangle.prototype, { if ( target === undefined ) { console.warn( 'THREE.Triangle: .getPlane() target is now required' ); - target = new Vector3(); + target = new Plane(); } @@ -7763,9 +8071,9 @@ Object.assign( Color.prototype, { setHSL: function ( h, s, l ) { // h,s,l ranges are in 0.0 - 1.0 - h = _Math.euclideanModulo( h, 1 ); - s = _Math.clamp( s, 0, 1 ); - l = _Math.clamp( l, 0, 1 ); + h = MathUtils.euclideanModulo( h, 1 ); + s = MathUtils.clamp( s, 0, 1 ); + l = MathUtils.clamp( l, 0, 1 ); if ( s === 0 ) { @@ -7895,20 +8203,28 @@ Object.assign( Color.prototype, { if ( style && style.length > 0 ) { - // color keywords - var hex = _colorKeywords[ style ]; + return this.setColorName( style ); - if ( hex !== undefined ) { + } - // red - this.setHex( hex ); + return this; - } else { + }, - // unknown color - console.warn( 'THREE.Color: Unknown color ' + style ); + setColorName: function ( style ) { - } + // color keywords + var hex = _colorKeywords[ style ]; + + if ( hex !== undefined ) { + + // red + this.setHex( hex ); + + } else { + + // unknown color + console.warn( 'THREE.Color: Unknown color ' + style ); } @@ -8165,9 +8481,9 @@ Object.assign( Color.prototype, { this.getHSL( _hslA ); color.getHSL( _hslB ); - var h = _Math.lerp( _hslA.h, _hslB.h, alpha ); - var s = _Math.lerp( _hslA.s, _hslB.s, alpha ); - var l = _Math.lerp( _hslA.l, _hslB.l, alpha ); + var h = MathUtils.lerp( _hslA.h, _hslB.h, alpha ); + var s = MathUtils.lerp( _hslA.s, _hslB.s, alpha ); + var l = MathUtils.lerp( _hslA.l, _hslB.l, alpha ); this.setHSL( h, s, l ); @@ -8214,6 +8530,8 @@ Object.assign( Color.prototype, { } ); +Color.NAMES = _colorKeywords; + /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ @@ -8283,19 +8601,17 @@ function Material() { Object.defineProperty( this, 'id', { value: materialId ++ } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'Material'; this.fog = true; - this.lights = true; this.blending = NormalBlending; this.side = FrontSide; this.flatShading = false; - this.vertexTangents = false; - this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors + this.vertexColors = false; this.opacity = 1; this.transparent = false; @@ -8311,9 +8627,10 @@ function Material() { this.depthTest = true; this.depthWrite = true; + this.stencilWriteMask = 0xff; this.stencilFunc = AlwaysStencilFunc; this.stencilRef = 0; - this.stencilMask = 0xff; + this.stencilFuncMask = 0xff; this.stencilFail = KeepStencilOp; this.stencilZFail = KeepStencilOp; this.stencilZPass = KeepStencilOp; @@ -8340,9 +8657,11 @@ function Material() { this.visible = true; + this.toneMapped = true; + this.userData = {}; - this.needsUpdate = true; + this.version = 0; } @@ -8437,18 +8756,31 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), if ( this.roughness !== undefined ) data.roughness = this.roughness; if ( this.metalness !== undefined ) data.metalness = this.metalness; + if ( this.sheen && this.sheen.isColor ) data.sheen = this.sheen.getHex(); if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); if ( this.shininess !== undefined ) data.shininess = this.shininess; - if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; - if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; + if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; + if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; + + if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { - if ( this.clearCoatNormalMap && this.clearCoatNormalMap.isTexture ) { + data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; - data.clearCoatNormalMap = this.clearCoatNormalMap.toJSON( meta ).uuid; - data.clearCoatNormalScale = this.clearCoatNormalScale.toArray(); + } + + if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { + + data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; + + } + + if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { + + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; + data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); } @@ -8516,7 +8848,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), if ( this.blending !== NormalBlending ) data.blending = this.blending; if ( this.flatShading === true ) data.flatShading = this.flatShading; if ( this.side !== FrontSide ) data.side = this.side; - if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors; + if ( this.vertexColors ) data.vertexColors = true; if ( this.opacity < 1 ) data.opacity = this.opacity; if ( this.transparent === true ) data.transparent = this.transparent; @@ -8526,9 +8858,10 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), data.depthWrite = this.depthWrite; data.stencilWrite = this.stencilWrite; + data.stencilWriteMask = this.stencilWriteMask; data.stencilFunc = this.stencilFunc; data.stencilRef = this.stencilRef; - data.stencilMask = this.stencilMask; + data.stencilFuncMask = this.stencilFuncMask; data.stencilFail = this.stencilFail; data.stencilZFail = this.stencilZFail; data.stencilZPass = this.stencilZPass; @@ -8560,6 +8893,9 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), if ( this.skinning === true ) data.skinning = true; if ( this.visible === false ) data.visible = false; + + if ( this.toneMapped === false ) data.toneMapped = false; + if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; // TODO: Copied from Object3D.toJSON @@ -8605,7 +8941,6 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), this.name = source.name; this.fog = source.fog; - this.lights = source.lights; this.blending = source.blending; this.side = source.side; @@ -8626,13 +8961,33 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), this.depthTest = source.depthTest; this.depthWrite = source.depthWrite; - this.stencilWrite = source.stencilWrite; + this.stencilWriteMask = source.stencilWriteMask; this.stencilFunc = source.stencilFunc; this.stencilRef = source.stencilRef; - this.stencilMask = source.stencilMask; + this.stencilFuncMask = source.stencilFuncMask; this.stencilFail = source.stencilFail; this.stencilZFail = source.stencilZFail; this.stencilZPass = source.stencilZPass; + this.stencilWrite = source.stencilWrite; + + var srcPlanes = source.clippingPlanes, + dstPlanes = null; + + if ( srcPlanes !== null ) { + + var n = srcPlanes.length; + dstPlanes = new Array( n ); + + for ( var i = 0; i !== n; ++ i ) + dstPlanes[ i ] = srcPlanes[ i ].clone(); + + } + + this.clippingPlanes = dstPlanes; + this.clipIntersection = source.clipIntersection; + this.clipShadows = source.clipShadows; + + this.shadowSide = source.shadowSide; this.colorWrite = source.colorWrite; @@ -8648,35 +9003,28 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), this.premultipliedAlpha = source.premultipliedAlpha; this.visible = source.visible; - this.userData = JSON.parse( JSON.stringify( source.userData ) ); - this.clipShadows = source.clipShadows; - this.clipIntersection = source.clipIntersection; + this.toneMapped = source.toneMapped; - var srcPlanes = source.clippingPlanes, - dstPlanes = null; - - if ( srcPlanes !== null ) { + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - var n = srcPlanes.length; - dstPlanes = new Array( n ); + return this; - for ( var i = 0; i !== n; ++ i ) - dstPlanes[ i ] = srcPlanes[ i ].clone(); + }, - } + dispose: function () { - this.clippingPlanes = dstPlanes; + this.dispatchEvent( { type: 'dispose' } ); - this.shadowSide = source.shadowSide; + } - return this; +} ); - }, +Object.defineProperty( Material.prototype, 'needsUpdate', { - dispose: function () { + set: function ( value ) { - this.dispatchEvent( { type: 'dispose' } ); + if ( value === true ) this.version ++; } @@ -8750,8 +9098,6 @@ function MeshBasicMaterial( parameters ) { this.skinning = false; this.morphTargets = false; - this.lights = false; - this.setValues( parameters ); } @@ -8800,6 +9146,8 @@ MeshBasicMaterial.prototype.copy = function ( source ) { * @author mrdoob / http://mrdoob.com/ */ +var _vector$3 = new Vector3(); + function BufferAttribute( array, itemSize, normalized ) { if ( Array.isArray( array ) ) { @@ -8815,7 +9163,7 @@ function BufferAttribute( array, itemSize, normalized ) { this.count = array !== undefined ? array.length / itemSize : 0; this.normalized = normalized === true; - this.dynamic = false; + this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: - 1 }; this.version = 0; @@ -8838,24 +9186,9 @@ Object.assign( BufferAttribute.prototype, { onUploadCallback: function () {}, - setArray: function ( array ) { - - if ( Array.isArray( array ) ) { - - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - - } + setUsage: function ( value ) { - this.count = array !== undefined ? array.length / this.itemSize : 0; - this.array = array; - - return this; - - }, - - setDynamic: function ( value ) { - - this.dynamic = value; + this.usage = value; return this; @@ -8869,7 +9202,7 @@ Object.assign( BufferAttribute.prototype, { this.count = source.count; this.normalized = source.normalized; - this.dynamic = source.dynamic; + this.usage = source.usage; return this; @@ -8998,6 +9331,78 @@ Object.assign( BufferAttribute.prototype, { }, + applyMatrix3: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.applyMatrix3( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + + applyMatrix4: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.applyMatrix4( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + + applyNormalMatrix: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.applyNormalMatrix( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + + transformDirection: function ( m ) { + + for ( var i = 0, l = this.count; i < l; i ++ ) { + + _vector$3.x = this.getX( i ); + _vector$3.y = this.getY( i ); + _vector$3.z = this.getZ( i ); + + _vector$3.transformDirection( m ); + + this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z ); + + } + + return this; + + }, + set: function ( value, offset ) { if ( offset === undefined ) offset = 0; @@ -9530,7 +9935,7 @@ var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id var _m1$2 = new Matrix4(); var _obj = new Object3D(); var _offset = new Vector3(); -var _box$1 = new Box3(); +var _box$2 = new Box3(); var _boxMorphTargets = new Box3(); var _vector$4 = new Vector3(); @@ -9538,7 +9943,7 @@ function BufferGeometry() { Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'BufferGeometry'; @@ -9547,6 +9952,7 @@ function BufferGeometry() { this.attributes = {}; this.morphAttributes = {}; + this.morphTargetsRelative = false; this.groups = []; @@ -9585,24 +9991,13 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy }, - addAttribute: function ( name, attribute ) { - - if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { - - console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); - - return this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); - - } - - if ( name === 'index' ) { + getAttribute: function ( name ) { - console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); - this.setIndex( attribute ); + return this.attributes[ name ]; - return this; + }, - } + setAttribute: function ( name, attribute ) { this.attributes[ name ] = attribute; @@ -9610,13 +10005,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy }, - getAttribute: function ( name ) { - - return this.attributes[ name ]; - - }, - - removeAttribute: function ( name ) { + deleteAttribute: function ( name ) { delete this.attributes[ name ]; @@ -9649,13 +10038,14 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy }, - applyMatrix: function ( matrix ) { + applyMatrix4: function ( matrix ) { var position = this.attributes.position; if ( position !== undefined ) { - matrix.applyToBufferAttribute( position ); + position.applyMatrix4( matrix ); + position.needsUpdate = true; } @@ -9666,7 +10056,8 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy var normalMatrix = new Matrix3().getNormalMatrix( matrix ); - normalMatrix.applyToBufferAttribute( normal ); + normal.applyNormalMatrix( normalMatrix ); + normal.needsUpdate = true; } @@ -9675,10 +10066,8 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy if ( tangent !== undefined ) { - var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + tangent.transformDirection( matrix ); - // Tangent is vec4, but the '.w' component is a sign value (+1/-1). - normalMatrix.applyToBufferAttribute( tangent ); tangent.needsUpdate = true; } @@ -9705,7 +10094,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy _m1$2.makeRotationX( angle ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9717,7 +10106,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy _m1$2.makeRotationY( angle ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9729,7 +10118,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy _m1$2.makeRotationZ( angle ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9741,7 +10130,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy _m1$2.makeTranslation( x, y, z ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9753,7 +10142,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy _m1$2.makeScale( x, y, z ); - this.applyMatrix( _m1$2 ); + this.applyMatrix4( _m1$2 ); return this; @@ -9765,7 +10154,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy _obj.updateMatrix(); - this.applyMatrix( _obj.matrix ); + this.applyMatrix4( _obj.matrix ); return this; @@ -9794,14 +10183,14 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); - this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); - this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); + this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); + this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); - this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); + this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); } @@ -9842,7 +10231,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy } - this.addAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); return this; @@ -9986,33 +10375,33 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy fromDirectGeometry: function ( geometry ) { var positions = new Float32Array( geometry.vertices.length * 3 ); - this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); + this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); if ( geometry.normals.length > 0 ) { var normals = new Float32Array( geometry.normals.length * 3 ); - this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); + this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); } if ( geometry.colors.length > 0 ) { var colors = new Float32Array( geometry.colors.length * 3 ); - this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); + this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); } if ( geometry.uvs.length > 0 ) { var uvs = new Float32Array( geometry.uvs.length * 2 ); - this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); + this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); } if ( geometry.uvs2.length > 0 ) { var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); - this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); + this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); } @@ -10047,14 +10436,14 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy if ( geometry.skinIndices.length > 0 ) { var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); - this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); + this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); } if ( geometry.skinWeights.length > 0 ) { var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); - this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); + this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); } @@ -10098,10 +10487,22 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { var morphAttribute = morphAttributesPosition[ i ]; - _box$1.setFromBufferAttribute( morphAttribute ); + _box$2.setFromBufferAttribute( morphAttribute ); + + if ( this.morphTargetsRelative ) { - this.boundingBox.expandByPoint( _box$1.min ); - this.boundingBox.expandByPoint( _box$1.max ); + _vector$4.addVectors( this.boundingBox.min, _box$2.min ); + this.boundingBox.expandByPoint( _vector$4 ); + + _vector$4.addVectors( this.boundingBox.max, _box$2.max ); + this.boundingBox.expandByPoint( _vector$4 ); + + } else { + + this.boundingBox.expandByPoint( _box$2.min ); + this.boundingBox.expandByPoint( _box$2.max ); + + } } @@ -10138,7 +10539,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy var center = this.boundingSphere.center; - _box$1.setFromBufferAttribute( position ); + _box$2.setFromBufferAttribute( position ); // process morph attributes if present @@ -10149,14 +10550,26 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy var morphAttribute = morphAttributesPosition[ i ]; _boxMorphTargets.setFromBufferAttribute( morphAttribute ); - _box$1.expandByPoint( _boxMorphTargets.min ); - _box$1.expandByPoint( _boxMorphTargets.max ); + if ( this.morphTargetsRelative ) { + + _vector$4.addVectors( _box$2.min, _boxMorphTargets.min ); + _box$2.expandByPoint( _vector$4 ); + + _vector$4.addVectors( _box$2.max, _boxMorphTargets.max ); + _box$2.expandByPoint( _vector$4 ); + + } else { + + _box$2.expandByPoint( _boxMorphTargets.min ); + _box$2.expandByPoint( _boxMorphTargets.max ); + + } } } - _box$1.getCenter( center ); + _box$2.getCenter( center ); // second, try to find a boundingSphere with a radius smaller than the // boundingSphere of the boundingBox: sqrt(3) smaller in the best case @@ -10178,11 +10591,19 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { var morphAttribute = morphAttributesPosition[ i ]; + var morphTargetsRelative = this.morphTargetsRelative; for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { _vector$4.fromBufferAttribute( morphAttribute, j ); + if ( morphTargetsRelative ) { + + _offset.fromBufferAttribute( position, j ); + _vector$4.add( _offset ); + + } + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) ); } @@ -10220,7 +10641,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy if ( attributes.normal === undefined ) { - this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); + this.setAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); } else { @@ -10428,7 +10849,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy var newAttribute = convertBufferAttribute( attribute, indices ); - geometry2.addAttribute( name, newAttribute ); + geometry2.setAttribute( name, newAttribute ); } @@ -10455,6 +10876,8 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy } + geometry2.morphTargetsRelative = this.morphTargetsRelative; + // groups var groups = this.groups; @@ -10559,7 +10982,12 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy } - if ( hasMorphAttributes ) data.data.morphAttributes = morphAttributes; + if ( hasMorphAttributes ) { + + data.data.morphAttributes = morphAttributes; + data.data.morphTargetsRelative = this.morphTargetsRelative; + + } var groups = this.groups; @@ -10648,7 +11076,7 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy for ( name in attributes ) { var attribute = attributes[ name ]; - this.addAttribute( name, attribute.clone() ); + this.setAttribute( name, attribute.clone() ); } @@ -10671,6 +11099,8 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy } + this.morphTargetsRelative = source.morphTargetsRelative; + // groups var groups = source.groups; @@ -10760,9 +11190,7 @@ function Mesh( geometry, material ) { this.type = 'Mesh'; this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } ); - - this.drawMode = TrianglesDrawMode; + this.material = material !== undefined ? material : new MeshBasicMaterial(); this.updateMorphTargets(); @@ -10774,18 +11202,10 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { isMesh: true, - setDrawMode: function ( value ) { - - this.drawMode = value; - - }, - copy: function ( source ) { Object3D.prototype.copy.call( this, source ); - this.drawMode = source.drawMode; - if ( source.morphTargetInfluences !== undefined ) { this.morphTargetInfluences = source.morphTargetInfluences.slice(); @@ -10886,6 +11306,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { var index = geometry.index; var position = geometry.attributes.position; var morphPosition = geometry.morphAttributes.position; + var morphTargetsRelative = geometry.morphTargetsRelative; var uv = geometry.attributes.uv; var uv2 = geometry.attributes.uv2; var groups = geometry.groups; @@ -10914,7 +11335,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = index.getX( j + 1 ); c = index.getX( j + 2 ); - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -10939,7 +11360,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = index.getX( i + 1 ); c = index.getX( i + 2 ); - intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -10972,7 +11393,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = j + 1; c = j + 2; - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -10997,7 +11418,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { b = i + 1; c = i + 2; - intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, uv, uv2, a, b, c ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ); if ( intersection ) { @@ -11101,7 +11522,7 @@ function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point } -function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, uv2, a, b, c ) { +function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) { _vA.fromBufferAttribute( position, a ); _vB.fromBufferAttribute( position, b ); @@ -11126,9 +11547,19 @@ function checkBufferGeometryIntersection( object, material, raycaster, ray, posi _tempB.fromBufferAttribute( morphAttribute, b ); _tempC.fromBufferAttribute( morphAttribute, c ); - _morphA.addScaledVector( _tempA.sub( _vA ), influence ); - _morphB.addScaledVector( _tempB.sub( _vB ), influence ); - _morphC.addScaledVector( _tempC.sub( _vC ), influence ); + if ( morphTargetsRelative ) { + + _morphA.addScaledVector( _tempA, influence ); + _morphB.addScaledVector( _tempB, influence ); + _morphC.addScaledVector( _tempC, influence ); + + } else { + + _morphA.addScaledVector( _tempA.sub( _vA ), influence ); + _morphB.addScaledVector( _tempB.sub( _vB ), influence ); + _morphC.addScaledVector( _tempC.sub( _vC ), influence ); + + } } @@ -11191,7 +11622,7 @@ function Geometry() { Object.defineProperty( this, 'id', { value: _geometryId += 2 } ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.name = ''; this.type = 'Geometry'; @@ -11230,7 +11661,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), isGeometry: true, - applyMatrix: function ( matrix ) { + applyMatrix4: function ( matrix ) { var normalMatrix = new Matrix3().getNormalMatrix( matrix ); @@ -11279,7 +11710,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), _m1$3.makeRotationX( angle ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11291,7 +11722,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), _m1$3.makeRotationY( angle ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11303,7 +11734,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), _m1$3.makeRotationZ( angle ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11315,7 +11746,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), _m1$3.makeTranslation( x, y, z ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11327,7 +11758,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), _m1$3.makeScale( x, y, z ); - this.applyMatrix( _m1$3 ); + this.applyMatrix4( _m1$3 ); return this; @@ -11339,7 +11770,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), _obj$1.updateMatrix(); - this.applyMatrix( _obj$1.matrix ); + this.applyMatrix4( _obj$1.matrix ); return this; @@ -11352,6 +11783,13 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), var indices = geometry.index !== null ? geometry.index.array : undefined; var attributes = geometry.attributes; + if ( attributes.position === undefined ) { + + console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' ); + return this; + + } + var positions = attributes.position.array; var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; var colors = attributes.color !== undefined ? attributes.color.array : undefined; @@ -11507,7 +11945,7 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), 0, 0, 0, 1 ); - this.applyMatrix( matrix ); + this.applyMatrix4( matrix ); return this; @@ -12564,195 +13002,197 @@ Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), // BoxGeometry -function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { +class BoxGeometry extends Geometry { - Geometry.call( this ); + constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { - this.type = 'BoxGeometry'; + super(); - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + this.type = 'BoxGeometry'; - this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); - this.mergeVertices(); + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; -} + this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); + this.mergeVertices(); + + } -BoxGeometry.prototype = Object.create( Geometry.prototype ); -BoxGeometry.prototype.constructor = BoxGeometry; +} // BoxBufferGeometry -function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) { +class BoxBufferGeometry extends BufferGeometry { - BufferGeometry.call( this ); + constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) { - this.type = 'BoxBufferGeometry'; + super(); - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + this.type = 'BoxBufferGeometry'; - var scope = this; + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; - width = width || 1; - height = height || 1; - depth = depth || 1; + var scope = this; - // segments + width = width || 1; + height = height || 1; + depth = depth || 1; - widthSegments = Math.floor( widthSegments ) || 1; - heightSegments = Math.floor( heightSegments ) || 1; - depthSegments = Math.floor( depthSegments ) || 1; + // segments - // buffers + widthSegments = Math.floor( widthSegments ) || 1; + heightSegments = Math.floor( heightSegments ) || 1; + depthSegments = Math.floor( depthSegments ) || 1; - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + // buffers - // helper variables + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - var numberOfVertices = 0; - var groupStart = 0; + // helper variables - // build each side of the box geometry + var numberOfVertices = 0; + var groupStart = 0; - buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px - buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx - buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py - buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny - buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz - buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + // build each side of the box geometry - // build geometry + buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px + buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx + buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py + buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny + buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz + buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + // build geometry - function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - var segmentWidth = width / gridX; - var segmentHeight = height / gridY; + function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { - var widthHalf = width / 2; - var heightHalf = height / 2; - var depthHalf = depth / 2; + var segmentWidth = width / gridX; + var segmentHeight = height / gridY; - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + var widthHalf = width / 2; + var heightHalf = height / 2; + var depthHalf = depth / 2; - var vertexCounter = 0; - var groupCount = 0; + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; - var ix, iy; + var vertexCounter = 0; + var groupCount = 0; - var vector = new Vector3(); + var ix, iy; - // generate vertices, normals and uvs + var vector = new Vector3(); + + // generate vertices, normals and uvs - for ( iy = 0; iy < gridY1; iy ++ ) { + for ( iy = 0; iy < gridY1; iy ++ ) { - var y = iy * segmentHeight - heightHalf; + var y = iy * segmentHeight - heightHalf; - for ( ix = 0; ix < gridX1; ix ++ ) { + for ( ix = 0; ix < gridX1; ix ++ ) { - var x = ix * segmentWidth - widthHalf; + var x = ix * segmentWidth - widthHalf; - // set values to correct vector component + // set values to correct vector component - vector[ u ] = x * udir; - vector[ v ] = y * vdir; - vector[ w ] = depthHalf; + vector[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; - // now apply vector to vertex buffer + // now apply vector to vertex buffer - vertices.push( vector.x, vector.y, vector.z ); + vertices.push( vector.x, vector.y, vector.z ); - // set values to correct vector component + // set values to correct vector component - vector[ u ] = 0; - vector[ v ] = 0; - vector[ w ] = depth > 0 ? 1 : - 1; + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : - 1; - // now apply vector to normal buffer + // now apply vector to normal buffer - normals.push( vector.x, vector.y, vector.z ); + normals.push( vector.x, vector.y, vector.z ); - // uvs + // uvs - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); - // counters + // counters - vertexCounter += 1; + vertexCounter += 1; + + } } - } + // indices - // indices + // 1. you need three indices to draw a single face + // 2. a single segment consists of two faces + // 3. so we need to generate six (2*3) indices per segment - // 1. you need three indices to draw a single face - // 2. a single segment consists of two faces - // 3. so we need to generate six (2*3) indices per segment + for ( iy = 0; iy < gridY; iy ++ ) { - for ( iy = 0; iy < gridY; iy ++ ) { + for ( ix = 0; ix < gridX; ix ++ ) { - for ( ix = 0; ix < gridX; ix ++ ) { + var a = numberOfVertices + ix + gridX1 * iy; + var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); + var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; - var a = numberOfVertices + ix + gridX1 * iy; - var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); - var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + // faces - // faces + indices.push( a, b, d ); + indices.push( b, c, d ); - indices.push( a, b, d ); - indices.push( b, c, d ); + // increase counter - // increase counter + groupCount += 6; - groupCount += 6; + } } - } + // add a group to the geometry. this will ensure multi material support - // add a group to the geometry. this will ensure multi material support + scope.addGroup( groupStart, groupCount, materialIndex ); - scope.addGroup( groupStart, groupCount, materialIndex ); + // calculate new start value for groups - // calculate new start value for groups + groupStart += groupCount; - groupStart += groupCount; + // update total number of vertices - // update total number of vertices + numberOfVertices += vertexCounter; - numberOfVertices += vertexCounter; + } } } -BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); -BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; - /** * Uniform Utilities */ @@ -13087,6 +13527,14 @@ Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { }, + updateWorldMatrix: function ( updateParents, updateChildren ) { + + Object3D.prototype.updateWorldMatrix.call( this, updateParents, updateChildren ); + + this.matrixWorldInverse.getInverse( this.matrixWorld ); + + }, + clone: function () { return new this.constructor().copy( this ); @@ -13165,7 +13613,7 @@ PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), // see http://www.bobatkins.com/photography/technical/field_of_view.html var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope ); this.updateProjectionMatrix(); }, @@ -13175,7 +13623,7 @@ PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), */ getFocalLength: function () { - var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov ); + var vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ); return 0.5 * this.getFilmHeight() / vExtentSlope; @@ -13183,8 +13631,8 @@ PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), getEffectiveFOV: function () { - return _Math.RAD2DEG * 2 * Math.atan( - Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom ); + return MathUtils.RAD2DEG * 2 * Math.atan( + Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom ); }, @@ -13282,7 +13730,7 @@ PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), updateProjectionMatrix: function () { var near = this.near, - top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, + top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom, height = 2 * top, width = this.aspect * height, left = - 0.5 * width, @@ -13380,7 +13828,7 @@ function CubeCamera( near, far, cubeResolution, options ) { options = options || { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; - this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options ); + this.renderTarget = new WebGLCubeRenderTarget( cubeResolution, options ); this.renderTarget.texture.name = "CubeCamera"; this.update = function ( renderer, scene ) { @@ -13446,18 +13894,26 @@ CubeCamera.prototype.constructor = CubeCamera; * @author WestLangley / http://github.com/WestLangley */ -function WebGLRenderTargetCube( width, height, options ) { +function WebGLCubeRenderTarget( size, options, dummy ) { - WebGLRenderTarget.call( this, width, height, options ); + if ( Number.isInteger( options ) ) { + + console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' ); + + options = dummy; + + } + + WebGLRenderTarget.call( this, size, size, options ); } -WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype ); -WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube; +WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype ); +WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget; -WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true; +WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true; -WebGLRenderTargetCube.prototype.fromEquirectangularTexture = function ( renderer, texture ) { +WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) { this.texture.type = texture.type; this.texture.format = texture.format; @@ -13558,7 +14014,7 @@ function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); - this.image = { data: data, width: width, height: height }; + this.image = { data: data || null, width: width || 1, height: height || 1 }; this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; @@ -13567,6 +14023,8 @@ function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, this.flipY = false; this.unpackAlignment = 1; + this.needsUpdate = true; + } DataTexture.prototype = Object.create( Texture.prototype ); @@ -13574,232 +14032,6 @@ DataTexture.prototype.constructor = DataTexture; DataTexture.prototype.isDataTexture = true; -/** - * @author bhouston / http://clara.io - */ - -var _vector1 = new Vector3(); -var _vector2 = new Vector3(); -var _normalMatrix = new Matrix3(); - -function Plane( normal, constant ) { - - // normal is assumed to be normalized - - this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); - this.constant = ( constant !== undefined ) ? constant : 0; - -} - -Object.assign( Plane.prototype, { - - isPlane: true, - - set: function ( normal, constant ) { - - this.normal.copy( normal ); - this.constant = constant; - - return this; - - }, - - setComponents: function ( x, y, z, w ) { - - this.normal.set( x, y, z ); - this.constant = w; - - return this; - - }, - - setFromNormalAndCoplanarPoint: function ( normal, point ) { - - this.normal.copy( normal ); - this.constant = - point.dot( this.normal ); - - return this; - - }, - - setFromCoplanarPoints: function ( a, b, c ) { - - var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize(); - - // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? - - this.setFromNormalAndCoplanarPoint( normal, a ); - - return this; - - }, - - clone: function () { - - return new this.constructor().copy( this ); - - }, - - copy: function ( plane ) { - - this.normal.copy( plane.normal ); - this.constant = plane.constant; - - return this; - - }, - - normalize: function () { - - // Note: will lead to a divide by zero if the plane is invalid. - - var inverseNormalLength = 1.0 / this.normal.length(); - this.normal.multiplyScalar( inverseNormalLength ); - this.constant *= inverseNormalLength; - - return this; - - }, - - negate: function () { - - this.constant *= - 1; - this.normal.negate(); - - return this; - - }, - - distanceToPoint: function ( point ) { - - return this.normal.dot( point ) + this.constant; - - }, - - distanceToSphere: function ( sphere ) { - - return this.distanceToPoint( sphere.center ) - sphere.radius; - - }, - - projectPoint: function ( point, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Plane: .projectPoint() target is now required' ); - target = new Vector3(); - - } - - return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); - - }, - - intersectLine: function ( line, target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Plane: .intersectLine() target is now required' ); - target = new Vector3(); - - } - - var direction = line.delta( _vector1 ); - - var denominator = this.normal.dot( direction ); - - if ( denominator === 0 ) { - - // line is coplanar, return origin - if ( this.distanceToPoint( line.start ) === 0 ) { - - return target.copy( line.start ); - - } - - // Unsure if this is the correct method to handle this case. - return undefined; - - } - - var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; - - if ( t < 0 || t > 1 ) { - - return undefined; - - } - - return target.copy( direction ).multiplyScalar( t ).add( line.start ); - - }, - - intersectsLine: function ( line ) { - - // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. - - var startSign = this.distanceToPoint( line.start ); - var endSign = this.distanceToPoint( line.end ); - - return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); - - }, - - intersectsBox: function ( box ) { - - return box.intersectsPlane( this ); - - }, - - intersectsSphere: function ( sphere ) { - - return sphere.intersectsPlane( this ); - - }, - - coplanarPoint: function ( target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); - target = new Vector3(); - - } - - return target.copy( this.normal ).multiplyScalar( - this.constant ); - - }, - - applyMatrix4: function ( matrix, optionalNormalMatrix ) { - - var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix ); - - var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix ); - - var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); - - this.constant = - referencePoint.dot( normal ); - - return this; - - }, - - translate: function ( offset ) { - - this.constant -= offset.dot( this.normal ); - - return this; - - }, - - equals: function ( plane ) { - - return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); - - } - -} ); - /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ @@ -13861,7 +14093,7 @@ Object.assign( Frustum.prototype, { }, - setFromMatrix: function ( m ) { + setFromProjectionMatrix: function ( m ) { var planes = this.planes; var me = m.elements; @@ -13971,1179 +14203,1233 @@ Object.assign( Frustum.prototype, { } ); -var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; +/** + * Uniforms library for shared webgl shaders + */ -var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; +var UniformsLib = { -var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; + common: { -var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, -var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; + map: { value: null }, + uvTransform: { value: new Matrix3() }, + uv2Transform: { value: new Matrix3() }, -var begin_vertex = "vec3 transformed = vec3( position );"; + alphaMap: { value: null }, -var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; + }, -var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}"; + specularmap: { -var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; + specularMap: { value: null }, -var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; + }, -var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; + envmap: { -var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif"; + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + reflectivity: { value: 1.0 }, + refractionRatio: { value: 0.98 }, + maxMipLevel: { value: 0 } -var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; + }, -var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; + aomap: { -var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; + aoMap: { value: null }, + aoMapIntensity: { value: 1 } -var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; + }, -var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; + lightmap: { -var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n\tvec3 clearCoatNormal;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}"; + lightMap: { value: null }, + lightMapIntensity: { value: 1 } -var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif"; + }, -var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; + emissivemap: { -var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; + emissiveMap: { value: null } -var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif"; + }, -var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; + bumpmap: { -var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; + bumpMap: { value: null }, + bumpScale: { value: 1 } -var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; + }, -var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; + normalmap: { -var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; + normalMap: { value: null }, + normalScale: { value: new Vector2( 1, 1 ) } -var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; + }, -var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; + displacementmap: { -var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; + displacementMap: { value: null }, + displacementScale: { value: 1 }, + displacementBias: { value: 0 } -var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; + }, -var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; + roughnessmap: { -var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; + roughnessMap: { value: null } -var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; + }, -var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif"; + metalnessmap: { -var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif"; + metalnessMap: { value: null } -var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; + }, -var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif"; + gradientmap: { -var lights_pars_begin = "uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; + gradientMap: { value: null } -var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; + }, -var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; + fog: { -var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; + fogDensity: { value: 0.00025 }, + fogNear: { value: 1 }, + fogFar: { value: 2000 }, + fogColor: { value: new Color( 0xffffff ) } -var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif"; + }, -var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat ccDotNL = saturate( dot( geometry.clearCoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearCoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifndef STANDARD\n\t\tfloat ccDotNV = saturate( dot( geometry.clearCoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearCoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\tfloat clearCoatInv = 1.0 - clearCoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;\n\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; + lights: { -var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tgeometry.clearCoatNormal = clearCoatNormal;\n#else\n\tgeometry.clearCoatNormal = geometryNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif"; + ambientLightColor: { value: [] }, -var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearCoatNormal, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif"; + lightProbe: { value: [] }, -var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, irradiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif"; + directionalLights: { value: [], properties: { + direction: {}, + color: {} + } }, -var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; + directionalLightShadows: { value: [], properties: { + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, -var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif"; + directionalShadowMap: { value: [] }, + directionalShadowMatrix: { value: [] }, -var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; + spotLights: { value: [], properties: { + color: {}, + position: {}, + direction: {}, + distance: {}, + coneCos: {}, + penumbraCos: {}, + decay: {} + } }, -var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif"; + spotLightShadows: { value: [], properties: { + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, -var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; + spotShadowMap: { value: [] }, + spotShadowMatrix: { value: [] }, -var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; + pointLights: { value: [], properties: { + color: {}, + position: {}, + decay: {}, + distance: {} + } }, -var map_particle_fragment = "#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif"; + pointLightShadows: { value: [], properties: { + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {}, + shadowCameraNear: {}, + shadowCameraFar: {} + } }, -var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif"; + pointShadowMap: { value: [] }, + pointShadowMatrix: { value: [] }, -var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; + hemisphereLights: { value: [], properties: { + direction: {}, + skyColor: {}, + groundColor: {} + } }, -var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src + rectAreaLights: { value: [], properties: { + color: {}, + position: {}, + width: {}, + height: {} + } } -var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif"; + }, -var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; + points: { -var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + size: { value: 1.0 }, + scale: { value: 1.0 }, + map: { value: null }, + alphaMap: { value: null }, + uvTransform: { value: new Matrix3() } -var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; + }, -var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy = normalScale * mapN.xy;\n\t\t\tnormal = normalize( vTBN * mapN );\n\t\t#else\n\t\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, normalScale, normalMap );\n\t\t#endif\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; + sprite: { -var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#endif\n#endif\n#if ( defined ( USE_NORMALMAP ) && !defined ( OBJECTSPACE_NORMALMAP )) || defined ( USE_CLEARCOAT_NORMALMAP )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec2 normalScale, in sampler2D normalMap ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy *= normalScale;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvec3 NfromST = cross( S, T );\n\t\t\tif( dot( NfromST, N ) > 0.0 ) {\n\t\t\t\tS *= -1.0;\n\t\t\t\tT *= -1.0;\n\t\t\t}\n\t\t#else\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif"; + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + center: { value: new Vector2( 0.5, 0.5 ) }, + rotation: { value: 0.0 }, + map: { value: null }, + alphaMap: { value: null }, + uvTransform: { value: new Matrix3() } -var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT_NORMALMAP\n vec3 clearCoatNormal = geometryNormal;\n#endif"; + } -var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 vTBN = mat3( tangent, bitangent, clearCoatNormal );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = clearCoatNormalScale * mapN.xy;\n\t\tclearCoatNormal = normalize( vTBN * mapN );\n\t#else\n\t\tclearCoatNormal = perturbNormal2Arb( - vViewPosition, clearCoatNormal, clearCoatNormalScale, clearCoatNormalMap );\n\t#endif\n#endif"; +}; -var clearcoat_normalmap_pars_fragment = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearCoatNormalMap;\n\tuniform vec2 clearCoatNormalScale;\n#endif"; +/** + * @author mrdoob / http://mrdoob.com/ + */ -var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; +function WebGLAnimation() { -var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; + var context = null; + var isAnimating = false; + var animationLoop = null; -var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;"; + function onAnimationFrame( time, frame ) { -var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; + if ( isAnimating === false ) return; -var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; + animationLoop( time, frame ); -var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; + context.requestAnimationFrame( onAnimationFrame ); -var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; + } -var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; + return { -var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif"; + start: function () { -var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif"; + if ( isAnimating === true ) return; + if ( animationLoop === null ) return; -var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}"; + context.requestAnimationFrame( onAnimationFrame ); -var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; + isAnimating = true; -var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; + }, -var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; + stop: function () { -var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; + isAnimating = false; -var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; + }, -var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; + setAnimationLoop: function ( callback ) { -var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; + animationLoop = callback; -var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; + }, -var uv_pars_fragment = "#ifdef USE_UV\n\tvarying vec2 vUv;\n#endif"; + setContext: function ( value ) { -var uv_pars_vertex = "#ifdef USE_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif"; + context = value; -var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; + } -var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; + }; -var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif"; +} -var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif"; +/** + * @author mrdoob / http://mrdoob.com/ + */ -var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif"; +function WebGLAttributes( gl, capabilities ) { -var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + var isWebGL2 = capabilities.isWebGL2; -var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; + var buffers = new WeakMap(); -var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; + function createBuffer( attribute, bufferType ) { -var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}"; + var array = attribute.array; + var usage = attribute.usage; -var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}"; + var buffer = gl.createBuffer(); -var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + gl.bindBuffer( bufferType, buffer ); + gl.bufferData( bufferType, array, usage ); -var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; + attribute.onUploadCallback(); -var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}"; + var type = 5126; -var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + if ( array instanceof Float32Array ) { -var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; + type = 5126; -var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Float64Array ) { -var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; + console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); -var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Uint16Array ) { -var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + type = 5123; -var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Int16Array ) { -var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + type = 5122; -var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Uint32Array ) { -var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}"; + type = 5125; -var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Int32Array ) { -var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + type = 5124; -var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } else if ( array instanceof Int8Array ) { -var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; + type = 5120; -var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; + } else if ( array instanceof Uint8Array ) { -var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) ) || defined( USE_CLEARCOAT_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; + type = 5121; -var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + } -var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + return { + buffer: buffer, + type: type, + bytesPerElement: array.BYTES_PER_ELEMENT, + version: attribute.version + }; -var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}"; + } -var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + function updateBuffer( buffer, attribute, bufferType ) { -var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}"; + var array = attribute.array; + var updateRange = attribute.updateRange; -var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; + gl.bindBuffer( bufferType, buffer ); -var ShaderChunk = { - alphamap_fragment: alphamap_fragment, - alphamap_pars_fragment: alphamap_pars_fragment, - alphatest_fragment: alphatest_fragment, - aomap_fragment: aomap_fragment, - aomap_pars_fragment: aomap_pars_fragment, - begin_vertex: begin_vertex, - beginnormal_vertex: beginnormal_vertex, - bsdfs: bsdfs, - bumpmap_pars_fragment: bumpmap_pars_fragment, - clipping_planes_fragment: clipping_planes_fragment, - clipping_planes_pars_fragment: clipping_planes_pars_fragment, - clipping_planes_pars_vertex: clipping_planes_pars_vertex, - clipping_planes_vertex: clipping_planes_vertex, - color_fragment: color_fragment, - color_pars_fragment: color_pars_fragment, - color_pars_vertex: color_pars_vertex, - color_vertex: color_vertex, - common: common, - cube_uv_reflection_fragment: cube_uv_reflection_fragment, - defaultnormal_vertex: defaultnormal_vertex, - displacementmap_pars_vertex: displacementmap_pars_vertex, - displacementmap_vertex: displacementmap_vertex, - emissivemap_fragment: emissivemap_fragment, - emissivemap_pars_fragment: emissivemap_pars_fragment, - encodings_fragment: encodings_fragment, - encodings_pars_fragment: encodings_pars_fragment, - envmap_fragment: envmap_fragment, - envmap_pars_fragment: envmap_pars_fragment, - envmap_pars_vertex: envmap_pars_vertex, - envmap_physical_pars_fragment: envmap_physical_pars_fragment, - envmap_vertex: envmap_vertex, - fog_vertex: fog_vertex, - fog_pars_vertex: fog_pars_vertex, - fog_fragment: fog_fragment, - fog_pars_fragment: fog_pars_fragment, - gradientmap_pars_fragment: gradientmap_pars_fragment, - lightmap_fragment: lightmap_fragment, - lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, - lights_pars_begin: lights_pars_begin, - lights_phong_fragment: lights_phong_fragment, - lights_phong_pars_fragment: lights_phong_pars_fragment, - lights_physical_fragment: lights_physical_fragment, - lights_physical_pars_fragment: lights_physical_pars_fragment, - lights_fragment_begin: lights_fragment_begin, - lights_fragment_maps: lights_fragment_maps, - lights_fragment_end: lights_fragment_end, - logdepthbuf_fragment: logdepthbuf_fragment, - logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, - logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, - logdepthbuf_vertex: logdepthbuf_vertex, - map_fragment: map_fragment, - map_pars_fragment: map_pars_fragment, - map_particle_fragment: map_particle_fragment, - map_particle_pars_fragment: map_particle_pars_fragment, - metalnessmap_fragment: metalnessmap_fragment, - metalnessmap_pars_fragment: metalnessmap_pars_fragment, - morphnormal_vertex: morphnormal_vertex, - morphtarget_pars_vertex: morphtarget_pars_vertex, - morphtarget_vertex: morphtarget_vertex, - normal_fragment_begin: normal_fragment_begin, - normal_fragment_maps: normal_fragment_maps, - normalmap_pars_fragment: normalmap_pars_fragment, - clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, - clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, - clearcoat_normalmap_pars_fragment: clearcoat_normalmap_pars_fragment, - packing: packing, - premultiplied_alpha_fragment: premultiplied_alpha_fragment, - project_vertex: project_vertex, - dithering_fragment: dithering_fragment, - dithering_pars_fragment: dithering_pars_fragment, - roughnessmap_fragment: roughnessmap_fragment, - roughnessmap_pars_fragment: roughnessmap_pars_fragment, - shadowmap_pars_fragment: shadowmap_pars_fragment, - shadowmap_pars_vertex: shadowmap_pars_vertex, - shadowmap_vertex: shadowmap_vertex, - shadowmask_pars_fragment: shadowmask_pars_fragment, - skinbase_vertex: skinbase_vertex, - skinning_pars_vertex: skinning_pars_vertex, - skinning_vertex: skinning_vertex, - skinnormal_vertex: skinnormal_vertex, - specularmap_fragment: specularmap_fragment, - specularmap_pars_fragment: specularmap_pars_fragment, - tonemapping_fragment: tonemapping_fragment, - tonemapping_pars_fragment: tonemapping_pars_fragment, - uv_pars_fragment: uv_pars_fragment, - uv_pars_vertex: uv_pars_vertex, - uv_vertex: uv_vertex, - uv2_pars_fragment: uv2_pars_fragment, - uv2_pars_vertex: uv2_pars_vertex, - uv2_vertex: uv2_vertex, - worldpos_vertex: worldpos_vertex, + if ( updateRange.count === - 1 ) { - background_frag: background_frag, - background_vert: background_vert, - cube_frag: cube_frag, - cube_vert: cube_vert, - depth_frag: depth_frag, - depth_vert: depth_vert, - distanceRGBA_frag: distanceRGBA_frag, - distanceRGBA_vert: distanceRGBA_vert, - equirect_frag: equirect_frag, - equirect_vert: equirect_vert, - linedashed_frag: linedashed_frag, - linedashed_vert: linedashed_vert, - meshbasic_frag: meshbasic_frag, - meshbasic_vert: meshbasic_vert, - meshlambert_frag: meshlambert_frag, - meshlambert_vert: meshlambert_vert, - meshmatcap_frag: meshmatcap_frag, - meshmatcap_vert: meshmatcap_vert, - meshphong_frag: meshphong_frag, - meshphong_vert: meshphong_vert, - meshphysical_frag: meshphysical_frag, - meshphysical_vert: meshphysical_vert, - normal_frag: normal_frag, - normal_vert: normal_vert, - points_frag: points_frag, - points_vert: points_vert, - shadow_frag: shadow_frag, - shadow_vert: shadow_vert, - sprite_frag: sprite_frag, - sprite_vert: sprite_vert -}; + // Not using update ranges -/** - * Uniforms library for shared webgl shaders - */ + gl.bufferSubData( bufferType, 0, array ); -var UniformsLib = { + } else { - common: { + if ( isWebGL2 ) { - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array, updateRange.offset, updateRange.count ); - map: { value: null }, - uvTransform: { value: new Matrix3() }, + } else { - alphaMap: { value: null }, + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); - }, + } - specularmap: { + updateRange.count = - 1; // reset range - specularMap: { value: null }, + } - }, + } - envmap: { + // - envMap: { value: null }, - flipEnvMap: { value: - 1 }, - reflectivity: { value: 1.0 }, - refractionRatio: { value: 0.98 }, - maxMipLevel: { value: 0 } + function get( attribute ) { - }, + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - aomap: { + return buffers.get( attribute ); - aoMap: { value: null }, - aoMapIntensity: { value: 1 } + } - }, + function remove( attribute ) { - lightmap: { + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - lightMap: { value: null }, - lightMapIntensity: { value: 1 } + var data = buffers.get( attribute ); - }, + if ( data ) { - emissivemap: { + gl.deleteBuffer( data.buffer ); - emissiveMap: { value: null } + buffers.delete( attribute ); - }, + } - bumpmap: { + } - bumpMap: { value: null }, - bumpScale: { value: 1 } + function update( attribute, bufferType ) { - }, + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - normalmap: { + var data = buffers.get( attribute ); - normalMap: { value: null }, - normalScale: { value: new Vector2( 1, 1 ) } + if ( data === undefined ) { - }, + buffers.set( attribute, createBuffer( attribute, bufferType ) ); - displacementmap: { + } else if ( data.version < attribute.version ) { - displacementMap: { value: null }, - displacementScale: { value: 1 }, - displacementBias: { value: 0 } + updateBuffer( data.buffer, attribute, bufferType ); - }, + data.version = attribute.version; - roughnessmap: { + } - roughnessMap: { value: null } + } - }, + return { - metalnessmap: { + get: get, + remove: remove, + update: update - metalnessMap: { value: null } + }; - }, +} - gradientmap: { +/** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - gradientMap: { value: null } +// PlaneGeometry - }, +function PlaneGeometry( width, height, widthSegments, heightSegments ) { - fog: { + Geometry.call( this ); - fogDensity: { value: 0.00025 }, - fogNear: { value: 1 }, - fogFar: { value: 2000 }, - fogColor: { value: new Color( 0xffffff ) } + this.type = 'PlaneGeometry'; - }, + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - lights: { + this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); + this.mergeVertices(); - ambientLightColor: { value: [] }, +} - lightProbe: { value: [] }, +PlaneGeometry.prototype = Object.create( Geometry.prototype ); +PlaneGeometry.prototype.constructor = PlaneGeometry; - directionalLights: { value: [], properties: { - direction: {}, - color: {}, +// PlaneBufferGeometry - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, +function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { - directionalShadowMap: { value: [] }, - directionalShadowMatrix: { value: [] }, + BufferGeometry.call( this ); - spotLights: { value: [], properties: { - color: {}, - position: {}, - direction: {}, - distance: {}, - coneCos: {}, - penumbraCos: {}, - decay: {}, + this.type = 'PlaneBufferGeometry'; - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - spotShadowMap: { value: [] }, - spotShadowMatrix: { value: [] }, + width = width || 1; + height = height || 1; - pointLights: { value: [], properties: { - color: {}, - position: {}, - decay: {}, - distance: {}, + var width_half = width / 2; + var height_half = height / 2; - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {}, - shadowCameraNear: {}, - shadowCameraFar: {} - } }, + var gridX = Math.floor( widthSegments ) || 1; + var gridY = Math.floor( heightSegments ) || 1; - pointShadowMap: { value: [] }, - pointShadowMatrix: { value: [] }, + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; - hemisphereLights: { value: [], properties: { - direction: {}, - skyColor: {}, - groundColor: {} - } }, + var segment_width = width / gridX; + var segment_height = height / gridY; - // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src - rectAreaLights: { value: [], properties: { - color: {}, - position: {}, - width: {}, - height: {} - } } + var ix, iy; - }, + // buffers - points: { + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - size: { value: 1.0 }, - scale: { value: 1.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } + // generate vertices, normals and uvs - }, + for ( iy = 0; iy < gridY1; iy ++ ) { - sprite: { + var y = iy * segment_height - height_half; - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - center: { value: new Vector2( 0.5, 0.5 ) }, - rotation: { value: 0.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } + for ( ix = 0; ix < gridX1; ix ++ ) { + + var x = ix * segment_width - width_half; + + vertices.push( x, - y, 0 ); + + normals.push( 0, 0, 1 ); + + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); + + } } -}; + // indices -/** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - */ + for ( iy = 0; iy < gridY; iy ++ ) { -var ShaderLib = { + for ( ix = 0; ix < gridX; ix ++ ) { - basic: { + var a = ix + gridX1 * iy; + var b = ix + gridX1 * ( iy + 1 ); + var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = ( ix + 1 ) + gridX1 * iy; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.fog - ] ), + // faces - vertexShader: ShaderChunk.meshbasic_vert, - fragmentShader: ShaderChunk.meshbasic_frag + indices.push( a, b, d ); + indices.push( b, c, d ); - }, + } - lambert: { + } - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) } - } - ] ), + // build geometry - vertexShader: ShaderChunk.meshlambert_vert, - fragmentShader: ShaderChunk.meshlambert_frag + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - }, +} - phong: { +PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); +PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.gradientmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - specular: { value: new Color( 0x111111 ) }, - shininess: { value: 30 } - } - ] ), +var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; - vertexShader: ShaderChunk.meshphong_vert, - fragmentShader: ShaderChunk.meshphong_frag +var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - }, +var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; - standard: { +var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.roughnessmap, - UniformsLib.metalnessmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - roughness: { value: 0.5 }, - metalness: { value: 0.5 }, - envMapIntensity: { value: 1 } // temporary - } - ] ), +var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag +var begin_vertex = "vec3 transformed = vec3( position );"; - }, +var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; - matcap: { +var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.fog, - { - matcap: { value: null } - } - ] ), +var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; - vertexShader: ShaderChunk.meshmatcap_vert, - fragmentShader: ShaderChunk.meshmatcap_frag +var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; - }, +var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; - points: { +var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\tvarying vec3 vViewPosition;\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.points, - UniformsLib.fog - ] ), +var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP ) && ! defined( TOON )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; - vertexShader: ShaderChunk.points_vert, - fragmentShader: ShaderChunk.points_frag +var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; - }, +var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - dashed: { +var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.fog, - { - scale: { value: 1 }, - dashSize: { value: 1 }, - totalSize: { value: 2 } - } - ] ), +var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; - vertexShader: ShaderChunk.linedashed_vert, - fragmentShader: ShaderChunk.linedashed_frag +var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n return m[ 2 ][ 3 ] == - 1.0;\n}"; - }, +var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_maxMipLevel 8.0\n#define cubeUV_minMipLevel 4.0\n#define cubeUV_maxTileSize 256.0\n#define cubeUV_minTileSize 16.0\nfloat getFace(vec3 direction) {\n vec3 absDirection = abs(direction);\n float face = -1.0;\n if (absDirection.x > absDirection.z) {\n if (absDirection.x > absDirection.y)\n face = direction.x > 0.0 ? 0.0 : 3.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n } else {\n if (absDirection.z > absDirection.y)\n face = direction.z > 0.0 ? 2.0 : 5.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n }\n return face;\n}\nvec2 getUV(vec3 direction, float face) {\n vec2 uv;\n if (face == 0.0) {\n uv = vec2(-direction.z, direction.y) / abs(direction.x);\n } else if (face == 1.0) {\n uv = vec2(direction.x, -direction.z) / abs(direction.y);\n } else if (face == 2.0) {\n uv = direction.xy / abs(direction.z);\n } else if (face == 3.0) {\n uv = vec2(direction.z, direction.y) / abs(direction.x);\n } else if (face == 4.0) {\n uv = direction.xz / abs(direction.y);\n } else {\n uv = vec2(-direction.x, direction.y) / abs(direction.z);\n }\n return 0.5 * (uv + 1.0);\n}\nvec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n float face = getFace(direction);\n float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n mipInt = max(mipInt, cubeUV_minMipLevel);\n float faceSize = exp2(mipInt);\n float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n vec2 uv = getUV(direction, face) * (faceSize - 1.0);\n vec2 f = fract(uv);\n uv += 0.5 - f;\n if (face > 2.0) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize;\n if(mipInt < cubeUV_maxMipLevel){\n uv.y += 2.0 * cubeUV_maxTileSize;\n }\n uv.y += filterInt * 2.0 * cubeUV_minTileSize;\n uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n uv *= texelSize;\n vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x += texelSize;\n vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.y += texelSize;\n vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x -= texelSize;\n vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n vec3 tm = mix(tl, tr, f.x);\n vec3 bm = mix(bl, br, f.x);\n return mix(tm, bm, f.y);\n}\n#define r0 1.0\n#define v0 0.339\n#define m0 -2.0\n#define r1 0.8\n#define v1 0.276\n#define m1 -1.0\n#define r4 0.4\n#define v4 0.046\n#define m4 2.0\n#define r5 0.305\n#define v5 0.016\n#define m5 3.0\n#define r6 0.21\n#define v6 0.0038\n#define m6 4.0\nfloat roughnessToMip(float roughness) {\n float mip = 0.0;\n if (roughness >= r1) {\n mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n } else if (roughness >= r4) {\n mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n } else if (roughness >= r5) {\n mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n } else if (roughness >= r6) {\n mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n } else {\n mip = -2.0 * log2(1.16 * roughness); }\n return mip;\n}\nvec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {\n float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);\n float mipF = fract(mip);\n float mipInt = floor(mip);\n vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);\n if (mipF == 0.0) {\n return vec4(color0, 1.0);\n } else {\n vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);\n return vec4(mix(color0, color1, mipF), 1.0);\n }\n}\n#endif"; - depth: { +var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.displacementmap - ] ), +var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; - vertexShader: ShaderChunk.depth_vert, - fragmentShader: ShaderChunk.depth_frag +var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif"; - }, +var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; - normal: { +var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - { - opacity: { value: 1.0 } - } - ] ), +var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; - vertexShader: ShaderChunk.normal_vert, - fragmentShader: ShaderChunk.normal_frag +var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; - }, +var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\t\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; - sprite: { +var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.sprite, - UniformsLib.fog - ] ), +var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; - vertexShader: ShaderChunk.sprite_vert, - fragmentShader: ShaderChunk.sprite_frag +var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; - }, +var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) { \n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; - background: { +var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; - uniforms: { - uvTransform: { value: new Matrix3() }, - t2D: { value: null }, - }, +var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; - vertexShader: ShaderChunk.background_vert, - fragmentShader: ShaderChunk.background_frag +var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; - }, - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ +var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; - cube: { +var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}"; - uniforms: { - tCube: { value: null }, - tFlip: { value: - 1 }, - opacity: { value: 1.0 } - }, +var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif"; - vertexShader: ShaderChunk.cube_vert, - fragmentShader: ShaderChunk.cube_frag +var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; - }, +var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif"; - equirect: { +var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; - uniforms: { - tEquirect: { value: null }, - }, +var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; - vertexShader: ShaderChunk.equirect_vert, - fragmentShader: ShaderChunk.equirect_frag +var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; - }, +var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)"; - distanceRGBA: { +var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.displacementmap, - { - referencePosition: { value: new Vector3() }, - nearDistance: { value: 1 }, - farDistance: { value: 1000 } - } - ] ), +var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; - vertexShader: ShaderChunk.distanceRGBA_vert, - fragmentShader: ShaderChunk.distanceRGBA_frag +var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif"; - }, +var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; - shadow: { +var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif"; - uniforms: mergeUniforms( [ - UniformsLib.lights, - UniformsLib.fog, - { - color: { value: new Color( 0x00000 ) }, - opacity: { value: 1.0 } - }, - ] ), +var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif"; - vertexShader: ShaderChunk.shadow_vert, - fragmentShader: ShaderChunk.shadow_frag +var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif"; - } +var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; -}; +var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif"; -ShaderLib.physical = { +var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; - uniforms: mergeUniforms( [ - ShaderLib.standard.uniforms, - { - clearCoat: { value: 0 }, - clearCoatRoughness: { value: 0 }, - clearCoatNormalScale: { value: new Vector2( 1, 1 ) }, - clearCoatNormalMap: { value: null }, - } - ] ), +var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif"; - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag +var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; -}; +var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; -/** - * @author mrdoob / http://mrdoob.com/ - */ +var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif"; -function WebGLAnimation() { +var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - var context = null; - var isAnimating = false; - var animationLoop = null; +var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; - function onAnimationFrame( time, frame ) { +var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; - if ( isAnimating === false ) return; +var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif"; - animationLoop( time, frame ); +var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; - context.requestAnimationFrame( onAnimationFrame ); +var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; - } +var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;"; - return { +var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; - start: function () { +var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif"; - if ( isAnimating === true ) return; - if ( animationLoop === null ) return; +var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif"; - context.requestAnimationFrame( onAnimationFrame ); +var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif"; - isAnimating = true; +var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif"; - }, +var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; - stop: function () { +var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; - isAnimating = false; +var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;"; - }, +var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; - setAnimationLoop: function ( callback ) { +var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; - animationLoop = callback; +var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; - }, +var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; - setContext: function ( value ) { +var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; - context = value; +var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif"; - } +var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif"; - }; +var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}"; -} +var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; -/** - * @author mrdoob / http://mrdoob.com/ - */ +var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; -function WebGLAttributes( gl ) { +var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; - var buffers = new WeakMap(); +var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; - function createBuffer( attribute, bufferType ) { +var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; - var array = attribute.array; - var usage = attribute.dynamic ? 35048 : 35044; +var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; - var buffer = gl.createBuffer(); +var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; - gl.bindBuffer( bufferType, buffer ); - gl.bufferData( bufferType, array, usage ); +var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; - attribute.onUploadCallback(); +var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif"; - var type = 5126; +var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif"; - if ( array instanceof Float32Array ) { +var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; - type = 5126; +var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; - } else if ( array instanceof Float64Array ) { +var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif"; - console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); +var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif"; - } else if ( array instanceof Uint16Array ) { +var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif"; - type = 5123; +var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; - } else if ( array instanceof Int16Array ) { +var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; - type = 5122; +var cube_frag = "#include \nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include \n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; - } else if ( array instanceof Uint32Array ) { +var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}"; - type = 5125; +var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}"; - } else if ( array instanceof Int32Array ) { +var depth_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}"; - type = 5124; +var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; - } else if ( array instanceof Int8Array ) { +var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}"; - type = 5120; +var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; - } else if ( array instanceof Uint8Array ) { +var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; - type = 5121; +var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } +var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; - return { - buffer: buffer, - type: type, - bytesPerElement: array.BYTES_PER_ELEMENT, - version: attribute.version - }; +var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } +var meshbasic_vert = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - function updateBuffer( buffer, attribute, bufferType ) { +var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - var array = attribute.array; - var updateRange = attribute.updateRange; +var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - gl.bindBuffer( bufferType, buffer ); +var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - if ( attribute.dynamic === false ) { +var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}"; - gl.bufferData( bufferType, array, 35044 ); +var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } else if ( updateRange.count === - 1 ) { +var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; - // Not using update ranges +var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - gl.bufferSubData( bufferType, 0, array ); +var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } else if ( updateRange.count === 0 ) { +var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' ); +var meshphysical_vert = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}"; - } else { +var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; - gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, - array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); +var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; - updateRange.count = - 1; // reset range +var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } +var points_vert = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}"; - } +var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n\t#include \n\t#include \n}"; - // +var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; - function get( attribute ) { +var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}"; - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; +var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; - return buffers.get( attribute ); +var ShaderChunk = { + alphamap_fragment: alphamap_fragment, + alphamap_pars_fragment: alphamap_pars_fragment, + alphatest_fragment: alphatest_fragment, + aomap_fragment: aomap_fragment, + aomap_pars_fragment: aomap_pars_fragment, + begin_vertex: begin_vertex, + beginnormal_vertex: beginnormal_vertex, + bsdfs: bsdfs, + bumpmap_pars_fragment: bumpmap_pars_fragment, + clipping_planes_fragment: clipping_planes_fragment, + clipping_planes_pars_fragment: clipping_planes_pars_fragment, + clipping_planes_pars_vertex: clipping_planes_pars_vertex, + clipping_planes_vertex: clipping_planes_vertex, + color_fragment: color_fragment, + color_pars_fragment: color_pars_fragment, + color_pars_vertex: color_pars_vertex, + color_vertex: color_vertex, + common: common, + cube_uv_reflection_fragment: cube_uv_reflection_fragment, + defaultnormal_vertex: defaultnormal_vertex, + displacementmap_pars_vertex: displacementmap_pars_vertex, + displacementmap_vertex: displacementmap_vertex, + emissivemap_fragment: emissivemap_fragment, + emissivemap_pars_fragment: emissivemap_pars_fragment, + encodings_fragment: encodings_fragment, + encodings_pars_fragment: encodings_pars_fragment, + envmap_fragment: envmap_fragment, + envmap_common_pars_fragment: envmap_common_pars_fragment, + envmap_pars_fragment: envmap_pars_fragment, + envmap_pars_vertex: envmap_pars_vertex, + envmap_physical_pars_fragment: envmap_physical_pars_fragment, + envmap_vertex: envmap_vertex, + fog_vertex: fog_vertex, + fog_pars_vertex: fog_pars_vertex, + fog_fragment: fog_fragment, + fog_pars_fragment: fog_pars_fragment, + gradientmap_pars_fragment: gradientmap_pars_fragment, + lightmap_fragment: lightmap_fragment, + lightmap_pars_fragment: lightmap_pars_fragment, + lights_lambert_vertex: lights_lambert_vertex, + lights_pars_begin: lights_pars_begin, + lights_toon_fragment: lights_toon_fragment, + lights_toon_pars_fragment: lights_toon_pars_fragment, + lights_phong_fragment: lights_phong_fragment, + lights_phong_pars_fragment: lights_phong_pars_fragment, + lights_physical_fragment: lights_physical_fragment, + lights_physical_pars_fragment: lights_physical_pars_fragment, + lights_fragment_begin: lights_fragment_begin, + lights_fragment_maps: lights_fragment_maps, + lights_fragment_end: lights_fragment_end, + logdepthbuf_fragment: logdepthbuf_fragment, + logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, + logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, + logdepthbuf_vertex: logdepthbuf_vertex, + map_fragment: map_fragment, + map_pars_fragment: map_pars_fragment, + map_particle_fragment: map_particle_fragment, + map_particle_pars_fragment: map_particle_pars_fragment, + metalnessmap_fragment: metalnessmap_fragment, + metalnessmap_pars_fragment: metalnessmap_pars_fragment, + morphnormal_vertex: morphnormal_vertex, + morphtarget_pars_vertex: morphtarget_pars_vertex, + morphtarget_vertex: morphtarget_vertex, + normal_fragment_begin: normal_fragment_begin, + normal_fragment_maps: normal_fragment_maps, + normalmap_pars_fragment: normalmap_pars_fragment, + clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin, + clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps, + clearcoat_pars_fragment: clearcoat_pars_fragment, + packing: packing, + premultiplied_alpha_fragment: premultiplied_alpha_fragment, + project_vertex: project_vertex, + dithering_fragment: dithering_fragment, + dithering_pars_fragment: dithering_pars_fragment, + roughnessmap_fragment: roughnessmap_fragment, + roughnessmap_pars_fragment: roughnessmap_pars_fragment, + shadowmap_pars_fragment: shadowmap_pars_fragment, + shadowmap_pars_vertex: shadowmap_pars_vertex, + shadowmap_vertex: shadowmap_vertex, + shadowmask_pars_fragment: shadowmask_pars_fragment, + skinbase_vertex: skinbase_vertex, + skinning_pars_vertex: skinning_pars_vertex, + skinning_vertex: skinning_vertex, + skinnormal_vertex: skinnormal_vertex, + specularmap_fragment: specularmap_fragment, + specularmap_pars_fragment: specularmap_pars_fragment, + tonemapping_fragment: tonemapping_fragment, + tonemapping_pars_fragment: tonemapping_pars_fragment, + uv_pars_fragment: uv_pars_fragment, + uv_pars_vertex: uv_pars_vertex, + uv_vertex: uv_vertex, + uv2_pars_fragment: uv2_pars_fragment, + uv2_pars_vertex: uv2_pars_vertex, + uv2_vertex: uv2_vertex, + worldpos_vertex: worldpos_vertex, - } + background_frag: background_frag, + background_vert: background_vert, + cube_frag: cube_frag, + cube_vert: cube_vert, + depth_frag: depth_frag, + depth_vert: depth_vert, + distanceRGBA_frag: distanceRGBA_frag, + distanceRGBA_vert: distanceRGBA_vert, + equirect_frag: equirect_frag, + equirect_vert: equirect_vert, + linedashed_frag: linedashed_frag, + linedashed_vert: linedashed_vert, + meshbasic_frag: meshbasic_frag, + meshbasic_vert: meshbasic_vert, + meshlambert_frag: meshlambert_frag, + meshlambert_vert: meshlambert_vert, + meshmatcap_frag: meshmatcap_frag, + meshmatcap_vert: meshmatcap_vert, + meshtoon_frag: meshtoon_frag, + meshtoon_vert: meshtoon_vert, + meshphong_frag: meshphong_frag, + meshphong_vert: meshphong_vert, + meshphysical_frag: meshphysical_frag, + meshphysical_vert: meshphysical_vert, + normal_frag: normal_frag, + normal_vert: normal_vert, + points_frag: points_frag, + points_vert: points_vert, + shadow_frag: shadow_frag, + shadow_vert: shadow_vert, + sprite_frag: sprite_frag, + sprite_vert: sprite_vert +}; - function remove( attribute ) { +/** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + * @author mikael emtinger / http://gomo.se/ + */ - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; +var ShaderLib = { - var data = buffers.get( attribute ); + basic: { - if ( data ) { + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.fog + ] ), + + vertexShader: ShaderChunk.meshbasic_vert, + fragmentShader: ShaderChunk.meshbasic_frag + + }, + + lambert: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) } + } + ] ), + + vertexShader: ShaderChunk.meshlambert_vert, + fragmentShader: ShaderChunk.meshlambert_frag + + }, + + phong: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + specular: { value: new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), - gl.deleteBuffer( data.buffer ); + vertexShader: ShaderChunk.meshphong_vert, + fragmentShader: ShaderChunk.meshphong_frag - buffers.delete( attribute ); + }, - } + standard: { - } + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.roughnessmap, + UniformsLib.metalnessmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + roughness: { value: 0.5 }, + metalness: { value: 0.5 }, + envMapIntensity: { value: 1 } // temporary + } + ] ), - function update( attribute, bufferType ) { + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + }, - var data = buffers.get( attribute ); + toon: { - if ( data === undefined ) { + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.gradientmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + specular: { value: new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), - buffers.set( attribute, createBuffer( attribute, bufferType ) ); + vertexShader: ShaderChunk.meshtoon_vert, + fragmentShader: ShaderChunk.meshtoon_frag - } else if ( data.version < attribute.version ) { + }, - updateBuffer( data.buffer, attribute, bufferType ); + matcap: { - data.version = attribute.version; + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.fog, + { + matcap: { value: null } + } + ] ), - } + vertexShader: ShaderChunk.meshmatcap_vert, + fragmentShader: ShaderChunk.meshmatcap_frag - } + }, - return { + points: { - get: get, - remove: remove, - update: update + uniforms: mergeUniforms( [ + UniformsLib.points, + UniformsLib.fog + ] ), - }; + vertexShader: ShaderChunk.points_vert, + fragmentShader: ShaderChunk.points_frag -} + }, -/** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ + dashed: { -// PlaneGeometry + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.fog, + { + scale: { value: 1 }, + dashSize: { value: 1 }, + totalSize: { value: 2 } + } + ] ), -function PlaneGeometry( width, height, widthSegments, heightSegments ) { + vertexShader: ShaderChunk.linedashed_vert, + fragmentShader: ShaderChunk.linedashed_frag - Geometry.call( this ); + }, - this.type = 'PlaneGeometry'; + depth: { - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap + ] ), - this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); - this.mergeVertices(); + vertexShader: ShaderChunk.depth_vert, + fragmentShader: ShaderChunk.depth_frag -} + }, -PlaneGeometry.prototype = Object.create( Geometry.prototype ); -PlaneGeometry.prototype.constructor = PlaneGeometry; + normal: { -// PlaneBufferGeometry + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + { + opacity: { value: 1.0 } + } + ] ), -function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { + vertexShader: ShaderChunk.normal_vert, + fragmentShader: ShaderChunk.normal_frag - BufferGeometry.call( this ); + }, - this.type = 'PlaneBufferGeometry'; + sprite: { - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + uniforms: mergeUniforms( [ + UniformsLib.sprite, + UniformsLib.fog + ] ), - width = width || 1; - height = height || 1; + vertexShader: ShaderChunk.sprite_vert, + fragmentShader: ShaderChunk.sprite_frag - var width_half = width / 2; - var height_half = height / 2; + }, - var gridX = Math.floor( widthSegments ) || 1; - var gridY = Math.floor( heightSegments ) || 1; + background: { - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + uniforms: { + uvTransform: { value: new Matrix3() }, + t2D: { value: null }, + }, - var segment_width = width / gridX; - var segment_height = height / gridY; + vertexShader: ShaderChunk.background_vert, + fragmentShader: ShaderChunk.background_frag - var ix, iy; + }, + /* ------------------------------------------------------------------------- + // Cube map shader + ------------------------------------------------------------------------- */ - // buffers + cube: { - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + uniforms: mergeUniforms( [ + UniformsLib.envmap, + { + opacity: { value: 1.0 } + } + ] ), - // generate vertices, normals and uvs + vertexShader: ShaderChunk.cube_vert, + fragmentShader: ShaderChunk.cube_frag - for ( iy = 0; iy < gridY1; iy ++ ) { + }, - var y = iy * segment_height - height_half; + equirect: { - for ( ix = 0; ix < gridX1; ix ++ ) { + uniforms: { + tEquirect: { value: null }, + }, - var x = ix * segment_width - width_half; + vertexShader: ShaderChunk.equirect_vert, + fragmentShader: ShaderChunk.equirect_frag - vertices.push( x, - y, 0 ); + }, - normals.push( 0, 0, 1 ); + distanceRGBA: { - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + referencePosition: { value: new Vector3() }, + nearDistance: { value: 1 }, + farDistance: { value: 1000 } + } + ] ), - } + vertexShader: ShaderChunk.distanceRGBA_vert, + fragmentShader: ShaderChunk.distanceRGBA_frag - } + }, - // indices + shadow: { - for ( iy = 0; iy < gridY; iy ++ ) { + uniforms: mergeUniforms( [ + UniformsLib.lights, + UniformsLib.fog, + { + color: { value: new Color( 0x00000 ) }, + opacity: { value: 1.0 } + }, + ] ), - for ( ix = 0; ix < gridX; ix ++ ) { + vertexShader: ShaderChunk.shadow_vert, + fragmentShader: ShaderChunk.shadow_frag - var a = ix + gridX1 * iy; - var b = ix + gridX1 * ( iy + 1 ); - var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = ( ix + 1 ) + gridX1 * iy; + } - // faces +}; - indices.push( a, b, d ); - indices.push( b, c, d ); +ShaderLib.physical = { + uniforms: mergeUniforms( [ + ShaderLib.standard.uniforms, + { + clearcoat: { value: 0 }, + clearcoatMap: { value: null }, + clearcoatRoughness: { value: 0 }, + clearcoatRoughnessMap: { value: null }, + clearcoatNormalScale: { value: new Vector2( 1, 1 ) }, + clearcoatNormalMap: { value: null }, + sheen: { value: new Color( 0x000000 ) }, + transparency: { value: 0 }, } + ] ), - } - - // build geometry - - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - -} + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag -PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); -PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; +}; /** * @author mrdoob / http://mrdoob.com/ @@ -15156,10 +15442,10 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { var planeMesh; var boxMesh; - // Store the current background texture and its `version` - // so we can recompile the material accordingly. + var currentBackground = null; var currentBackgroundVersion = 0; + var currentTonemapping = null; function render( renderList, scene, camera, forceClear ) { @@ -15168,8 +15454,8 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { // Ignore background in AR // TODO: Reconsider this. - var vr = renderer.vr; - var session = vr.getSession && vr.getSession(); + var xr = renderer.xr; + var session = xr.getSession && xr.getSession(); if ( session && session.environmentBlendMode === 'additive' ) { @@ -15180,15 +15466,11 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { if ( background === null ) { setClear( clearColor, clearAlpha ); - currentBackground = null; - currentBackgroundVersion = 0; } else if ( background && background.isColor ) { setClear( background, 1 ); forceClear = true; - currentBackground = null; - currentBackgroundVersion = 0; } @@ -15198,7 +15480,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { } - if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) { + if ( background && ( background.isCubeTexture || background.isWebGLCubeRenderTarget || background.mapping === CubeUVReflectionMapping ) ) { if ( boxMesh === undefined ) { @@ -15216,8 +15498,8 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { } ) ); - boxMesh.geometry.removeAttribute( 'normal' ); - boxMesh.geometry.removeAttribute( 'uv' ); + boxMesh.geometry.deleteAttribute( 'normal' ); + boxMesh.geometry.deleteAttribute( 'uv' ); boxMesh.onBeforeRender = function ( renderer, scene, camera ) { @@ -15226,11 +15508,11 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { }; // enable code injection for non-built-in material - Object.defineProperty( boxMesh.material, 'map', { + Object.defineProperty( boxMesh.material, 'envMap', { get: function () { - return this.uniforms.tCube.value; + return this.uniforms.envMap.value; } @@ -15240,17 +15522,20 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { } - var texture = background.isWebGLRenderTargetCube ? background.texture : background; - boxMesh.material.uniforms.tCube.value = texture; - boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1; + var texture = background.isWebGLCubeRenderTarget ? background.texture : background; + + boxMesh.material.uniforms.envMap.value = texture; + boxMesh.material.uniforms.flipEnvMap.value = texture.isCubeTexture ? - 1 : 1; if ( currentBackground !== background || - currentBackgroundVersion !== texture.version ) { + currentBackgroundVersion !== texture.version || + currentTonemapping !== renderer.toneMapping ) { boxMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = texture.version; + currentTonemapping = renderer.toneMapping; } @@ -15275,7 +15560,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { } ) ); - planeMesh.geometry.removeAttribute( 'normal' ); + planeMesh.geometry.deleteAttribute( 'normal' ); // enable code injection for non-built-in material Object.defineProperty( planeMesh.material, 'map', { @@ -15303,12 +15588,14 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { planeMesh.material.uniforms.uvTransform.value.copy( background.matrix ); if ( currentBackground !== background || - currentBackgroundVersion !== background.version ) { + currentBackgroundVersion !== background.version || + currentTonemapping !== renderer.toneMapping ) { planeMesh.material.needsUpdate = true; currentBackground = background; currentBackgroundVersion = background.version; + currentTonemapping = renderer.toneMapping; } @@ -15363,6 +15650,8 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { function WebGLBufferRenderer( gl, extensions, info, capabilities ) { + var isWebGL2 = capabilities.isWebGL2; + var mode; function setMode( value ) { @@ -15379,17 +15668,21 @@ function WebGLBufferRenderer( gl, extensions, info, capabilities ) { } - function renderInstances( geometry, start, count ) { + function renderInstances( geometry, start, count, primcount ) { - var extension; + if ( primcount === 0 ) return; + + var extension, methodName; - if ( capabilities.isWebGL2 ) { + if ( isWebGL2 ) { extension = gl; + methodName = 'drawArraysInstanced'; } else { extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawArraysInstancedANGLE'; if ( extension === null ) { @@ -15400,9 +15693,9 @@ function WebGLBufferRenderer( gl, extensions, info, capabilities ) { } - extension[ capabilities.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount ); + extension[ methodName ]( mode, start, count, primcount ); - info.update( count, mode, geometry.maxInstancedCount ); + info.update( count, mode, primcount ); } @@ -15447,7 +15740,7 @@ function WebGLCapabilities( gl, extensions, parameters ) { if ( precision === 'highp' ) { if ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 && - gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) { + gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) { return 'highp'; @@ -15460,7 +15753,7 @@ function WebGLCapabilities( gl, extensions, parameters ) { if ( precision === 'mediump' ) { if ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 && - gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) { + gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) { return 'mediump'; @@ -15472,7 +15765,10 @@ function WebGLCapabilities( gl, extensions, parameters ) { } - var isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext; + /* eslint-disable no-undef */ + var isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) || + ( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext ); + /* eslint-enable no-undef */ var precision = parameters.precision !== undefined ? parameters.precision : 'highp'; var maxPrecision = getMaxPrecision( precision ); @@ -15684,6 +15980,7 @@ function WebGLClipping() { } scope.numPlanes = nPlanes; + scope.numIntersection = 0; return dstArray; @@ -15756,13 +16053,13 @@ function WebGLExtensions( gl ) { function WebGLGeometries( gl, attributes, info ) { - var geometries = {}; - var wireframeAttributes = {}; + var geometries = new WeakMap(); + var wireframeAttributes = new WeakMap(); function onGeometryDispose( event ) { var geometry = event.target; - var buffergeometry = geometries[ geometry.id ]; + var buffergeometry = geometries.get( geometry ); if ( buffergeometry.index !== null ) { @@ -15778,14 +16075,14 @@ function WebGLGeometries( gl, attributes, info ) { geometry.removeEventListener( 'dispose', onGeometryDispose ); - delete geometries[ geometry.id ]; + geometries.delete( geometry ); - var attribute = wireframeAttributes[ buffergeometry.id ]; + var attribute = wireframeAttributes.get( buffergeometry ); if ( attribute ) { attributes.remove( attribute ); - delete wireframeAttributes[ buffergeometry.id ]; + wireframeAttributes.delete( buffergeometry ); } @@ -15797,7 +16094,7 @@ function WebGLGeometries( gl, attributes, info ) { function get( object, geometry ) { - var buffergeometry = geometries[ geometry.id ]; + var buffergeometry = geometries.get( geometry ); if ( buffergeometry ) return buffergeometry; @@ -15819,7 +16116,7 @@ function WebGLGeometries( gl, attributes, info ) { } - geometries[ geometry.id ] = buffergeometry; + geometries.set( geometry, buffergeometry ); info.memory.geometries ++; @@ -15909,19 +16206,19 @@ function WebGLGeometries( gl, attributes, info ) { // - var previousAttribute = wireframeAttributes[ geometry.id ]; + var previousAttribute = wireframeAttributes.get( geometry ); if ( previousAttribute ) attributes.remove( previousAttribute ); // - wireframeAttributes[ geometry.id ] = attribute; + wireframeAttributes.set( geometry, attribute ); } function getWireframeAttribute( geometry ) { - var currentAttribute = wireframeAttributes[ geometry.id ]; + var currentAttribute = wireframeAttributes.get( geometry ); if ( currentAttribute ) { @@ -15945,7 +16242,7 @@ function WebGLGeometries( gl, attributes, info ) { } - return wireframeAttributes[ geometry.id ]; + return wireframeAttributes.get( geometry ); } @@ -15966,6 +16263,8 @@ function WebGLGeometries( gl, attributes, info ) { function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { + var isWebGL2 = capabilities.isWebGL2; + var mode; function setMode( value ) { @@ -15991,17 +16290,21 @@ function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { } - function renderInstances( geometry, start, count ) { + function renderInstances( geometry, start, count, primcount ) { - var extension; + if ( primcount === 0 ) return; + + var extension, methodName; - if ( capabilities.isWebGL2 ) { + if ( isWebGL2 ) { extension = gl; + methodName = 'drawElementsInstanced'; } else { - var extension = extensions.get( 'ANGLE_instanced_arrays' ); + extension = extensions.get( 'ANGLE_instanced_arrays' ); + methodName = 'drawElementsInstancedANGLE'; if ( extension === null ) { @@ -16012,9 +16315,9 @@ function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) { } - extension[ capabilities.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount ); + extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount ); - info.update( count, mode, geometry.maxInstancedCount ); + info.update( count, mode, primcount ); } @@ -16058,11 +16361,6 @@ function WebGLInfo( gl ) { render.triangles += instanceCount * ( count / 3 ); break; - case 5: - case 6: - render.triangles += instanceCount * ( count - 2 ); - break; - case 1: render.lines += instanceCount * ( count / 2 ); break; @@ -16127,7 +16425,10 @@ function WebGLMorphtargets( gl ) { var objectInfluences = object.morphTargetInfluences; - var length = objectInfluences.length; + // When object doesn't have morph target influences defined, we treat it as a 0-length array + // This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences + + var length = objectInfluences === undefined ? 0 : objectInfluences.length; var influences = influencesList[ geometry.id ]; @@ -16158,8 +16459,8 @@ function WebGLMorphtargets( gl ) { if ( influence[ 1 ] !== 0 ) { - if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i ); - if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i ); + if ( morphTargets ) geometry.deleteAttribute( 'morphTarget' + i ); + if ( morphNormals ) geometry.deleteAttribute( 'morphNormal' + i ); } @@ -16180,6 +16481,8 @@ function WebGLMorphtargets( gl ) { // Add morphAttributes + var morphInfluencesSum = 0; + for ( var i = 0; i < 8; i ++ ) { var influence = influences[ i ]; @@ -16191,10 +16494,11 @@ function WebGLMorphtargets( gl ) { if ( value ) { - if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] ); - if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] ); + if ( morphTargets ) geometry.setAttribute( 'morphTarget' + i, morphTargets[ index ] ); + if ( morphNormals ) geometry.setAttribute( 'morphNormal' + i, morphNormals[ index ] ); morphInfluences[ i ] = value; + morphInfluencesSum += value; continue; } @@ -16205,6 +16509,12 @@ function WebGLMorphtargets( gl ) { } + // GLSL shader uses formula baseinfluence * base + sum(target * influence) + // This allows us to switch between absolute morphs and relative morphs without changing shader code + // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence) + var morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; + + program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence ); program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences ); } @@ -16221,9 +16531,9 @@ function WebGLMorphtargets( gl ) { * @author mrdoob / http://mrdoob.com/ */ -function WebGLObjects( geometries, info ) { +function WebGLObjects( gl, geometries, attributes, info ) { - var updateList = {}; + var updateMap = new WeakMap(); function update( object ) { @@ -16234,7 +16544,7 @@ function WebGLObjects( geometries, info ) { // Update once per frame - if ( updateList[ buffergeometry.id ] !== frame ) { + if ( updateMap.get( buffergeometry ) !== frame ) { if ( geometry.isGeometry ) { @@ -16244,7 +16554,13 @@ function WebGLObjects( geometries, info ) { geometries.update( buffergeometry ); - updateList[ buffergeometry.id ] = frame; + updateMap.set( buffergeometry, frame ); + + } + + if ( object.isInstancedMesh ) { + + attributes.update( object.instanceMatrix, 34962 ); } @@ -16254,7 +16570,7 @@ function WebGLObjects( geometries, info ) { function dispose() { - updateList = {}; + updateMap = new WeakMap(); } @@ -16312,7 +16628,7 @@ function DataTexture2DArray( data, width, height, depth ) { Texture.call( this, null ); - this.image = { data: data, width: width, height: height, depth: depth }; + this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; @@ -16322,6 +16638,8 @@ function DataTexture2DArray( data, width, height, depth ) { this.generateMipmaps = false; this.flipY = false; + this.needsUpdate = true; + } DataTexture2DArray.prototype = Object.create( Texture.prototype ); @@ -16344,7 +16662,7 @@ function DataTexture3D( data, width, height, depth ) { Texture.call( this, null ); - this.image = { data: data, width: width, height: height, depth: depth }; + this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 }; this.magFilter = NearestFilter; this.minFilter = NearestFilter; @@ -16354,6 +16672,9 @@ function DataTexture3D( data, width, height, depth ) { this.generateMipmaps = false; this.flipY = false; + this.needsUpdate = true; + + } DataTexture3D.prototype = Object.create( Texture.prototype ); @@ -16822,6 +17143,20 @@ function setValueV4i( gl, v ) { } +// uint + +function setValueV1ui( gl, v ) { + + var cache = this.cache; + + if ( cache[ 0 ] === v ) return; + + gl.uniform1ui( this.addr, v ); + + cache[ 0 ] = v; + +} + // Helper to pick the right setter for the singular case function getSingularSetter( type ) { @@ -16837,16 +17172,37 @@ function getSingularSetter( type ) { case 0x8b5b: return setValueM3; // _MAT3 case 0x8b5c: return setValueM4; // _MAT4 - case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES - case 0x8b5f: return setValueT3D1; // SAMPLER_3D - case 0x8b60: return setValueT6; // SAMPLER_CUBE - case 0x8DC1: return setValueT2DArray1; // SAMPLER_2D_ARRAY - case 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2 case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3 case 0x8b55: case 0x8b59: return setValueV4i; // _VEC4 + case 0x1405: return setValueV1ui; // UINT + + case 0x8b5e: // SAMPLER_2D + case 0x8d66: // SAMPLER_EXTERNAL_OES + case 0x8dca: // INT_SAMPLER_2D + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + case 0x8b62: // SAMPLER_2D_SHADOW + return setValueT1; + + case 0x8b5f: // SAMPLER_3D + case 0x8dcb: // INT_SAMPLER_3D + case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D + return setValueT3D1; + + case 0x8b60: // SAMPLER_CUBE + case 0x8dcc: // INT_SAMPLER_CUBE + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + case 0x8dc5: // SAMPLER_CUBE_SHADOW + return setValueT6; + + case 0x8dc1: // SAMPLER_2D_ARRAY + case 0x8dcf: // INT_SAMPLER_2D_ARRAY + case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW + return setValueT2DArray1; + } } @@ -16985,14 +17341,24 @@ function getPureArraySetter( type ) { case 0x8b5b: return setValueM3Array; // _MAT3 case 0x8b5c: return setValueM4Array; // _MAT4 - case 0x8b5e: return setValueT1Array; // SAMPLER_2D - case 0x8b60: return setValueT6Array; // SAMPLER_CUBE - case 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2 case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3 case 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4 + case 0x8b5e: // SAMPLER_2D + case 0x8d66: // SAMPLER_EXTERNAL_OES + case 0x8dca: // INT_SAMPLER_2D + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + case 0x8b62: // SAMPLER_2D_SHADOW + return setValueT1Array; + + case 0x8b60: // SAMPLER_CUBE + case 0x8dcc: // INT_SAMPLER_CUBE + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + case 0x8dc5: // SAMPLER_CUBE_SHADOW + return setValueT6Array; + } } @@ -17329,15 +17695,13 @@ function getToneMappingFunction( functionName, toneMapping ) { } -function generateExtensions( extensions, parameters, rendererExtensions ) { - - extensions = extensions || {}; +function generateExtensions( parameters ) { var chunks = [ - ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || ( parameters.normalMap && ! parameters.objectSpaceNormalMap ) || parameters.clearCoatNormalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', - ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '', - ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '', - ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '' + ( parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '', + ( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', + ( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '', + ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : '' ]; return chunks.filter( filterEmptyLine ).join( '\n' ); @@ -17411,60 +17775,91 @@ function replaceClippingPlaneNums( string, parameters ) { } -function parseIncludes( string ) { +// Resolve Includes - var pattern = /^[ \t]*#include +<([\w\d./]+)>/gm; +var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; - function replace( match, include ) { +function resolveIncludes( string ) { - var replace = ShaderChunk[ include ]; + return string.replace( includePattern, includeReplacer ); - if ( replace === undefined ) { +} - throw new Error( 'Can not resolve #include <' + include + '>' ); +function includeReplacer( match, include ) { - } + var string = ShaderChunk[ include ]; - return parseIncludes( replace ); + if ( string === undefined ) { + + throw new Error( 'Can not resolve #include <' + include + '>' ); } - return string.replace( pattern, replace ); + return resolveIncludes( string ); } +// Unroll Loops + +var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; +var unrollLoopPattern = /#pragma unroll_loop_start[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g; + function unrollLoops( string ) { - var pattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; + return string + .replace( unrollLoopPattern, loopReplacer ) + .replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer ); + +} - function replace( match, start, end, snippet ) { +function deprecatedLoopReplacer( match, start, end, snippet ) { - var unroll = ''; + console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' ); + return loopReplacer( match, start, end, snippet ); - for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { +} - unroll += snippet - .replace( /\[ i \]/g, '[ ' + i + ' ]' ) - .replace( /UNROLLED_LOOP_INDEX/g, i ); +function loopReplacer( match, start, end, snippet ) { - } + var string = ''; - return unroll; + for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) { + + string += snippet + .replace( /\[ i \]/g, '[ ' + i + ' ]' ) + .replace( /UNROLLED_LOOP_INDEX/g, i ); } - return string.replace( pattern, replace ); + return string; } -function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) { +// + +function generatePrecision( parameters ) { - var gl = renderer.getContext(); + var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;"; + + if ( parameters.precision === "highp" ) { + + precisionstring += "\n#define HIGH_PRECISION"; + + } else if ( parameters.precision === "mediump" ) { + + precisionstring += "\n#define MEDIUM_PRECISION"; + + } else if ( parameters.precision === "lowp" ) { + + precisionstring += "\n#define LOW_PRECISION"; + + } - var defines = material.defines; + return precisionstring; - var vertexShader = shader.vertexShader; - var fragmentShader = shader.fragmentShader; +} + +function generateShadowMapTypeDefine( parameters ) { var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; @@ -17476,15 +17871,23 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; + } else if ( parameters.shadowMapType === VSMShadowMap ) { + + shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; + } + return shadowMapTypeDefine; + +} + +function generateEnvMapTypeDefine( parameters ) { + var envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; - var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; - var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; if ( parameters.envMap ) { - switch ( material.envMap.mapping ) { + switch ( parameters.envMapMode ) { case CubeReflectionMapping: case CubeRefractionMapping: @@ -17507,7 +17910,19 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, } - switch ( material.envMap.mapping ) { + } + + return envMapTypeDefine; + +} + +function generateEnvMapModeDefine( parameters ) { + + var envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; + + if ( parameters.envMap ) { + + switch ( parameters.envMapMode ) { case CubeRefractionMapping: case EquirectangularRefractionMapping: @@ -17516,7 +17931,19 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, } - switch ( material.combine ) { + } + + return envMapModeDefine; + +} + +function generateEnvMapBlendingDefine( parameters ) { + + var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; + + if ( parameters.envMap ) { + + switch ( parameters.combine ) { case MultiplyOperation: envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; @@ -17534,23 +17961,35 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, } - var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; + return envMapBlendingDefine; + +} - // console.log( 'building new program ' ); +function WebGLProgram( renderer, cacheKey, parameters ) { - // + var gl = renderer.getContext(); - var customExtensions = capabilities.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions ); + var defines = parameters.defines; - var customDefines = generateDefines( defines ); + var vertexShader = parameters.vertexShader; + var fragmentShader = parameters.fragmentShader; + var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters ); + var envMapTypeDefine = generateEnvMapTypeDefine( parameters ); + var envMapModeDefine = generateEnvMapModeDefine( parameters ); + var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters ); - // + + var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0; + + var customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters ); + + var customDefines = generateDefines( defines ); var program = gl.createProgram(); var prefixVertex, prefixFragment; - if ( material.isRawShaderMaterial ) { + if ( parameters.isRawShaderMaterial ) { prefixVertex = [ @@ -17581,20 +18020,20 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, prefixVertex = [ - 'precision ' + parameters.precision + ' float;', - 'precision ' + parameters.precision + ' int;', + generatePrecision( parameters ), - '#define SHADER_NAME ' + shader.name, + '#define SHADER_NAME ' + parameters.shaderName, customDefines, + parameters.instancing ? '#define USE_INSTANCING' : '', parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', '#define GAMMA_FACTOR ' + gammaFactorDefine, '#define MAX_BONES ' + parameters.maxBones, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', @@ -17605,7 +18044,11 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', - parameters.clearCoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', + ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', + + parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', + parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', @@ -17615,6 +18058,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexUvs ? '#define USE_UV' : '', + parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', @@ -17632,7 +18076,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', - parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', + ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', @@ -17640,6 +18084,13 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, 'uniform mat4 viewMatrix;', 'uniform mat3 normalMatrix;', 'uniform vec3 cameraPosition;', + 'uniform bool isOrthographic;', + + '#ifdef USE_INSTANCING', + + ' attribute mat4 instanceMatrix;', + + '#endif', 'attribute vec3 position;', 'attribute vec3 normal;', @@ -17697,10 +18148,9 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, customExtensions, - 'precision ' + parameters.precision + ' float;', - 'precision ' + parameters.precision + ' int;', + generatePrecision( parameters ), - '#define SHADER_NAME ' + shader.name, + '#define SHADER_NAME ' + parameters.shaderName, customDefines, @@ -17709,7 +18159,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, '#define GAMMA_FACTOR ' + gammaFactorDefine, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', - ( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '', + ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.matcap ? '#define USE_MATCAP' : '', @@ -17723,15 +18173,21 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '', - parameters.clearCoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', + ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '', + parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', + parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.sheen ? '#define USE_SHEEN' : '', + parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexUvs ? '#define USE_UV' : '', + parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', @@ -17748,12 +18204,13 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', - parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '', + ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '', - ( ( material.extensions ? material.extensions.shaderTextureLOD : false ) || parameters.envMap ) && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '', + ( ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ) ? '#define TEXTURE_LOD_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', + 'uniform bool isOrthographic;', ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '', ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below @@ -17761,15 +18218,16 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, parameters.dithering ? '#define DITHERING' : '', - ( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? + ( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding || parameters.lightMapEncoding ) ? ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '', parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', + parameters.lightMapEncoding ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '', parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '', - parameters.depthPacking ? '#define DEPTH_PACKING ' + material.depthPacking : '', + parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n' @@ -17777,24 +18235,24 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, } - vertexShader = parseIncludes( vertexShader ); + vertexShader = resolveIncludes( vertexShader ); vertexShader = replaceLightNums( vertexShader, parameters ); vertexShader = replaceClippingPlaneNums( vertexShader, parameters ); - fragmentShader = parseIncludes( fragmentShader ); + fragmentShader = resolveIncludes( fragmentShader ); fragmentShader = replaceLightNums( fragmentShader, parameters ); fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters ); vertexShader = unrollLoops( vertexShader ); fragmentShader = unrollLoops( fragmentShader ); - if ( capabilities.isWebGL2 && ! material.isRawShaderMaterial ) { + if ( parameters.isWebGL2 && ! parameters.isRawShaderMaterial ) { var isGLSL3ShaderMaterial = false; var versionRegex = /^\s*#version\s+300\s+es\s*\n/; - if ( material.isShaderMaterial && + if ( parameters.isShaderMaterial && vertexShader.match( versionRegex ) !== null && fragmentShader.match( versionRegex ) !== null ) { @@ -17806,6 +18264,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, } // GLSL 3.0 conversion + prefixVertex = [ '#version 300 es\n', '#define attribute in', @@ -17846,9 +18305,9 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, // Force a particular attribute to index 0. - if ( material.index0AttributeName !== undefined ) { + if ( parameters.index0AttributeName !== undefined ) { - gl.bindAttribLocation( program, 0, material.index0AttributeName ); + gl.bindAttribLocation( program, 0, parameters.index0AttributeName ); } else if ( parameters.morphTargets === true ) { @@ -17893,7 +18352,6 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, this.diagnostics = { runnable: runnable, - material: material, programLog: programLog, @@ -17919,6 +18377,9 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, // clean up + gl.detachShader( program, glVertexShader ); + gl.detachShader( program, glFragmentShader ); + gl.deleteShader( glVertexShader ); gl.deleteShader( glFragmentShader ); @@ -17965,9 +18426,9 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters, // - this.name = shader.name; + this.name = parameters.shaderName; this.id = programIdCount ++; - this.code = code; + this.cacheKey = cacheKey; this.usedTimes = 1; this.program = program; this.vertexShader = glVertexShader; @@ -17985,6 +18446,13 @@ function WebGLPrograms( renderer, extensions, capabilities ) { var programs = []; + var isWebGL2 = capabilities.isWebGL2; + var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; + var floatVertexTextures = capabilities.floatVertexTextures; + var precision = capabilities.precision; + var maxVertexUniforms = capabilities.maxVertexUniforms; + var vertexTextures = capabilities.vertexTextures; + var shaderIDs = { MeshDepthMaterial: 'depth', MeshDistanceMaterial: 'distanceRGBA', @@ -17992,7 +18460,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) { MeshBasicMaterial: 'basic', MeshLambertMaterial: 'lambert', MeshPhongMaterial: 'phong', - MeshToonMaterial: 'phong', + MeshToonMaterial: 'toon', MeshStandardMaterial: 'physical', MeshPhysicalMaterial: 'physical', MeshMatcapMaterial: 'matcap', @@ -18004,25 +18472,57 @@ function WebGLPrograms( renderer, extensions, capabilities ) { }; var parameterNames = [ - "precision", "supportsVertexTextures", "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", - "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "clearCoatNormalMap", "displacementMap", "specularMap", + "precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", + "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV", + "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap", "roughnessMap", "metalnessMap", "gradientMap", - "alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp", + "alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2", "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", "maxBones", "useVertexTexture", "morphTargets", "morphNormals", "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights", + "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows", "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', - "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering" + "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering", + "sheen" ]; + function getShaderObject( material, shaderID ) { + + var shaderobject; + + if ( shaderID ) { + + var shader = ShaderLib[ shaderID ]; + + shaderobject = { + name: material.type, + uniforms: UniformsUtils.clone( shader.uniforms ), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader + }; + + } else { + + shaderobject = { + name: material.type, + uniforms: material.uniforms, + vertexShader: material.vertexShader, + fragmentShader: material.fragmentShader + }; + + } + + return shaderobject; + + } function allocateBones( object ) { var skeleton = object.skeleton; var bones = skeleton.bones; - if ( capabilities.floatVertexTextures ) { + if ( floatVertexTextures ) { return 1024; @@ -18035,7 +18535,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) { // - limit here is ANGLE's 254 max uniform vectors // (up to 54 should be safe) - var nVertexUniforms = capabilities.maxVertexUniforms; + var nVertexUniforms = maxVertexUniforms; var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 ); var maxBones = Math.min( nVertexMatrices, bones.length ); @@ -18053,7 +18553,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) { } - function getTextureEncodingFromMap( map, gammaOverrideLinear ) { + function getTextureEncodingFromMap( map ) { var encoding; @@ -18072,18 +18572,16 @@ function WebGLPrograms( renderer, extensions, capabilities ) { } - // add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point. - if ( encoding === LinearEncoding && gammaOverrideLinear ) { - - encoding = GammaEncoding; - - } - return encoding; } - this.getParameters = function ( material, lights, shadows, fog, nClipPlanes, nClipIntersection, object ) { + this.getParameters = function ( material, lights, shadows, scene, nClipPlanes, nClipIntersection, object ) { + + var fog = scene.fog; + var environment = material.isMeshStandardMaterial ? scene.environment : null; + + var envMap = material.envMap || environment; var shaderID = shaderIDs[ material.type ]; @@ -18091,7 +18589,6 @@ function WebGLPrograms( renderer, extensions, capabilities ) { // (not to blow over maxLights budget) var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0; - var precision = capabilities.precision; if ( material.precision !== null ) { @@ -18105,31 +18602,52 @@ function WebGLPrograms( renderer, extensions, capabilities ) { } + var shaderobject = getShaderObject( material, shaderID ); + material.onBeforeCompile( shaderobject, renderer ); + var currentRenderTarget = renderer.getRenderTarget(); var parameters = { + isWebGL2: isWebGL2, + shaderID: shaderID, + shaderName: shaderobject.name, + + uniforms: shaderobject.uniforms, + vertexShader: shaderobject.vertexShader, + fragmentShader: shaderobject.fragmentShader, + defines: material.defines, + + isRawShaderMaterial: material.isRawShaderMaterial, + isShaderMaterial: material.isShaderMaterial, precision: precision, - supportsVertexTextures: capabilities.vertexTextures, - outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ), + + instancing: object.isInstancedMesh === true, + + supportsVertexTextures: vertexTextures, + outputEncoding: ( currentRenderTarget !== null ) ? getTextureEncodingFromMap( currentRenderTarget.texture ) : renderer.outputEncoding, map: !! material.map, - mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ), + mapEncoding: getTextureEncodingFromMap( material.map ), matcap: !! material.matcap, - matcapEncoding: getTextureEncodingFromMap( material.matcap, renderer.gammaInput ), - envMap: !! material.envMap, - envMapMode: material.envMap && material.envMap.mapping, - envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ), - envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ), + matcapEncoding: getTextureEncodingFromMap( material.matcap ), + envMap: !! envMap, + envMapMode: envMap && envMap.mapping, + envMapEncoding: getTextureEncodingFromMap( envMap ), + envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ), lightMap: !! material.lightMap, + lightMapEncoding: getTextureEncodingFromMap( material.lightMap ), aoMap: !! material.aoMap, emissiveMap: !! material.emissiveMap, - emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ), + emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ), bumpMap: !! material.bumpMap, normalMap: !! material.normalMap, objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap, - clearCoatNormalMap: !! material.clearCoatNormalMap, + tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap, + clearcoatMap: !! material.clearcoatMap, + clearcoatRoughnessMap: !! material.clearcoatRoughnessMap, + clearcoatNormalMap: !! material.clearcoatNormalMap, displacementMap: !! material.displacementMap, roughnessMap: !! material.roughnessMap, metalnessMap: !! material.metalnessMap, @@ -18138,24 +18656,27 @@ function WebGLPrograms( renderer, extensions, capabilities ) { gradientMap: !! material.gradientMap, + sheen: !! material.sheen, + combine: material.combine, vertexTangents: ( material.normalMap && material.vertexTangents ), vertexColors: material.vertexColors, - vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearCoatNormalMap, + vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap, + uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap ) && !! material.displacementMap, fog: !! fog, useFog: material.fog, - fogExp: ( fog && fog.isFogExp2 ), + fogExp2: ( fog && fog.isFogExp2 ), flatShading: material.flatShading, sizeAttenuation: material.sizeAttenuation, - logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer, + logarithmicDepthBuffer: logarithmicDepthBuffer, skinning: material.skinning && maxBones > 0, maxBones: maxBones, - useVertexTexture: capabilities.floatVertexTextures, + useVertexTexture: floatVertexTextures, morphTargets: material.morphTargets, morphNormals: material.morphNormals, @@ -18177,10 +18698,10 @@ function WebGLPrograms( renderer, extensions, capabilities ) { dithering: material.dithering, - shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && shadows.length > 0, + shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, shadowMapType: renderer.shadowMap.type, - toneMapping: renderer.toneMapping, + toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, physicallyCorrectLights: renderer.physicallyCorrectLights, premultipliedAlpha: material.premultipliedAlpha, @@ -18189,7 +18710,20 @@ function WebGLPrograms( renderer, extensions, capabilities ) { doubleSided: material.side === DoubleSide, flipSided: material.side === BackSide, - depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false + depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false, + + index0AttributeName: material.index0AttributeName, + + extensionDerivatives: material.extensions && material.extensions.derivatives, + extensionFragDepth: material.extensions && material.extensions.fragDepth, + extensionDrawbuffers: material.extensions && material.extensions.drawBuffers, + extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD, + + rendererExtensionFragDepth: isWebGL2 || extensions.get( 'EXT_frag_depth' ) !== null, + rendererExtensionDrawBuffers: isWebGL2 || extensions.get( 'WEBGL_draw_buffers' ) !== null, + rendererExtensionShaderTextureLod: isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) !== null, + + onBeforeCompile: material.onBeforeCompile }; @@ -18197,7 +18731,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) { }; - this.getProgramCode = function ( material, parameters ) { + this.getProgramCacheKey = function ( parameters ) { var array = []; @@ -18207,50 +18741,53 @@ function WebGLPrograms( renderer, extensions, capabilities ) { } else { - array.push( material.fragmentShader ); - array.push( material.vertexShader ); + array.push( parameters.fragmentShader ); + array.push( parameters.vertexShader ); } - if ( material.defines !== undefined ) { + if ( parameters.defines !== undefined ) { - for ( var name in material.defines ) { + for ( var name in parameters.defines ) { array.push( name ); - array.push( material.defines[ name ] ); + array.push( parameters.defines[ name ] ); } } - for ( var i = 0; i < parameterNames.length; i ++ ) { + if ( parameters.isRawShaderMaterial === undefined ) { - array.push( parameters[ parameterNames[ i ] ] ); + for ( var i = 0; i < parameterNames.length; i ++ ) { - } + array.push( parameters[ parameterNames[ i ] ] ); + + } - array.push( material.onBeforeCompile.toString() ); + array.push( renderer.outputEncoding ); + array.push( renderer.gammaFactor ); - array.push( renderer.gammaOutput ); + } - array.push( renderer.gammaFactor ); + array.push( parameters.onBeforeCompile.toString() ); return array.join(); }; - this.acquireProgram = function ( material, shader, parameters, code ) { + this.acquireProgram = function ( parameters, cacheKey ) { var program; // Check if code has been already compiled for ( var p = 0, pl = programs.length; p < pl; p ++ ) { - var programInfo = programs[ p ]; + var preexistingProgram = programs[ p ]; - if ( programInfo.code === code ) { + if ( preexistingProgram.cacheKey === cacheKey ) { - program = programInfo; + program = preexistingProgram; ++ program.usedTimes; break; @@ -18261,7 +18798,7 @@ function WebGLPrograms( renderer, extensions, capabilities ) { if ( program === undefined ) { - program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ); + program = new WebGLProgram( renderer, cacheKey, parameters ); programs.push( program ); } @@ -18473,10 +19010,31 @@ function WebGLRenderList() { } - function sort() { + function sort( customOpaqueSort, customTransparentSort ) { + + if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable ); + if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable ); + + } + + function finish() { + + // Clear references from inactive renderItems in the list + + for ( var i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) { + + var renderItem = renderItems[ i ]; - if ( opaque.length > 1 ) opaque.sort( painterSortStable ); - if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable ); + if ( renderItem.id === null ) break; + + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.program = null; + renderItem.group = null; + + } } @@ -18487,6 +19045,7 @@ function WebGLRenderList() { init: init, push: push, unshift: unshift, + finish: finish, sort: sort }; @@ -18495,7 +19054,7 @@ function WebGLRenderList() { function WebGLRenderLists() { - var lists = {}; + var lists = new WeakMap(); function onSceneDispose( event ) { @@ -18503,29 +19062,29 @@ function WebGLRenderLists() { scene.removeEventListener( 'dispose', onSceneDispose ); - delete lists[ scene.id ]; + lists.delete( scene ); } function get( scene, camera ) { - var cameras = lists[ scene.id ]; + var cameras = lists.get( scene ); var list; if ( cameras === undefined ) { list = new WebGLRenderList(); - lists[ scene.id ] = {}; - lists[ scene.id ][ camera.id ] = list; + lists.set( scene, new WeakMap() ); + lists.get( scene ).set( camera, list ); scene.addEventListener( 'dispose', onSceneDispose ); } else { - list = cameras[ camera.id ]; + list = cameras.get( camera ); if ( list === undefined ) { list = new WebGLRenderList(); - cameras[ camera.id ] = list; + cameras.set( camera, list ); } @@ -18537,7 +19096,7 @@ function WebGLRenderLists() { function dispose() { - lists = {}; + lists = new WeakMap(); } @@ -18573,12 +19132,7 @@ function UniformsCache() { case 'DirectionalLight': uniforms = { direction: new Vector3(), - color: new Color(), - - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() + color: new Color() }; break; @@ -18590,12 +19144,7 @@ function UniformsCache() { distance: 0, coneCos: 0, penumbraCos: 0, - decay: 0, - - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2() + decay: 0 }; break; @@ -18604,14 +19153,7 @@ function UniformsCache() { position: new Vector3(), color: new Color(), distance: 0, - decay: 0, - - shadow: false, - shadowBias: 0, - shadowRadius: 1, - shadowMapSize: new Vector2(), - shadowCameraNear: 1, - shadowCameraFar: 1000 + decay: 0 }; break; @@ -18629,7 +19171,6 @@ function UniformsCache() { position: new Vector3(), halfWidth: new Vector3(), halfHeight: new Vector3() - // TODO (abelnation): set RectAreaLight shadow uniforms }; break; @@ -18645,6 +19186,66 @@ function UniformsCache() { } +function ShadowUniformsCache() { + + var lights = {}; + + return { + + get: function ( light ) { + + if ( lights[ light.id ] !== undefined ) { + + return lights[ light.id ]; + + } + + var uniforms; + + switch ( light.type ) { + + case 'DirectionalLight': + uniforms = { + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; + + case 'SpotLight': + uniforms = { + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2() + }; + break; + + case 'PointLight': + uniforms = { + shadowBias: 0, + shadowRadius: 1, + shadowMapSize: new Vector2(), + shadowCameraNear: 1, + shadowCameraFar: 1000 + }; + break; + + // TODO (abelnation): set RectAreaLight shadow uniforms + + } + + lights[ light.id ] = uniforms; + + return uniforms; + + } + + }; + +} + + + var nextVersion = 0; function shadowCastingLightsFirst( lightA, lightB ) { @@ -18657,6 +19258,8 @@ function WebGLLights() { var cache = new UniformsCache(); + var shadowCache = ShadowUniformsCache(); + var state = { version: 0, @@ -18670,26 +19273,25 @@ function WebGLLights() { numDirectionalShadows: - 1, numPointShadows: - 1, - numSpotShadows: - 1, + numSpotShadows: - 1 }, ambient: [ 0, 0, 0 ], probe: [], directional: [], + directionalShadow: [], directionalShadowMap: [], directionalShadowMatrix: [], spot: [], + spotShadow: [], spotShadowMap: [], spotShadowMatrix: [], rectArea: [], point: [], + pointShadow: [], pointShadowMap: [], pointShadowMatrix: [], - hemi: [], - - numDirectionalShadows: - 1, - numPointShadows: - 1, - numSpotShadows: - 1 + hemi: [] }; @@ -18753,16 +19355,17 @@ function WebGLLights() { uniforms.direction.sub( vector3 ); uniforms.direction.transformDirection( viewMatrix ); - uniforms.shadow = light.castShadow; - if ( light.castShadow ) { var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; + var shadowUniforms = shadowCache.get( light ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + state.directionalShadow[ directionalLength ] = shadowUniforms; state.directionalShadowMap[ directionalLength ] = shadowMap; state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; @@ -18793,16 +19396,17 @@ function WebGLLights() { uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); uniforms.decay = light.decay; - uniforms.shadow = light.castShadow; - if ( light.castShadow ) { var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; + var shadowUniforms = shadowCache.get( light ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + state.spotShadow[ spotLength ] = shadowUniforms; state.spotShadowMap[ spotLength ] = shadowMap; state.spotShadowMatrix[ spotLength ] = light.shadow.matrix; @@ -18857,18 +19461,19 @@ function WebGLLights() { uniforms.distance = light.distance; uniforms.decay = light.decay; - uniforms.shadow = light.castShadow; - if ( light.castShadow ) { var shadow = light.shadow; - uniforms.shadowBias = shadow.bias; - uniforms.shadowRadius = shadow.radius; - uniforms.shadowMapSize = shadow.mapSize; - uniforms.shadowCameraNear = shadow.camera.near; - uniforms.shadowCameraFar = shadow.camera.far; + var shadowUniforms = shadowCache.get( light ); + + shadowUniforms.shadowBias = shadow.bias; + shadowUniforms.shadowRadius = shadow.radius; + shadowUniforms.shadowMapSize = shadow.mapSize; + shadowUniforms.shadowCameraNear = shadow.camera.near; + shadowUniforms.shadowCameraFar = shadow.camera.far; + state.pointShadow[ pointLength ] = shadowUniforms; state.pointShadowMap[ pointLength ] = shadowMap; state.pointShadowMatrix[ pointLength ] = light.shadow.matrix; @@ -18920,8 +19525,11 @@ function WebGLLights() { state.point.length = pointLength; state.hemi.length = hemiLength; + state.directionalShadow.length = numDirectionalShadows; state.directionalShadowMap.length = numDirectionalShadows; + state.pointShadow.length = numPointShadows; state.pointShadowMap.length = numPointShadows; + state.spotShadow.length = numSpotShadows; state.spotShadowMap.length = numSpotShadows; state.directionalShadowMatrix.length = numDirectionalShadows; state.pointShadowMatrix.length = numPointShadows; @@ -19006,7 +19614,7 @@ function WebGLRenderState() { function WebGLRenderStates() { - var renderStates = {}; + var renderStates = new WeakMap(); function onSceneDispose( event ) { @@ -19014,7 +19622,7 @@ function WebGLRenderStates() { scene.removeEventListener( 'dispose', onSceneDispose ); - delete renderStates[ scene.id ]; + renderStates.delete( scene ); } @@ -19022,24 +19630,24 @@ function WebGLRenderStates() { var renderState; - if ( renderStates[ scene.id ] === undefined ) { + if ( renderStates.has( scene ) === false ) { renderState = new WebGLRenderState(); - renderStates[ scene.id ] = {}; - renderStates[ scene.id ][ camera.id ] = renderState; + renderStates.set( scene, new WeakMap() ); + renderStates.get( scene ).set( camera, renderState ); scene.addEventListener( 'dispose', onSceneDispose ); } else { - if ( renderStates[ scene.id ][ camera.id ] === undefined ) { + if ( renderStates.get( scene ).has( camera ) === false ) { renderState = new WebGLRenderState(); - renderStates[ scene.id ][ camera.id ] = renderState; + renderStates.get( scene ).set( camera, renderState ); } else { - renderState = renderStates[ scene.id ][ camera.id ]; + renderState = renderStates.get( scene ).get( camera ); } @@ -19051,7 +19659,7 @@ function WebGLRenderStates() { function dispose() { - renderStates = {}; + renderStates = new WeakMap(); } @@ -19108,7 +19716,6 @@ function MeshDepthMaterial( parameters ) { this.wireframeLinewidth = 1; this.fog = false; - this.lights = false; this.setValues( parameters ); @@ -19188,7 +19795,6 @@ function MeshDistanceMaterial( parameters ) { this.displacementBias = 0; this.fog = false; - this.lights = false; this.setValues( parameters ); @@ -19222,6 +19828,10 @@ MeshDistanceMaterial.prototype.copy = function ( source ) { }; +var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include \nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = sqrt( squared_mean - mean * mean );\n gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}"; + +var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}"; + /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ @@ -19230,73 +19840,51 @@ MeshDistanceMaterial.prototype.copy = function ( source ) { function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { var _frustum = new Frustum(), - _projScreenMatrix = new Matrix4(), _shadowMapSize = new Vector2(), - _maxShadowMapSize = new Vector2( maxTextureSize, maxTextureSize ), - - _lookTarget = new Vector3(), - _lightPositionWorld = new Vector3(), - - _MorphingFlag = 1, - _SkinningFlag = 2, + _viewportSize = new Vector2(), - _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1, + _viewport = new Vector4(), - _depthMaterials = new Array( _NumberOfMaterialVariants ), - _distanceMaterials = new Array( _NumberOfMaterialVariants ), + _depthMaterials = [], + _distanceMaterials = [], _materialCache = {}; var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide }; - var cubeDirections = [ - new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), - new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) - ]; - - var cubeUps = [ - new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), - new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) - ]; - - var cube2DViewPorts = [ - new Vector4(), new Vector4(), new Vector4(), - new Vector4(), new Vector4(), new Vector4() - ]; - - // init - - for ( var i = 0; i !== _NumberOfMaterialVariants; ++ i ) { - - var useMorphing = ( i & _MorphingFlag ) !== 0; - var useSkinning = ( i & _SkinningFlag ) !== 0; + var shadowMaterialVertical = new ShaderMaterial( { - var depthMaterial = new MeshDepthMaterial( { - - depthPacking: RGBADepthPacking, - - morphTargets: useMorphing, - skinning: useSkinning - - } ); - - _depthMaterials[ i ] = depthMaterial; + defines: { + SAMPLE_RATE: 2.0 / 8.0, + HALF_SAMPLE_RATE: 1.0 / 8.0 + }, - // + uniforms: { + shadow_pass: { value: null }, + resolution: { value: new Vector2() }, + radius: { value: 4.0 } + }, - var distanceMaterial = new MeshDistanceMaterial( { + vertexShader: vsm_vert, - morphTargets: useMorphing, - skinning: useSkinning + fragmentShader: vsm_frag - } ); + } ); - _distanceMaterials[ i ] = distanceMaterial; + var shadowMaterialHorizonal = shadowMaterialVertical.clone(); + shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1; - } + var fullScreenTri = new BufferGeometry(); + fullScreenTri.setAttribute( + "position", + new BufferAttribute( + new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ), + 3 + ) + ); - // + var fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical ); var scope = this; @@ -19328,13 +19916,10 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { // render depth map - var faceCount; - for ( var i = 0, il = lights.length; i < il; i ++ ) { var light = lights[ i ]; var shadow = light.shadow; - var isPointLight = light && light.isPointLight; if ( shadow === undefined ) { @@ -19343,168 +19928,201 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { } - var shadowCamera = shadow.camera; - _shadowMapSize.copy( shadow.mapSize ); - _shadowMapSize.min( _maxShadowMapSize ); - if ( isPointLight ) { + var shadowFrameExtents = shadow.getFrameExtents(); - var vpWidth = _shadowMapSize.x; - var vpHeight = _shadowMapSize.y; + _shadowMapSize.multiply( shadowFrameExtents ); - // These viewports map a cube-map onto a 2D texture with the - // following orientation: - // - // xzXZ - // y Y - // - // X - Positive x direction - // x - Negative x direction - // Y - Positive y direction - // y - Negative y direction - // Z - Positive z direction - // z - Negative z direction - - // positive X - cube2DViewPorts[ 0 ].set( vpWidth * 2, vpHeight, vpWidth, vpHeight ); - // negative X - cube2DViewPorts[ 1 ].set( 0, vpHeight, vpWidth, vpHeight ); - // positive Z - cube2DViewPorts[ 2 ].set( vpWidth * 3, vpHeight, vpWidth, vpHeight ); - // negative Z - cube2DViewPorts[ 3 ].set( vpWidth, vpHeight, vpWidth, vpHeight ); - // positive Y - cube2DViewPorts[ 4 ].set( vpWidth * 3, 0, vpWidth, vpHeight ); - // negative Y - cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight ); - - _shadowMapSize.x *= 4.0; - _shadowMapSize.y *= 2.0; + _viewportSize.copy( shadow.mapSize ); + + if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) { + + console.warn( 'THREE.WebGLShadowMap:', light, 'has shadow exceeding max texture size, reducing' ); + + if ( _shadowMapSize.x > maxTextureSize ) { + + _viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x ); + _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; + shadow.mapSize.x = _viewportSize.x; + + } + + if ( _shadowMapSize.y > maxTextureSize ) { + + _viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y ); + _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; + shadow.mapSize.y = _viewportSize.y; + + } } - if ( shadow.map === null ) { + if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { - var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat }; shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); shadow.map.texture.name = light.name + ".shadowMap"; - shadowCamera.updateProjectionMatrix(); + shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + + shadow.camera.updateProjectionMatrix(); } - if ( shadow.isSpotLightShadow ) { + if ( shadow.map === null ) { - shadow.update( light ); + var pars = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat }; + + shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); + shadow.map.texture.name = light.name + ".shadowMap"; + + shadow.camera.updateProjectionMatrix(); } - var shadowMap = shadow.map; - var shadowMatrix = shadow.matrix; + _renderer.setRenderTarget( shadow.map ); + _renderer.clear(); - _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); - shadowCamera.position.copy( _lightPositionWorld ); + var viewportCount = shadow.getViewportCount(); - if ( isPointLight ) { + for ( var vp = 0; vp < viewportCount; vp ++ ) { - faceCount = 6; + var viewport = shadow.getViewport( vp ); - // for point lights we set the shadow matrix to be a translation-only matrix - // equal to inverse of the light's position + _viewport.set( + _viewportSize.x * viewport.x, + _viewportSize.y * viewport.y, + _viewportSize.x * viewport.z, + _viewportSize.y * viewport.w + ); - shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z ); + _state.viewport( _viewport ); - } else { + shadow.updateMatrices( light, vp ); - faceCount = 1; + _frustum = shadow.getFrustum(); - _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + renderObject( scene, camera, shadow.camera, light, this.type ); - // compute shadow matrix + } - shadowMatrix.set( - 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 0.5, 0.5, - 0.0, 0.0, 0.0, 1.0 - ); + // do blur pass for VSM + + if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) { - shadowMatrix.multiply( shadowCamera.projectionMatrix ); - shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + VSMPass( shadow, camera ); } - _renderer.setRenderTarget( shadowMap ); - _renderer.clear(); + } - // render shadow map for each cube face (if omni-directional) or - // run a single pass if not + scope.needsUpdate = false; - for ( var face = 0; face < faceCount; face ++ ) { + _renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel ); - if ( isPointLight ) { + }; - _lookTarget.copy( shadowCamera.position ); - _lookTarget.add( cubeDirections[ face ] ); - shadowCamera.up.copy( cubeUps[ face ] ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + function VSMPass( shadow, camera ) { - var vpDimensions = cube2DViewPorts[ face ]; - _state.viewport( vpDimensions ); + var geometry = _objects.update( fullScreenMesh ); - } + // vertical pass - // update camera matrices and frustum + shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture; + shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize; + shadowMaterialVertical.uniforms.radius.value = shadow.radius; + _renderer.setRenderTarget( shadow.mapPass ); + _renderer.clear(); + _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null ); - _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); + // horizonal pass - // set object matrices & frustum culling + shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture; + shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize; + shadowMaterialHorizonal.uniforms.radius.value = shadow.radius; + _renderer.setRenderTarget( shadow.map ); + _renderer.clear(); + _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null ); - renderObject( scene, camera, shadowCamera, isPointLight ); + } - } + function getDepthMaterialVariant( useMorphing, useSkinning, useInstancing ) { + + var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; + + var material = _depthMaterials[ index ]; + + if ( material === undefined ) { + + material = new MeshDepthMaterial( { + + depthPacking: RGBADepthPacking, + + morphTargets: useMorphing, + skinning: useSkinning + + } ); + + _depthMaterials[ index ] = material; } - scope.needsUpdate = false; + return material; - _renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel ); + } - }; + function getDistanceMaterialVariant( useMorphing, useSkinning, useInstancing ) { + + var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2; + + var material = _distanceMaterials[ index ]; + + if ( material === undefined ) { + + material = new MeshDistanceMaterial( { + + morphTargets: useMorphing, + skinning: useSkinning + + } ); + + _distanceMaterials[ index ] = material; - function getDepthMaterial( object, material, isPointLight, lightPositionWorld, shadowCameraNear, shadowCameraFar ) { + } + + return material; + + } + + function getDepthMaterial( object, material, light, shadowCameraNear, shadowCameraFar, type ) { var geometry = object.geometry; var result = null; - var materialVariants = _depthMaterials; + var getMaterialVariant = getDepthMaterialVariant; var customMaterial = object.customDepthMaterial; - if ( isPointLight ) { + if ( light.isPointLight === true ) { - materialVariants = _distanceMaterials; + getMaterialVariant = getDistanceMaterialVariant; customMaterial = object.customDistanceMaterial; } - if ( ! customMaterial ) { + if ( customMaterial === undefined ) { var useMorphing = false; - if ( material.morphTargets ) { + if ( material.morphTargets === true ) { - if ( geometry && geometry.isBufferGeometry ) { + if ( geometry.isBufferGeometry === true ) { useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0; - } else if ( geometry && geometry.isGeometry ) { + } else if ( geometry.isGeometry === true ) { useMorphing = geometry.morphTargets && geometry.morphTargets.length > 0; @@ -19512,20 +20130,25 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { } - if ( object.isSkinnedMesh && material.skinning === false ) { + var useSkinning = false; - console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); + if ( object.isSkinnedMesh === true ) { - } + if ( material.skinning === true ) { - var useSkinning = object.isSkinnedMesh && material.skinning; + useSkinning = true; - var variantIndex = 0; + } else { + + console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object ); - if ( useMorphing ) variantIndex |= _MorphingFlag; - if ( useSkinning ) variantIndex |= _SkinningFlag; + } + + } - result = materialVariants[ variantIndex ]; + var useInstancing = object.isInstancedMesh === true; + + result = getMaterialVariant( useMorphing, useSkinning, useInstancing ); } else { @@ -19567,7 +20190,15 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { result.visible = material.visible; result.wireframe = material.wireframe; - result.side = ( material.shadowSide != null ) ? material.shadowSide : shadowSide[ material.side ]; + if ( type === VSMShadowMap ) { + + result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side; + + } else { + + result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ]; + + } result.clipShadows = material.clipShadows; result.clippingPlanes = material.clippingPlanes; @@ -19576,9 +20207,9 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { result.wireframeLinewidth = material.wireframeLinewidth; result.linewidth = material.linewidth; - if ( isPointLight && result.isMeshDistanceMaterial ) { + if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) { - result.referencePosition.copy( lightPositionWorld ); + result.referencePosition.setFromMatrixPosition( light.matrixWorld ); result.nearDistance = shadowCameraNear; result.farDistance = shadowCameraFar; @@ -19588,7 +20219,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { } - function renderObject( object, camera, shadowCamera, isPointLight ) { + function renderObject( object, camera, shadowCamera, light, type ) { if ( object.visible === false ) return; @@ -19596,7 +20227,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) { - if ( object.castShadow && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { + if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) { object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld ); @@ -19614,7 +20245,8 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { if ( groupMaterial && groupMaterial.visible ) { - var depthMaterial = getDepthMaterial( object, groupMaterial, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + var depthMaterial = getDepthMaterial( object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group ); } @@ -19623,7 +20255,8 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { } else if ( material.visible ) { - var depthMaterial = getDepthMaterial( object, material, isPointLight, _lightPositionWorld, shadowCamera.near, shadowCamera.far ); + var depthMaterial = getDepthMaterial( object, material, light, shadowCamera.near, shadowCamera.far, type ); + _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null ); } @@ -19636,7 +20269,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { for ( var i = 0, l = children.length; i < l; i ++ ) { - renderObject( children[ i ], camera, shadowCamera, isPointLight ); + renderObject( children[ i ], camera, shadowCamera, light, type ); } @@ -19648,7 +20281,9 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { * @author mrdoob / http://mrdoob.com/ */ -function WebGLState( gl, extensions, utils, capabilities ) { +function WebGLState( gl, extensions, capabilities ) { + + var isWebGL2 = capabilities.isWebGL2; function ColorBuffer() { @@ -19966,8 +20601,6 @@ function WebGLState( gl, extensions, utils, capabilities ) { var enabledCapabilities = {}; - var compressedTextureFormats = null; - var currentProgram = null; var currentBlendingEnabled = null; @@ -20081,9 +20714,9 @@ function WebGLState( gl, extensions, utils, capabilities ) { if ( attributeDivisors[ attribute ] !== meshPerAttribute ) { - var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); + var extension = isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' ); - extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); + extension[ isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute ); attributeDivisors[ attribute ] = meshPerAttribute; } @@ -20127,49 +20760,60 @@ function WebGLState( gl, extensions, utils, capabilities ) { } - function getCompressedTextureFormats() { - - if ( compressedTextureFormats === null ) { - - compressedTextureFormats = []; - - if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || - extensions.get( 'WEBGL_compressed_texture_s3tc' ) || - extensions.get( 'WEBGL_compressed_texture_etc1' ) || - extensions.get( 'WEBGL_compressed_texture_astc' ) ) { - - var formats = gl.getParameter( 34467 ); + function useProgram( program ) { - for ( var i = 0; i < formats.length; i ++ ) { + if ( currentProgram !== program ) { - compressedTextureFormats.push( formats[ i ] ); + gl.useProgram( program ); - } + currentProgram = program; - } + return true; } - return compressedTextureFormats; + return false; } - function useProgram( program ) { + var equationToGL = { + [ AddEquation ]: 32774, + [ SubtractEquation ]: 32778, + [ ReverseSubtractEquation ]: 32779 + }; - if ( currentProgram !== program ) { + if ( isWebGL2 ) { - gl.useProgram( program ); + equationToGL[ MinEquation ] = 32775; + equationToGL[ MaxEquation ] = 32776; - currentProgram = program; + } else { - return true; + var extension = extensions.get( 'EXT_blend_minmax' ); - } + if ( extension !== null ) { - return false; + equationToGL[ MinEquation ] = extension.MIN_EXT; + equationToGL[ MaxEquation ] = extension.MAX_EXT; + + } } + var factorToGL = { + [ ZeroFactor ]: 0, + [ OneFactor ]: 1, + [ SrcColorFactor ]: 768, + [ SrcAlphaFactor ]: 770, + [ SrcAlphaSaturateFactor ]: 776, + [ DstColorFactor ]: 774, + [ DstAlphaFactor ]: 772, + [ OneMinusSrcColorFactor ]: 769, + [ OneMinusSrcAlphaFactor ]: 771, + [ OneMinusDstColorFactor ]: 775, + [ OneMinusDstAlphaFactor ]: 773 + }; + function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { if ( blending === NoBlending ) { @@ -20281,7 +20925,7 @@ function WebGLState( gl, extensions, utils, capabilities ) { if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) { - gl.blendEquationSeparate( utils.convert( blendEquation ), utils.convert( blendEquationAlpha ) ); + gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] ); currentBlendEquation = blendEquation; currentBlendEquationAlpha = blendEquationAlpha; @@ -20290,7 +20934,7 @@ function WebGLState( gl, extensions, utils, capabilities ) { if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) { - gl.blendFuncSeparate( utils.convert( blendSrc ), utils.convert( blendDst ), utils.convert( blendSrcAlpha ), utils.convert( blendDstAlpha ) ); + gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] ); currentBlendSrc = blendSrc; currentBlendDst = blendDst; @@ -20328,7 +20972,8 @@ function WebGLState( gl, extensions, utils, capabilities ) { stencilBuffer.setTest( stencilWrite ); if ( stencilWrite ) { - stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilMask ); + stencilBuffer.setMask( material.stencilWriteMask ); + stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask ); stencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass ); } @@ -20485,6 +21130,21 @@ function WebGLState( gl, extensions, utils, capabilities ) { } + function unbindTexture() { + + var boundTexture = currentBoundTextures[ currentTextureSlot ]; + + if ( boundTexture !== undefined && boundTexture.type !== undefined ) { + + gl.bindTexture( boundTexture.type, null ); + + boundTexture.type = undefined; + boundTexture.texture = undefined; + + } + + } + function compressedTexImage2D() { try { @@ -20568,8 +21228,6 @@ function WebGLState( gl, extensions, utils, capabilities ) { enabledCapabilities = {}; - compressedTextureFormats = null; - currentTextureSlot = null; currentBoundTextures = {}; @@ -20600,7 +21258,6 @@ function WebGLState( gl, extensions, utils, capabilities ) { disableUnusedAttributes: disableUnusedAttributes, enable: enable, disable: disable, - getCompressedTextureFormats: getCompressedTextureFormats, useProgram: useProgram, @@ -20617,6 +21274,7 @@ function WebGLState( gl, extensions, utils, capabilities ) { activeTexture: activeTexture, bindTexture: bindTexture, + unbindTexture: unbindTexture, compressedTexImage2D: compressedTexImage2D, texImage2D: texImage2D, texImage3D: texImage3D, @@ -20636,12 +21294,31 @@ function WebGLState( gl, extensions, utils, capabilities ) { function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { - var _videoTextures = {}; + var isWebGL2 = capabilities.isWebGL2; + var maxTextures = capabilities.maxTextures; + var maxCubemapSize = capabilities.maxCubemapSize; + var maxTextureSize = capabilities.maxTextureSize; + var maxSamples = capabilities.maxSamples; + + var _videoTextures = new WeakMap(); var _canvas; - // + // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas, + // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")! + // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d). + + var useOffscreenCanvas = false; + + try { - var useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'; + useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' + && ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null; + + } catch ( err ) { + + // Ignore any errors + + } function createCanvas( width, height ) { @@ -20675,7 +21352,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) || ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) { - var floor = needsPowerOfTwo ? _Math.floorPowerOfTwo : Math.floor; + var floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor; var width = floor( scale * image.width ); var height = floor( scale * image.height ); @@ -20716,13 +21393,13 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, function isPowerOfTwo( image ) { - return _Math.isPowerOfTwo( image.width ) && _Math.isPowerOfTwo( image.height ); + return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height ); } function textureNeedsPowerOfTwo( texture ) { - if ( capabilities.isWebGL2 ) return false; + if ( isWebGL2 ) return false; return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) || ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ); @@ -20747,9 +21424,17 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - function getInternalFormat( glFormat, glType ) { + function getInternalFormat( internalFormatName, glFormat, glType ) { - if ( ! capabilities.isWebGL2 ) return glFormat; + if ( isWebGL2 === false ) return glFormat; + + if ( internalFormatName !== null ) { + + if ( _gl[ internalFormatName ] !== undefined ) return _gl[ internalFormatName ]; + + console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' ); + + } var internalFormat = glFormat; @@ -20818,7 +21503,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( texture.isVideoTexture ) { - delete _videoTextures[ texture.id ]; + _videoTextures.delete( texture ); } @@ -20871,7 +21556,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - if ( renderTarget.isWebGLRenderTargetCube ) { + if ( renderTarget.isWebGLCubeRenderTarget ) { for ( var i = 0; i < 6; i ++ ) { @@ -20906,9 +21591,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, var textureUnit = textureUnits; - if ( textureUnit >= capabilities.maxTextures ) { + if ( textureUnit >= maxTextures ) { - console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); + console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures ); } @@ -20986,104 +21671,110 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, function setTextureCube( texture, slot ) { + if ( texture.image.length !== 6 ) return; + var textureProperties = properties.get( texture ); - if ( texture.image.length === 6 ) { + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { - if ( texture.version > 0 && textureProperties.__version !== texture.version ) { + initTexture( textureProperties, texture ); - initTexture( textureProperties, texture ); + state.activeTexture( 33984 + slot ); + state.bindTexture( 34067, textureProperties.__webglTexture ); - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + _gl.pixelStorei( 37440, texture.flipY ); - _gl.pixelStorei( 37440, texture.flipY ); + var isCompressed = ( texture && ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ) ); + var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); - var isCompressed = ( texture && texture.isCompressedTexture ); - var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture ); + var cubeImage = []; - var cubeImage = []; + for ( var i = 0; i < 6; i ++ ) { - for ( var i = 0; i < 6; i ++ ) { + if ( ! isCompressed && ! isDataTexture ) { - if ( ! isCompressed && ! isDataTexture ) { + cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize ); - cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, capabilities.maxCubemapSize ); + } else { - } else { + cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; - cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ]; + } - } + } - } + var image = cubeImage[ 0 ], + supportsMips = isPowerOfTwo( image ) || isWebGL2, + glFormat = utils.convert( texture.format ), + glType = utils.convert( texture.type ), + glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType ); - var image = cubeImage[ 0 ], - supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2, - glFormat = utils.convert( texture.format ), - glType = utils.convert( texture.type ), - glInternalFormat = getInternalFormat( glFormat, glType ); + setTextureParameters( 34067, texture, supportsMips ); - setTextureParameters( 34067, texture, supportsMips ); + var mipmaps; - var mipmaps = texture.mipmaps; + if ( isCompressed ) { for ( var i = 0; i < 6; i ++ ) { - if ( ! isCompressed ) { + mipmaps = cubeImage[ i ].mipmaps; - if ( isDataTexture ) { + for ( var j = 0; j < mipmaps.length; j ++ ) { - state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); + var mipmap = mipmaps[ j ]; - for ( var j = 0; j < mipmaps.length; ++ j ) { + if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { - var mipmap = mipmaps[ j ]; - var image = mipmap.image[ i ].image; + if ( glFormat !== null ) { - state.texImage2D( 34069 + i, j + 1, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data ); + state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + + } else { + + console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); } } else { - state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); + state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); - for ( var j = 0; j < mipmaps.length; ++ j ) { + } - var mipmap = mipmaps[ j ]; + } - state.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); + } - } + textureProperties.__maxMipLevel = mipmaps.length - 1; - } + } else { - } else { + mipmaps = texture.mipmaps; - var mipmaps = cubeImage[ i ].mipmaps; + for ( var i = 0; i < 6; i ++ ) { - for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) { + if ( isDataTexture ) { - var mipmap = mipmaps[ j ]; + state.texImage2D( 34069 + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data ); - if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { + for ( var j = 0; j < mipmaps.length; j ++ ) { - if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { + var mipmap = mipmaps[ j ]; + var mipmapImage = mipmap.image[ i ].image; - state.compressedTexImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + state.texImage2D( 34069 + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data ); - } else { + } - console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' ); + } else { - } + state.texImage2D( 34069 + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] ); - } else { + for ( var j = 0; j < mipmaps.length; j ++ ) { - state.texImage2D( 34069 + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + var mipmap = mipmaps[ j ]; - } + state.texImage2D( 34069 + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[ i ] ); } @@ -21091,25 +21782,25 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - textureProperties.__maxMipLevel = isCompressed ? mipmaps.length - 1 : mipmaps.length; + textureProperties.__maxMipLevel = mipmaps.length; - if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { + } - // We assume images for cube map have the same size. - generateMipmap( 34067, texture, image.width, image.height ); + if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - } + // We assume images for cube map have the same size. + generateMipmap( 34067, texture, image.width, image.height ); - textureProperties.__version = texture.version; + } - if ( texture.onUpdate ) texture.onUpdate( texture ); + textureProperties.__version = texture.version; - } else { + if ( texture.onUpdate ) texture.onUpdate( texture ); - state.activeTexture( 33984 + slot ); - state.bindTexture( 34067, textureProperties.__webglTexture ); + } else { - } + state.activeTexture( 33984 + slot ); + state.bindTexture( 34067, textureProperties.__webglTexture ); } @@ -21122,23 +21813,37 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - function setTextureParameters( textureType, texture, supportsMips ) { + var wrappingToGL = { + [ RepeatWrapping ]: 10497, + [ ClampToEdgeWrapping ]: 33071, + [ MirroredRepeatWrapping ]: 33648 + }; - var extension; + var filterToGL = { + [ NearestFilter ]: 9728, + [ NearestMipmapNearestFilter ]: 9984, + [ NearestMipmapLinearFilter ]: 9986, + + [ LinearFilter ]: 9729, + [ LinearMipmapNearestFilter ]: 9985, + [ LinearMipmapLinearFilter ]: 9987 + }; + + function setTextureParameters( textureType, texture, supportsMips ) { if ( supportsMips ) { - _gl.texParameteri( textureType, 10242, utils.convert( texture.wrapS ) ); - _gl.texParameteri( textureType, 10243, utils.convert( texture.wrapT ) ); + _gl.texParameteri( textureType, 10242, wrappingToGL[ texture.wrapS ] ); + _gl.texParameteri( textureType, 10243, wrappingToGL[ texture.wrapT ] ); if ( textureType === 32879 || textureType === 35866 ) { - _gl.texParameteri( textureType, 32882, utils.convert( texture.wrapR ) ); + _gl.texParameteri( textureType, 32882, wrappingToGL[ texture.wrapR ] ); } - _gl.texParameteri( textureType, 10240, utils.convert( texture.magFilter ) ); - _gl.texParameteri( textureType, 10241, utils.convert( texture.minFilter ) ); + _gl.texParameteri( textureType, 10240, filterToGL[ texture.magFilter ] ); + _gl.texParameteri( textureType, 10241, filterToGL[ texture.minFilter ] ); } else { @@ -21168,12 +21873,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - extension = extensions.get( 'EXT_texture_filter_anisotropic' ); + var extension = extensions.get( 'EXT_texture_filter_anisotropic' ); if ( extension ) { if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; - if ( texture.type === HalfFloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return; + if ( texture.type === HalfFloatType && ( isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return; if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { @@ -21219,12 +21924,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, _gl.pixelStorei( 3317, texture.unpackAlignment ); var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false; - var image = resizeImage( texture.image, needsPowerOfTwo, false, capabilities.maxTextureSize ); + var image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize ); - var supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2, + var supportsMips = isPowerOfTwo( image ) || isWebGL2, glFormat = utils.convert( texture.format ), glType = utils.convert( texture.type ), - glInternalFormat = getInternalFormat( glFormat, glType ); + glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType ); setTextureParameters( textureType, texture, supportsMips ); @@ -21238,10 +21943,10 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( texture.type === FloatType ) { - if ( ! capabilities.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' ); + if ( isWebGL2 === false ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' ); glInternalFormat = 36012; - } else if ( capabilities.isWebGL2 ) { + } else if ( isWebGL2 ) { // WebGL 2.0 requires signed internalformat for glTexImage2D glInternalFormat = 33189; @@ -21319,7 +22024,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) { - if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) { + if ( glFormat !== null ) { state.compressedTexImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); @@ -21380,7 +22085,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - generateMipmap( 3553, texture, image.width, image.height ); + generateMipmap( textureType, texture, image.width, image.height ); } @@ -21397,7 +22102,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, var glFormat = utils.convert( renderTarget.texture.format ); var glType = utils.convert( renderTarget.texture.type ); - var glInternalFormat = getInternalFormat( glFormat, glType ); + var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null ); _gl.bindFramebuffer( 36160, framebuffer ); _gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 ); @@ -21447,7 +22152,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, var glFormat = utils.convert( renderTarget.texture.format ); var glType = utils.convert( renderTarget.texture.type ); - var glInternalFormat = getInternalFormat( glFormat, glType ); + var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); if ( isMultisample ) { @@ -21470,7 +22175,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, // Setup resources for a Depth Texture for a FBO (needs an extension) function setupDepthTexture( framebuffer, renderTarget ) { - var isCube = ( renderTarget && renderTarget.isWebGLRenderTargetCube ); + var isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget ); if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' ); _gl.bindFramebuffer( 36160, framebuffer ); @@ -21517,7 +22222,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, var renderTargetProperties = properties.get( renderTarget ); - var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); + var isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); if ( renderTarget.depthTexture ) { @@ -21565,9 +22270,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info.memory.textures ++; - var isCube = ( renderTarget.isWebGLRenderTargetCube === true ); + var isCube = ( renderTarget.isWebGLCubeRenderTarget === true ); var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true ); - var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2; + var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2; // Setup framebuffer @@ -21587,15 +22292,16 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( isMultisample ) { - if ( capabilities.isWebGL2 ) { + if ( isWebGL2 ) { renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer(); renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer(); _gl.bindRenderbuffer( 36161, renderTargetProperties.__webglColorRenderbuffer ); + var glFormat = utils.convert( renderTarget.texture.format ); var glType = utils.convert( renderTarget.texture.type ); - var glInternalFormat = getInternalFormat( glFormat, glType ); + var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType ); var samples = getRenderTargetSamples( renderTarget ); _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height ); @@ -21673,11 +22379,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, function updateRenderTargetMipmap( renderTarget ) { var texture = renderTarget.texture; - var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2; + var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2; if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) { - var target = renderTarget.isWebGLRenderTargetCube ? 34067 : 3553; + var target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553; var webglTexture = properties.get( texture ).__webglTexture; state.bindTexture( target, webglTexture ); @@ -21692,7 +22398,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( renderTarget.isWebGLMultisampleRenderTarget ) { - if ( capabilities.isWebGL2 ) { + if ( isWebGL2 ) { var renderTargetProperties = properties.get( renderTarget ); @@ -21720,21 +22426,20 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, function getRenderTargetSamples( renderTarget ) { - return ( capabilities.isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ? - Math.min( capabilities.maxSamples, renderTarget.samples ) : 0; + return ( isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ? + Math.min( maxSamples, renderTarget.samples ) : 0; } function updateVideoTexture( texture ) { - var id = texture.id; var frame = info.render.frame; // Check the last frame we updated the VideoTexture - if ( _videoTextures[ id ] !== frame ) { + if ( _videoTextures.get( texture ) !== frame ) { - _videoTextures[ id ] = frame; + _videoTextures.set( texture, frame ); texture.update(); } @@ -21767,7 +22472,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, function safeSetTextureCube( texture, slot ) { - if ( texture && texture.isWebGLRenderTargetCube ) { + if ( texture && texture.isWebGLCubeRenderTarget ) { if ( warnedTextureCube === false ) { @@ -21780,7 +22485,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } - // currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture + // currently relying on the fact that WebGLCubeRenderTarget.texture is a Texture and NOT a CubeTexture // TODO: unify these code paths if ( ( texture && texture.isCubeTexture ) || ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { @@ -21792,7 +22497,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } else { - // assumed: texture property of THREE.WebGLRenderTargetCube + // assumed: texture property of THREE.WebGLCubeRenderTarget setTextureCubeDynamic( texture, slot ); } @@ -21824,22 +22529,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, function WebGLUtils( gl, extensions, capabilities ) { + var isWebGL2 = capabilities.isWebGL2; + function convert( p ) { var extension; - if ( p === RepeatWrapping ) return 10497; - if ( p === ClampToEdgeWrapping ) return 33071; - if ( p === MirroredRepeatWrapping ) return 33648; - - if ( p === NearestFilter ) return 9728; - if ( p === NearestMipmapNearestFilter ) return 9984; - if ( p === NearestMipmapLinearFilter ) return 9986; - - if ( p === LinearFilter ) return 9729; - if ( p === LinearMipmapNearestFilter ) return 9985; - if ( p === LinearMipmapLinearFilter ) return 9987; - if ( p === UnsignedByteType ) return 5121; if ( p === UnsignedShort4444Type ) return 32819; if ( p === UnsignedShort5551Type ) return 32820; @@ -21854,11 +22549,19 @@ function WebGLUtils( gl, extensions, capabilities ) { if ( p === HalfFloatType ) { - if ( capabilities.isWebGL2 ) return 5131; + if ( isWebGL2 ) return 5131; extension = extensions.get( 'OES_texture_half_float' ); - if ( extension !== null ) return extension.HALF_FLOAT_OES; + if ( extension !== null ) { + + return extension.HALF_FLOAT_OES; + + } else { + + return null; + + } } @@ -21871,22 +22574,13 @@ function WebGLUtils( gl, extensions, capabilities ) { if ( p === DepthStencilFormat ) return 34041; if ( p === RedFormat ) return 6403; - if ( p === AddEquation ) return 32774; - if ( p === SubtractEquation ) return 32778; - if ( p === ReverseSubtractEquation ) return 32779; - - if ( p === ZeroFactor ) return 0; - if ( p === OneFactor ) return 1; - if ( p === SrcColorFactor ) return 768; - if ( p === OneMinusSrcColorFactor ) return 769; - if ( p === SrcAlphaFactor ) return 770; - if ( p === OneMinusSrcAlphaFactor ) return 771; - if ( p === DstAlphaFactor ) return 772; - if ( p === OneMinusDstAlphaFactor ) return 773; + // WebGL2 formats. - if ( p === DstColorFactor ) return 774; - if ( p === OneMinusDstColorFactor ) return 775; - if ( p === SrcAlphaSaturateFactor ) return 776; + if ( p === RedIntegerFormat ) return 36244; + if ( p === RGFormat ) return 33319; + if ( p === RGIntegerFormat ) return 33320; + if ( p === RGBIntegerFormat ) return 36248; + if ( p === RGBAIntegerFormat ) return 36249; if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) { @@ -21900,6 +22594,10 @@ function WebGLUtils( gl, extensions, capabilities ) { if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; + } else { + + return null; + } } @@ -21916,6 +22614,10 @@ function WebGLUtils( gl, extensions, capabilities ) { if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + } else { + + return null; + } } @@ -21924,41 +22626,53 @@ function WebGLUtils( gl, extensions, capabilities ) { extension = extensions.get( 'WEBGL_compressed_texture_etc1' ); - if ( extension !== null ) return extension.COMPRESSED_RGB_ETC1_WEBGL; + if ( extension !== null ) { + + return extension.COMPRESSED_RGB_ETC1_WEBGL; + + } else { + + return null; + + } } - if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || - p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || - p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || - p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || - p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) { + if ( p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) { - extension = extensions.get( 'WEBGL_compressed_texture_astc' ); + extension = extensions.get( 'WEBGL_compressed_texture_etc' ); if ( extension !== null ) { - return p; + if ( p === RGB_ETC2_Format ) return extension.COMPRESSED_RGB8_ETC2; + if ( p === RGBA_ETC2_EAC_Format ) return extension.COMPRESSED_RGBA8_ETC2_EAC; } } - if ( p === MinEquation || p === MaxEquation ) { + if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || + p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || + p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || + p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || + p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format || + p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format || + p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format || + p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format || + p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format || + p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format ) { - if ( capabilities.isWebGL2 ) { + extension = extensions.get( 'WEBGL_compressed_texture_astc' ); - if ( p === MinEquation ) return 32775; - if ( p === MaxEquation ) return 32776; + if ( extension !== null ) { - } + // TODO Complete? - extension = extensions.get( 'EXT_blend_minmax' ); + return p; - if ( extension !== null ) { + } else { - if ( p === MinEquation ) return extension.MIN_EXT; - if ( p === MaxEquation ) return extension.MAX_EXT; + return null; } @@ -21966,42 +22680,28 @@ function WebGLUtils( gl, extensions, capabilities ) { if ( p === UnsignedInt248Type ) { - if ( capabilities.isWebGL2 ) return 34042; + if ( isWebGL2 ) return 34042; extension = extensions.get( 'WEBGL_depth_texture' ); - if ( extension !== null ) return extension.UNSIGNED_INT_24_8_WEBGL; - - } + if ( extension !== null ) { - return 0; + return extension.UNSIGNED_INT_24_8_WEBGL; - } - - return { convert: convert }; + } else { -} + return null; -/** - * @author mrdoob / http://mrdoob.com/ - */ + } -function Group() { + } - Object3D.call( this ); + } - this.type = 'Group'; + return { convert: convert }; } -Group.prototype = Object.assign( Object.create( Object3D.prototype ), { - - constructor: Group, - - isGroup: true - -} ); - /** * @author mrdoob / http://mrdoob.com/ */ @@ -22023,631 +22723,382 @@ ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototyp } ); /** - * @author jsantell / https://www.jsantell.com/ * @author mrdoob / http://mrdoob.com/ */ -var cameraLPos = new Vector3(); -var cameraRPos = new Vector3(); - -/** - * Assumes 2 cameras that are parallel and share an X-axis, and that - * the cameras' projection and world matrices have already been set. - * And that near and far planes are identical for both cameras. - * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765 - */ -function setProjectionFromUnion( camera, cameraL, cameraR ) { - - cameraLPos.setFromMatrixPosition( cameraL.matrixWorld ); - cameraRPos.setFromMatrixPosition( cameraR.matrixWorld ); - - var ipd = cameraLPos.distanceTo( cameraRPos ); - - var projL = cameraL.projectionMatrix.elements; - var projR = cameraR.projectionMatrix.elements; +function Group() { - // VR systems will have identical far and near planes, and - // most likely identical top and bottom frustum extents. - // Use the left camera for these values. - var near = projL[ 14 ] / ( projL[ 10 ] - 1 ); - var far = projL[ 14 ] / ( projL[ 10 ] + 1 ); - var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ]; - var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ]; + Object3D.call( this ); - var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ]; - var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ]; - var left = near * leftFov; - var right = near * rightFov; + this.type = 'Group'; - // Calculate the new camera's position offset from the - // left camera. xOffset should be roughly half `ipd`. - var zOffset = ipd / ( - leftFov + rightFov ); - var xOffset = zOffset * - leftFov; +} - // TODO: Better way to apply this offset? - cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale ); - camera.translateX( xOffset ); - camera.translateZ( zOffset ); - camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale ); - camera.matrixWorldInverse.getInverse( camera.matrixWorld ); +Group.prototype = Object.assign( Object.create( Object3D.prototype ), { - // Find the union of the frustum values of the cameras and scale - // the values so that the near plane's position does not change in world space, - // although must now be relative to the new union camera. - var near2 = near + zOffset; - var far2 = far + zOffset; - var left2 = left - xOffset; - var right2 = right + ( ipd - xOffset ); - var top2 = topFov * far / far2 * near2; - var bottom2 = bottomFov * far / far2 * near2; + constructor: Group, - camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 ); + isGroup: true -} +} ); /** * @author mrdoob / http://mrdoob.com/ */ -function WebVRManager( renderer ) { +function WebXRManager( renderer, gl ) { - var renderWidth, renderHeight; var scope = this; - var device = null; - var frameData = null; - - var poseTarget = null; - - var controllers = []; - var standingMatrix = new Matrix4(); - var standingMatrixInverse = new Matrix4(); + var session = null; var framebufferScaleFactor = 1.0; + var referenceSpace = null; var referenceSpaceType = 'local-floor'; - if ( typeof window !== 'undefined' && 'VRFrameData' in window ) { - - frameData = new window.VRFrameData(); - window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false ); + var pose = null; - } + var controllers = []; + var inputSourcesMap = new Map(); - var matrixWorldInverse = new Matrix4(); - var tempQuaternion = new Quaternion(); - var tempPosition = new Vector3(); + // var cameraL = new PerspectiveCamera(); - cameraL.viewport = new Vector4(); cameraL.layers.enable( 1 ); + cameraL.viewport = new Vector4(); var cameraR = new PerspectiveCamera(); - cameraR.viewport = new Vector4(); cameraR.layers.enable( 2 ); + cameraR.viewport = new Vector4(); var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); cameraVR.layers.enable( 1 ); cameraVR.layers.enable( 2 ); - // - - function isPresenting() { - - return device !== null && device.isPresenting === true; - - } - - var currentSize = new Vector2(), currentPixelRatio; - - function onVRDisplayPresentChange() { - - if ( isPresenting() ) { - - var eyeParameters = device.getEyeParameters( 'left' ); - renderWidth = 2 * eyeParameters.renderWidth * framebufferScaleFactor; - renderHeight = eyeParameters.renderHeight * framebufferScaleFactor; - - currentPixelRatio = renderer.getPixelRatio(); - renderer.getSize( currentSize ); - - renderer.setDrawingBufferSize( renderWidth, renderHeight, 1 ); - - cameraL.viewport.set( 0, 0, renderWidth / 2, renderHeight ); - cameraR.viewport.set( renderWidth / 2, 0, renderWidth / 2, renderHeight ); - - animation.start(); - - scope.dispatchEvent( { type: 'sessionstart' } ); - - } else { - - if ( scope.enabled ) { - - renderer.setDrawingBufferSize( currentSize.width, currentSize.height, currentPixelRatio ); - - } - - animation.stop(); - - scope.dispatchEvent( { type: 'sessionend' } ); - - } - - } + var _currentDepthNear = null; + var _currentDepthFar = null; // - var triggers = []; - - function findGamepad( id ) { - - var gamepads = navigator.getGamepads && navigator.getGamepads(); - - for ( var i = 0, j = 0, l = gamepads.length; i < l; i ++ ) { - - var gamepad = gamepads[ i ]; - - if ( gamepad && ( gamepad.id === 'Daydream Controller' || - gamepad.id === 'Gear VR Controller' || gamepad.id === 'Oculus Go Controller' || - gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || - gamepad.id.startsWith( 'HTC Vive Focus' ) || - gamepad.id.startsWith( 'Spatial Controller' ) ) ) { - - if ( j === id ) return gamepad; - - j ++; - - } - - } - - } - - function updateControllers() { - - for ( var i = 0; i < controllers.length; i ++ ) { - - var controller = controllers[ i ]; - - var gamepad = findGamepad( i ); - - if ( gamepad !== undefined && gamepad.pose !== undefined ) { - - if ( gamepad.pose === null ) return; - - // Pose - - var pose = gamepad.pose; - - if ( pose.hasPosition === false ) controller.position.set( 0.2, - 0.6, - 0.05 ); - - if ( pose.position !== null ) controller.position.fromArray( pose.position ); - if ( pose.orientation !== null ) controller.quaternion.fromArray( pose.orientation ); - controller.matrix.compose( controller.position, controller.quaternion, controller.scale ); - controller.matrix.premultiply( standingMatrix ); - controller.matrix.decompose( controller.position, controller.quaternion, controller.scale ); - controller.matrixWorldNeedsUpdate = true; - controller.visible = true; - - // Trigger - - var buttonId = gamepad.id === 'Daydream Controller' ? 0 : 1; - - if ( triggers[ i ] === undefined ) triggers[ i ] = false; - - if ( triggers[ i ] !== gamepad.buttons[ buttonId ].pressed ) { - - triggers[ i ] = gamepad.buttons[ buttonId ].pressed; - - if ( triggers[ i ] === true ) { - - controller.dispatchEvent( { type: 'selectstart' } ); - - } else { - - controller.dispatchEvent( { type: 'selectend' } ); - controller.dispatchEvent( { type: 'select' } ); + this.enabled = false; - } + this.isPresenting = false; - } + this.getController = function ( id ) { - } else { + var controller = controllers[ id ]; - controller.visible = false; + if ( controller === undefined ) { - } + controller = {}; + controllers[ id ] = controller; } - } - - function updateViewportFromBounds( viewport, bounds ) { - - if ( bounds !== null && bounds.length === 4 ) { + if ( controller.targetRay === undefined ) { - viewport.set( bounds[ 0 ] * renderWidth, bounds[ 1 ] * renderHeight, bounds[ 2 ] * renderWidth, bounds[ 3 ] * renderHeight ); + controller.targetRay = new Group(); + controller.targetRay.matrixAutoUpdate = false; + controller.targetRay.visible = false; } - } - - // + return controller.targetRay; - this.enabled = false; + }; - this.getController = function ( id ) { + this.getControllerGrip = function ( id ) { var controller = controllers[ id ]; if ( controller === undefined ) { - controller = new Group(); - controller.matrixAutoUpdate = false; - controller.visible = false; - + controller = {}; controllers[ id ] = controller; } - return controller; + if ( controller.grip === undefined ) { - }; - - this.getDevice = function () { + controller.grip = new Group(); + controller.grip.matrixAutoUpdate = false; + controller.grip.visible = false; - return device; - - }; - - this.setDevice = function ( value ) { - - if ( value !== undefined ) device = value; - - animation.setContext( value ); - - }; - - this.setFramebufferScaleFactor = function ( value ) { + } - framebufferScaleFactor = value; + return controller.grip; }; - this.setReferenceSpaceType = function ( value ) { + // - referenceSpaceType = value; + function onSessionEvent( event ) { - }; + var controller = inputSourcesMap.get( event.inputSource ); - this.setPoseTarget = function ( object ) { + if ( controller ) { - if ( object !== undefined ) poseTarget = object; + if ( controller.targetRay ) { - }; + controller.targetRay.dispatchEvent( { type: event.type } ); - this.getCamera = function ( camera ) { - - var userHeight = referenceSpaceType === 'local-floor' ? 1.6 : 0; + } - if ( isPresenting() === false ) { + if ( controller.grip ) { - camera.position.set( 0, userHeight, 0 ); - camera.rotation.set( 0, 0, 0 ); + controller.grip.dispatchEvent( { type: event.type } ); - return camera; + } } - device.depthNear = camera.near; - device.depthFar = camera.far; - - device.getFrameData( frameData ); - - // - - if ( referenceSpaceType === 'local-floor' ) { - - var stageParameters = device.stageParameters; + } - if ( stageParameters ) { + function onSessionEnd() { - standingMatrix.fromArray( stageParameters.sittingToStandingTransform ); + inputSourcesMap.forEach( function ( controller, inputSource ) { - } else { + if ( controller.targetRay ) { - standingMatrix.makeTranslation( 0, userHeight, 0 ); + controller.targetRay.dispatchEvent( { type: 'disconnected', data: inputSource } ); + controller.targetRay.visible = false; } - } - - - var pose = frameData.pose; - var poseObject = poseTarget !== null ? poseTarget : camera; + if ( controller.grip ) { - // We want to manipulate poseObject by its position and quaternion components since users may rely on them. - poseObject.matrix.copy( standingMatrix ); - poseObject.matrix.decompose( poseObject.position, poseObject.quaternion, poseObject.scale ); + controller.grip.dispatchEvent( { type: 'disconnected', data: inputSource } ); + controller.grip.visible = false; - if ( pose.orientation !== null ) { - - tempQuaternion.fromArray( pose.orientation ); - poseObject.quaternion.multiply( tempQuaternion ); - - } - - if ( pose.position !== null ) { - - tempQuaternion.setFromRotationMatrix( standingMatrix ); - tempPosition.fromArray( pose.position ); - tempPosition.applyQuaternion( tempQuaternion ); - poseObject.position.add( tempPosition ); + } - } + } ); - poseObject.updateMatrixWorld(); + inputSourcesMap.clear(); // - cameraL.near = camera.near; - cameraR.near = camera.near; - - cameraL.far = camera.far; - cameraR.far = camera.far; - - cameraL.matrixWorldInverse.fromArray( frameData.leftViewMatrix ); - cameraR.matrixWorldInverse.fromArray( frameData.rightViewMatrix ); - - // TODO (mrdoob) Double check this code - - standingMatrixInverse.getInverse( standingMatrix ); - - if ( referenceSpaceType === 'local-floor' ) { - - cameraL.matrixWorldInverse.multiply( standingMatrixInverse ); - cameraR.matrixWorldInverse.multiply( standingMatrixInverse ); - - } - - var parent = poseObject.parent; + renderer.setFramebuffer( null ); + renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830 + animation.stop(); - if ( parent !== null ) { + scope.isPresenting = false; - matrixWorldInverse.getInverse( parent.matrixWorld ); + scope.dispatchEvent( { type: 'sessionend' } ); - cameraL.matrixWorldInverse.multiply( matrixWorldInverse ); - cameraR.matrixWorldInverse.multiply( matrixWorldInverse ); + } - } + function onRequestReferenceSpace( value ) { - // envMap and Mirror needs camera.matrixWorld + referenceSpace = value; - cameraL.matrixWorld.getInverse( cameraL.matrixWorldInverse ); - cameraR.matrixWorld.getInverse( cameraR.matrixWorldInverse ); + animation.setContext( session ); + animation.start(); - cameraL.projectionMatrix.fromArray( frameData.leftProjectionMatrix ); - cameraR.projectionMatrix.fromArray( frameData.rightProjectionMatrix ); + scope.isPresenting = true; - setProjectionFromUnion( cameraVR, cameraL, cameraR ); + scope.dispatchEvent( { type: 'sessionstart' } ); - // + } - var layers = device.getLayers(); + this.setFramebufferScaleFactor = function ( value ) { - if ( layers.length ) { + framebufferScaleFactor = value; - var layer = layers[ 0 ]; + // Warn if function is used while presenting + if ( scope.isPresenting == true ) { - updateViewportFromBounds( cameraL.viewport, layer.leftBounds ); - updateViewportFromBounds( cameraR.viewport, layer.rightBounds ); + console.warn( "WebXRManager: Cannot change framebuffer scale while presenting VR content" ); } - updateControllers(); - - return cameraVR; - }; - this.getStandingMatrix = function () { - - return standingMatrix; - - }; - - this.isPresenting = isPresenting; - - // Animation Loop - - var animation = new WebGLAnimation(); - - this.setAnimationLoop = function ( callback ) { - - animation.setAnimationLoop( callback ); - - if ( isPresenting() ) animation.start(); - - }; - - this.submitFrame = function () { + this.setReferenceSpaceType = function ( value ) { - if ( isPresenting() ) device.submitFrame(); + referenceSpaceType = value; }; - this.dispose = function () { - - if ( typeof window !== 'undefined' ) { + this.getReferenceSpace = function () { - window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange ); - - } + return referenceSpace; }; - // DEPRECATED - - this.setFrameOfReferenceType = function () { + this.getSession = function () { - console.warn( 'THREE.WebVRManager: setFrameOfReferenceType() has been deprecated.' ); + return session; }; -} - -Object.assign( WebVRManager.prototype, EventDispatcher.prototype ); - -/** - * @author mrdoob / http://mrdoob.com/ - */ - -function WebXRManager( renderer, gl ) { - - var scope = this; - - var session = null; - - var referenceSpace = null; - var referenceSpaceType = 'local-floor'; - - var pose = null; - - var controllers = []; - var inputSources = []; - - function isPresenting() { - - return session !== null && referenceSpace !== null; - - } - - // + this.setSession = function ( value ) { - var cameraL = new PerspectiveCamera(); - cameraL.layers.enable( 1 ); - cameraL.viewport = new Vector4(); + session = value; - var cameraR = new PerspectiveCamera(); - cameraR.layers.enable( 2 ); - cameraR.viewport = new Vector4(); + if ( session !== null ) { - var cameraVR = new ArrayCamera( [ cameraL, cameraR ] ); - cameraVR.layers.enable( 1 ); - cameraVR.layers.enable( 2 ); + session.addEventListener( 'select', onSessionEvent ); + session.addEventListener( 'selectstart', onSessionEvent ); + session.addEventListener( 'selectend', onSessionEvent ); + session.addEventListener( 'squeeze', onSessionEvent ); + session.addEventListener( 'squeezestart', onSessionEvent ); + session.addEventListener( 'squeezeend', onSessionEvent ); + session.addEventListener( 'end', onSessionEnd ); - // + var attributes = gl.getContextAttributes(); - this.enabled = false; + var layerInit = { + antialias: attributes.antialias, + alpha: attributes.alpha, + depth: attributes.depth, + stencil: attributes.stencil, + framebufferScaleFactor: framebufferScaleFactor + }; - this.getController = function ( id ) { + // eslint-disable-next-line no-undef + var baseLayer = new XRWebGLLayer( session, gl, layerInit ); - var controller = controllers[ id ]; + session.updateRenderState( { baseLayer: baseLayer } ); - if ( controller === undefined ) { + session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace ); - controller = new Group(); - controller.matrixAutoUpdate = false; - controller.visible = false; + // - controllers[ id ] = controller; + session.addEventListener( 'inputsourceschange', updateInputSources ); } - return controller; - }; - // - - function onSessionEvent( event ) { + function updateInputSources( event ) { - for ( var i = 0; i < controllers.length; i ++ ) { + var inputSources = session.inputSources; - if ( inputSources[ i ] === event.inputSource ) { + // Assign inputSources to available controllers - controllers[ i ].dispatchEvent( { type: event.type } ); + for ( var i = 0; i < controllers.length; i ++ ) { - } + inputSourcesMap.set( inputSources[ i ], controllers[ i ] ); } - } + // Notify disconnected - function onSessionEnd() { + for ( var i = 0; i < event.removed.length; i ++ ) { - renderer.setFramebuffer( null ); - renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830 - animation.stop(); - - scope.dispatchEvent( { type: 'sessionend' } ); - - } + var inputSource = event.removed[ i ]; + var controller = inputSourcesMap.get( inputSource ); - function onRequestReferenceSpace( value ) { + if ( controller ) { - referenceSpace = value; + if ( controller.targetRay ) { - animation.setContext( session ); - animation.start(); + controller.targetRay.dispatchEvent( { type: 'disconnected', data: inputSource } ); - scope.dispatchEvent( { type: 'sessionstart' } ); + } - } + if ( controller.grip ) { - this.setFramebufferScaleFactor = function ( value ) { + controller.grip.dispatchEvent( { type: 'disconnected', data: inputSource } ); - }; + } - this.setReferenceSpaceType = function ( value ) { + inputSourcesMap.delete( inputSource ); - referenceSpaceType = value; + } - }; + } - this.getSession = function () { + // Notify connected - return session; + for ( var i = 0; i < event.added.length; i ++ ) { - }; + var inputSource = event.added[ i ]; + var controller = inputSourcesMap.get( inputSource ); - this.setSession = function ( value ) { + if ( controller ) { - session = value; + if ( controller.targetRay ) { - if ( session !== null ) { + controller.targetRay.dispatchEvent( { type: 'connected', data: inputSource } ); - session.addEventListener( 'select', onSessionEvent ); - session.addEventListener( 'selectstart', onSessionEvent ); - session.addEventListener( 'selectend', onSessionEvent ); - session.addEventListener( 'end', onSessionEnd ); + } - session.updateRenderState( { baseLayer: new XRWebGLLayer( session, gl ) } ); + if ( controller.grip ) { - session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace ); + controller.grip.dispatchEvent( { type: 'connected', data: inputSource } ); - // + } - inputSources = session.inputSources; + } - session.addEventListener( 'inputsourceschange', function () { + } - inputSources = session.inputSources; - console.log( inputSources ); + } - for ( var i = 0; i < controllers.length; i ++ ) { + // - var controller = controllers[ i ]; - controller.userData.inputSource = inputSources[ i ]; + var cameraLPos = new Vector3(); + var cameraRPos = new Vector3(); - } + /** + * @author jsantell / https://www.jsantell.com/ + * + * Assumes 2 cameras that are parallel and share an X-axis, and that + * the cameras' projection and world matrices have already been set. + * And that near and far planes are identical for both cameras. + * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765 + */ + function setProjectionFromUnion( camera, cameraL, cameraR ) { + + cameraLPos.setFromMatrixPosition( cameraL.matrixWorld ); + cameraRPos.setFromMatrixPosition( cameraR.matrixWorld ); + + var ipd = cameraLPos.distanceTo( cameraRPos ); + + var projL = cameraL.projectionMatrix.elements; + var projR = cameraR.projectionMatrix.elements; + + // VR systems will have identical far and near planes, and + // most likely identical top and bottom frustum extents. + // Use the left camera for these values. + var near = projL[ 14 ] / ( projL[ 10 ] - 1 ); + var far = projL[ 14 ] / ( projL[ 10 ] + 1 ); + var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ]; + var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ]; + + var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ]; + var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ]; + var left = near * leftFov; + var right = near * rightFov; + + // Calculate the new camera's position offset from the + // left camera. xOffset should be roughly half `ipd`. + var zOffset = ipd / ( - leftFov + rightFov ); + var xOffset = zOffset * - leftFov; + + // TODO: Better way to apply this offset? + cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale ); + camera.translateX( xOffset ); + camera.translateZ( zOffset ); + camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale ); + camera.matrixWorldInverse.getInverse( camera.matrixWorld ); - } ); + // Find the union of the frustum values of the cameras and scale + // the values so that the near plane's position does not change in world space, + // although must now be relative to the new union camera. + var near2 = near + zOffset; + var far2 = far + zOffset; + var left2 = left - xOffset; + var right2 = right + ( ipd - xOffset ); + var top2 = topFov * far / far2 * near2; + var bottom2 = bottomFov * far / far2 * near2; - } + camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 ); - }; + } function updateCamera( camera, parent ) { @@ -22667,42 +23118,51 @@ function WebXRManager( renderer, gl ) { this.getCamera = function ( camera ) { - if ( isPresenting() ) { + cameraVR.near = cameraR.near = cameraL.near = camera.near; + cameraVR.far = cameraR.far = cameraL.far = camera.far; - var parent = camera.parent; - var cameras = cameraVR.cameras; + if ( _currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far ) { - updateCamera( cameraVR, parent ); + // Note that the new renderState won't apply until the next frame. See #18320 - for ( var i = 0; i < cameras.length; i ++ ) { + session.updateRenderState( { + depthNear: cameraVR.near, + depthFar: cameraVR.far + } ); - updateCamera( cameras[ i ], parent ); + _currentDepthNear = cameraVR.near; + _currentDepthFar = cameraVR.far; - } + } - // update camera and its children + var parent = camera.parent; + var cameras = cameraVR.cameras; - camera.matrixWorld.copy( cameraVR.matrixWorld ); + updateCamera( cameraVR, parent ); - var children = camera.children; + for ( var i = 0; i < cameras.length; i ++ ) { - for ( var i = 0, l = children.length; i < l; i ++ ) { + updateCamera( cameras[ i ], parent ); + + } - children[ i ].updateMatrixWorld( true ); + // update camera and its children - } + camera.matrixWorld.copy( cameraVR.matrixWorld ); - setProjectionFromUnion( cameraVR, cameraL, cameraR ); + var children = camera.children; - return cameraVR; + for ( var i = 0, l = children.length; i < l; i ++ ) { + + children[ i ].updateMatrixWorld( true ); } - return camera; + setProjectionFromUnion( cameraVR, cameraL, cameraR ); - }; + return cameraVR; - this.isPresenting = isPresenting; + }; // Animation Loop @@ -22723,10 +23183,9 @@ function WebXRManager( renderer, gl ) { var view = views[ i ]; var viewport = baseLayer.getViewport( view ); - var viewMatrix = view.transform.inverse.matrix; var camera = cameraVR.cameras[ i ]; - camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix ); + camera.matrix.fromArray( view.transform.matrix ); camera.projectionMatrix.fromArray( view.projectionMatrix ); camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height ); @@ -22742,75 +23201,75 @@ function WebXRManager( renderer, gl ) { // + var inputSources = session.inputSources; + for ( var i = 0; i < controllers.length; i ++ ) { var controller = controllers[ i ]; var inputSource = inputSources[ i ]; - if ( inputSource ) { + var inputPose = null; + var gripPose = null; - var inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); - - if ( inputPose !== null ) { + if ( inputSource ) { - controller.matrix.fromArray( inputPose.transform.matrix ); - controller.matrix.decompose( controller.position, controller.rotation, controller.scale ); - controller.visible = true; + if ( controller.targetRay ) { - continue; + inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); - } + if ( inputPose !== null ) { - } + controller.targetRay.matrix.fromArray( inputPose.transform.matrix ); + controller.targetRay.matrix.decompose( controller.targetRay.position, controller.targetRay.rotation, controller.targetRay.scale ); - controller.visible = false; + } - } + } - if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); + if ( controller.grip && inputSource.gripSpace ) { - } + gripPose = frame.getPose( inputSource.gripSpace, referenceSpace ); - var animation = new WebGLAnimation(); - animation.setAnimationLoop( onAnimationFrame ); + if ( gripPose !== null ) { - this.setAnimationLoop = function ( callback ) { + controller.grip.matrix.fromArray( gripPose.transform.matrix ); + controller.grip.matrix.decompose( controller.grip.position, controller.grip.rotation, controller.grip.scale ); - onAnimationFrameCallback = callback; + } - }; + } - this.dispose = function () {}; + } - // DEPRECATED + if ( controller.targetRay ) { - this.getStandingMatrix = function () { + controller.targetRay.visible = inputPose !== null; - console.warn( 'THREE.WebXRManager: getStandingMatrix() is no longer needed.' ); - return new Matrix4(); + } - }; + if ( controller.grip ) { - this.getDevice = function () { + controller.grip.visible = gripPose !== null; - console.warn( 'THREE.WebXRManager: getDevice() has been deprecated.' ); + } - }; + } - this.setDevice = function () { + if ( onAnimationFrameCallback ) onAnimationFrameCallback( time, frame ); - console.warn( 'THREE.WebXRManager: setDevice() has been deprecated.' ); + } - }; + var animation = new WebGLAnimation(); + animation.setAnimationLoop( onAnimationFrame ); - this.setFrameOfReferenceType = function () { + this.setAnimationLoop = function ( callback ) { - console.warn( 'THREE.WebXRManager: setFrameOfReferenceType() has been deprecated.' ); + onAnimationFrameCallback = callback; }; - this.submitFrame = function () {}; + this.dispose = function () {}; } @@ -22876,8 +23335,7 @@ function WebGLRenderer( parameters ) { // physically based shading this.gammaFactor = 2.0; // for backwards compatibility - this.gammaInput = false; - this.gammaOutput = false; + this.outputEncoding = LinearEncoding; // physical lights @@ -22931,6 +23389,8 @@ function WebGLRenderer( parameters ) { _height = _canvas.height, _pixelRatio = 1, + _opaqueSort = null, + _transparentSort = null, _viewport = new Vector4( 0, 0, _width, _height ), _scissor = new Vector4( 0, 0, _width, _height ), @@ -23030,7 +23490,7 @@ function WebGLRenderer( parameters ) { capabilities = new WebGLCapabilities( _gl, extensions, parameters ); - if ( ! capabilities.isWebGL2 ) { + if ( capabilities.isWebGL2 === false ) { extensions.get( 'WEBGL_depth_texture' ); extensions.get( 'OES_texture_float' ); @@ -23046,16 +23506,16 @@ function WebGLRenderer( parameters ) { utils = new WebGLUtils( _gl, extensions, capabilities ); - state = new WebGLState( _gl, extensions, utils, capabilities ); + state = new WebGLState( _gl, extensions, capabilities ); state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() ); state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() ); info = new WebGLInfo( _gl ); properties = new WebGLProperties(); textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ); - attributes = new WebGLAttributes( _gl ); + attributes = new WebGLAttributes( _gl, capabilities ); geometries = new WebGLGeometries( _gl, attributes, info ); - objects = new WebGLObjects( geometries, info ); + objects = new WebGLObjects( _gl, geometries, attributes, info ); morphtargets = new WebGLMorphtargets( _gl ); programCache = new WebGLPrograms( _this, extensions, capabilities ); renderLists = new WebGLRenderLists(); @@ -23079,11 +23539,11 @@ function WebGLRenderer( parameters ) { initGLContext(); - // vr + // xr - var vr = ( typeof navigator !== 'undefined' && 'xr' in navigator && 'supportsSession' in navigator.xr ) ? new WebXRManager( _this, _gl ) : new WebVRManager( _this ); + var xr = new WebXRManager( _this, _gl ); - this.vr = vr; + this.xr = xr; // shadow map @@ -23151,7 +23611,7 @@ function WebGLRenderer( parameters ) { this.setSize = function ( width, height, updateStyle ) { - if ( vr.isPresenting() ) { + if ( xr.isPresenting ) { console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' ); return; @@ -23273,6 +23733,18 @@ function WebGLRenderer( parameters ) { }; + this.setOpaqueSort = function ( method ) { + + _opaqueSort = method; + + }; + + this.setTransparentSort = function ( method ) { + + _transparentSort = method; + + }; + // Clearing this.getClearColor = function () { @@ -23341,10 +23813,12 @@ function WebGLRenderer( parameters ) { properties.dispose(); objects.dispose(); - vr.dispose(); + xr.dispose(); animation.stop(); + this.forceContextLoss(); + }; // Events @@ -23477,13 +23951,17 @@ function WebGLRenderer( parameters ) { }; - this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { + var tempScene = new Scene(); + + this.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) { + + if ( scene === null ) scene = tempScene; // renderBufferDirect second parameter used to be fog (could be null) var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 ); - state.setMaterial( material, frontFaceCW ); + var program = setProgram( camera, scene, material, object ); - var program = setProgram( camera, fog, material, object ); + state.setMaterial( material, frontFaceCW ); var updateBuffers = false; @@ -23498,7 +23976,7 @@ function WebGLRenderer( parameters ) { } - if ( object.morphTargetInfluences ) { + if ( material.morphTargets || material.morphNormals ) { morphtargets.update( object, geometry, material, program ); @@ -23510,6 +23988,21 @@ function WebGLRenderer( parameters ) { var index = geometry.index; var position = geometry.attributes.position; + + // + + if ( index === null ) { + + if ( position === undefined || position.count === 0 ) return; + + } else if ( index.count === 0 ) { + + return; + + } + + // + var rangeFactor = 1; if ( material.wireframe === true ) { @@ -23533,7 +24026,7 @@ function WebGLRenderer( parameters ) { if ( updateBuffers ) { - setupVertexAttributes( material, program, geometry ); + setupVertexAttributes( object, geometry, material, program ); if ( index !== null ) { @@ -23545,17 +24038,7 @@ function WebGLRenderer( parameters ) { // - var dataCount = Infinity; - - if ( index !== null ) { - - dataCount = index.count; - - } else if ( position !== undefined ) { - - dataCount = position.count; - - } + var dataCount = ( index !== null ) ? index.count : position.count; var rangeStart = geometry.drawRange.start * rangeFactor; var rangeCount = geometry.drawRange.count * rangeFactor; @@ -23581,25 +24064,10 @@ function WebGLRenderer( parameters ) { } else { - switch ( object.drawMode ) { - - case TrianglesDrawMode: - renderer.setMode( 4 ); - break; - - case TriangleStripDrawMode: - renderer.setMode( 5 ); - break; - - case TriangleFanDrawMode: - renderer.setMode( 6 ); - break; - - } + renderer.setMode( 4 ); } - } else if ( object.isLine ) { var lineWidth = material.linewidth; @@ -23632,13 +24100,13 @@ function WebGLRenderer( parameters ) { } - if ( geometry && geometry.isInstancedBufferGeometry ) { + if ( object.isInstancedMesh ) { - if ( geometry.maxInstancedCount > 0 ) { + renderer.renderInstances( geometry, drawStart, drawCount, object.count ); - renderer.renderInstances( geometry, drawStart, drawCount ); + } else if ( geometry.isInstancedBufferGeometry ) { - } + renderer.renderInstances( geometry, drawStart, drawCount, geometry.maxInstancedCount ); } else { @@ -23648,16 +24116,11 @@ function WebGLRenderer( parameters ) { }; - function setupVertexAttributes( material, program, geometry ) { + function setupVertexAttributes( object, geometry, material, program ) { - if ( geometry && geometry.isInstancedBufferGeometry && ! capabilities.isWebGL2 ) { + if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) { - if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { - - console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' ); - return; - - } + if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) return; } @@ -23740,6 +24203,29 @@ function WebGLRenderer( parameters ) { } + } else if ( name === 'instanceMatrix' ) { + + var attribute = attributes.get( object.instanceMatrix ); + + // TODO Attribute may not be available on context restore + + if ( attribute === undefined ) continue; + + var buffer = attribute.buffer; + var type = attribute.type; + + state.enableAttributeAndDivisor( programAttribute + 0, 1 ); + state.enableAttributeAndDivisor( programAttribute + 1, 1 ); + state.enableAttributeAndDivisor( programAttribute + 2, 1 ); + state.enableAttributeAndDivisor( programAttribute + 3, 1 ); + + _gl.bindBuffer( 34962, buffer ); + + _gl.vertexAttribPointer( programAttribute + 0, 4, type, false, 64, 0 ); + _gl.vertexAttribPointer( programAttribute + 1, 4, type, false, 64, 16 ); + _gl.vertexAttribPointer( programAttribute + 2, 4, type, false, 64, 32 ); + _gl.vertexAttribPointer( programAttribute + 3, 4, type, false, 64, 48 ); + } else if ( materialDefaultAttributeValues !== undefined ) { var value = materialDefaultAttributeValues[ name ]; @@ -23802,6 +24288,8 @@ function WebGLRenderer( parameters ) { currentRenderState.setupLights( camera ); + var compiled = {}; + scene.traverse( function ( object ) { if ( object.material ) { @@ -23810,13 +24298,19 @@ function WebGLRenderer( parameters ) { for ( var i = 0; i < object.material.length; i ++ ) { - initMaterial( object.material[ i ], scene.fog, object ); + if ( object.material[ i ].uuid in compiled === false ) { + + initMaterial( object.material[ i ], scene, object ); + compiled[ object.material[ i ].uuid ] = true; + + } } - } else { + } else if ( object.material.uuid in compiled === false ) { - initMaterial( object.material, scene.fog, object ); + initMaterial( object.material, scene, object ); + compiled[ object.material.uuid ] = true; } @@ -23832,7 +24326,7 @@ function WebGLRenderer( parameters ) { function onAnimationFrame( time ) { - if ( vr.isPresenting() ) return; + if ( xr.isPresenting ) return; if ( onAnimationFrameCallback ) onAnimationFrameCallback( time ); } @@ -23845,7 +24339,7 @@ function WebGLRenderer( parameters ) { this.setAnimationLoop = function ( callback ) { onAnimationFrameCallback = callback; - vr.setAnimationLoop( callback ); + xr.setAnimationLoop( callback ); animation.start(); @@ -23896,9 +24390,9 @@ function WebGLRenderer( parameters ) { if ( camera.parent === null ) camera.updateMatrixWorld(); - if ( vr.enabled ) { + if ( xr.enabled && xr.isPresenting ) { - camera = vr.getCamera( camera ); + camera = xr.getCamera( camera ); } @@ -23910,7 +24404,7 @@ function WebGLRenderer( parameters ) { scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget ); _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); - _frustum.setFromMatrix( _projScreenMatrix ); + _frustum.setFromProjectionMatrix( _projScreenMatrix ); _localClippingEnabled = this.localClippingEnabled; _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); @@ -23920,9 +24414,11 @@ function WebGLRenderer( parameters ) { projectObject( scene, camera, 0, _this.sortObjects ); + currentRenderList.finish(); + if ( _this.sortObjects === true ) { - currentRenderList.sort(); + currentRenderList.sort( _opaqueSort, _transparentSort ); } @@ -24002,12 +24498,6 @@ function WebGLRenderer( parameters ) { state.setPolygonOffset( false ); - if ( vr.enabled ) { - - vr.submitFrame(); - - } - // _gl.finish(); currentRenderList = null; @@ -24078,7 +24568,14 @@ function WebGLRenderer( parameters ) { if ( object.isSkinnedMesh ) { - object.skeleton.update(); + // update skeleton only once in a frame + + if ( object.skeleton.frame !== info.render.frame ) { + + object.skeleton.update(); + object.skeleton.frame = info.render.frame; + + } } @@ -24188,9 +24685,9 @@ function WebGLRenderer( parameters ) { if ( object.isImmediateRenderObject ) { - state.setMaterial( material ); + var program = setProgram( camera, scene, material, object ); - var program = setProgram( camera, scene.fog, material, object ); + state.setMaterial( material ); _currentGeometryProgram.geometry = null; _currentGeometryProgram.program = null; @@ -24200,7 +24697,7 @@ function WebGLRenderer( parameters ) { } else { - _this.renderBufferDirect( camera, scene.fog, geometry, material, object, group ); + _this.renderBufferDirect( camera, scene, geometry, material, object, group ); } @@ -24209,7 +24706,7 @@ function WebGLRenderer( parameters ) { } - function initMaterial( material, fog, object ) { + function initMaterial( material, scene, object ) { var materialProperties = properties.get( material ); @@ -24218,10 +24715,8 @@ function WebGLRenderer( parameters ) { var lightsStateVersion = lights.state.version; - var parameters = programCache.getParameters( - material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object ); - - var code = programCache.getProgramCode( material, parameters ); + var parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, _clipping.numPlanes, _clipping.numIntersection, object ); + var programCacheKey = programCache.getProgramCacheKey( parameters ); var program = materialProperties.program; var programChange = true; @@ -24231,7 +24726,7 @@ function WebGLRenderer( parameters ) { // new material material.addEventListener( 'dispose', onMaterialDispose ); - } else if ( program.code !== code ) { + } else if ( program.cacheKey !== programCacheKey ) { // changed glsl or parameters releaseMaterialProgramReference( material ); @@ -24256,36 +24751,12 @@ function WebGLRenderer( parameters ) { if ( programChange ) { - if ( parameters.shaderID ) { - - var shader = ShaderLib[ parameters.shaderID ]; - - materialProperties.shader = { - name: material.type, - uniforms: cloneUniforms( shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader - }; - - } else { - - materialProperties.shader = { - name: material.type, - uniforms: material.uniforms, - vertexShader: material.vertexShader, - fragmentShader: material.fragmentShader - }; - - } - - material.onBeforeCompile( materialProperties.shader, _this ); - - // Computing code again as onBeforeCompile may have changed the shaders - code = programCache.getProgramCode( material, parameters ); - - program = programCache.acquireProgram( material, materialProperties.shader, parameters, code ); + program = programCache.acquireProgram( parameters, programCacheKey ); materialProperties.program = program; + materialProperties.uniforms = parameters.uniforms; + materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null; + materialProperties.outputEncoding = _this.outputEncoding; material.program = program; } @@ -24324,7 +24795,7 @@ function WebGLRenderer( parameters ) { } - var uniforms = materialProperties.shader.uniforms; + var uniforms = materialProperties.uniforms; if ( ! material.isShaderMaterial && ! material.isRawShaderMaterial || @@ -24336,22 +24807,26 @@ function WebGLRenderer( parameters ) { } - materialProperties.fog = fog; + materialProperties.fog = scene.fog; // store the light setup it was created for + materialProperties.needsLights = materialNeedsLights( material ); materialProperties.lightsStateVersion = lightsStateVersion; - if ( material.lights ) { + if ( materialProperties.needsLights ) { // wire up the material to this renderer's lighting state uniforms.ambientLightColor.value = lights.state.ambient; uniforms.lightProbe.value = lights.state.probe; uniforms.directionalLights.value = lights.state.directional; + uniforms.directionalLightShadows.value = lights.state.directionalShadow; uniforms.spotLights.value = lights.state.spot; + uniforms.spotLightShadows.value = lights.state.spotShadow; uniforms.rectAreaLights.value = lights.state.rectArea; uniforms.pointLights.value = lights.state.point; + uniforms.pointLightShadows.value = lights.state.pointShadow; uniforms.hemisphereLights.value = lights.state.hemi; uniforms.directionalShadowMap.value = lights.state.directionalShadowMap; @@ -24372,10 +24847,13 @@ function WebGLRenderer( parameters ) { } - function setProgram( camera, fog, material, object ) { + function setProgram( camera, scene, material, object ) { textures.resetTextureUnits(); + var fog = scene.fog; + var environment = material.isMeshStandardMaterial ? scene.environment : null; + var materialProperties = properties.get( material ); var lights = currentRenderState.state.lights; @@ -24398,34 +24876,40 @@ function WebGLRenderer( parameters ) { } - if ( material.needsUpdate === false ) { + if ( material.version === materialProperties.__version ) { if ( materialProperties.program === undefined ) { - material.needsUpdate = true; + initMaterial( material, scene, object ); } else if ( material.fog && materialProperties.fog !== fog ) { - material.needsUpdate = true; + initMaterial( material, scene, object ); + + } else if ( materialProperties.environment !== environment ) { - } else if ( material.lights && materialProperties.lightsStateVersion !== lights.state.version ) { + initMaterial( material, scene, object ); - material.needsUpdate = true; + } else if ( materialProperties.needsLights && ( materialProperties.lightsStateVersion !== lights.state.version ) ) { + + initMaterial( material, scene, object ); } else if ( materialProperties.numClippingPlanes !== undefined && ( materialProperties.numClippingPlanes !== _clipping.numPlanes || materialProperties.numIntersection !== _clipping.numIntersection ) ) { - material.needsUpdate = true; + initMaterial( material, scene, object ); - } + } else if ( materialProperties.outputEncoding !== _this.outputEncoding ) { - } + initMaterial( material, scene, object ); - if ( material.needsUpdate ) { + } + + } else { - initMaterial( material, fog, object ); - material.needsUpdate = false; + initMaterial( material, scene, object ); + materialProperties.__version = material.version; } @@ -24435,7 +24919,7 @@ function WebGLRenderer( parameters ) { var program = materialProperties.program, p_uniforms = program.getUniforms(), - m_uniforms = materialProperties.shader.uniforms; + m_uniforms = materialProperties.uniforms; if ( state.useProgram( program.program ) ) { @@ -24482,6 +24966,7 @@ function WebGLRenderer( parameters ) { if ( material.isShaderMaterial || material.isMeshPhongMaterial || + material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap ) { @@ -24497,6 +24982,18 @@ function WebGLRenderer( parameters ) { } if ( material.isMeshPhongMaterial || + material.isMeshToonMaterial || + material.isMeshLambertMaterial || + material.isMeshBasicMaterial || + material.isMeshStandardMaterial || + material.isShaderMaterial ) { + + p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true ); + + } + + if ( material.isMeshPhongMaterial || + material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || @@ -24511,7 +25008,7 @@ function WebGLRenderer( parameters ) { // skinning uniforms must be set even if material didn't change // auto-setting of texture unit for bone texture must go before other textures - // not sure why, but otherwise weird things happen + // otherwise textures used for skinning can take over texture units reserved for other material textures if ( material.skinning ) { @@ -24537,14 +25034,13 @@ function WebGLRenderer( parameters ) { var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix - size = _Math.ceilPowerOfTwo( size ); + size = MathUtils.ceilPowerOfTwo( size ); size = Math.max( size, 4 ); var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel boneMatrices.set( skeleton.boneMatrices ); // copy current values var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType ); - boneTexture.needsUpdate = true; skeleton.boneMatrices = boneMatrices; skeleton.boneTexture = boneTexture; @@ -24565,12 +25061,19 @@ function WebGLRenderer( parameters ) { } + if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) { + + materialProperties.receiveShadow = object.receiveShadow; + p_uniforms.setValue( _gl, 'receiveShadow', object.receiveShadow ); + + } + if ( refreshMaterial ) { p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure ); p_uniforms.setValue( _gl, 'toneMappingWhitePoint', _this.toneMappingWhitePoint ); - if ( material.lights ) { + if ( materialProperties.needsLights ) { // the current material requires lighting info @@ -24602,38 +25105,33 @@ function WebGLRenderer( parameters ) { refreshUniformsCommon( m_uniforms, material ); refreshUniformsLambert( m_uniforms, material ); - } else if ( material.isMeshPhongMaterial ) { + } else if ( material.isMeshToonMaterial ) { refreshUniformsCommon( m_uniforms, material ); + refreshUniformsToon( m_uniforms, material ); - if ( material.isMeshToonMaterial ) { - - refreshUniformsToon( m_uniforms, material ); - - } else { - - refreshUniformsPhong( m_uniforms, material ); + } else if ( material.isMeshPhongMaterial ) { - } + refreshUniformsCommon( m_uniforms, material ); + refreshUniformsPhong( m_uniforms, material ); } else if ( material.isMeshStandardMaterial ) { - refreshUniformsCommon( m_uniforms, material ); + refreshUniformsCommon( m_uniforms, material, environment ); if ( material.isMeshPhysicalMaterial ) { - refreshUniformsPhysical( m_uniforms, material ); + refreshUniformsPhysical( m_uniforms, material, environment ); } else { - refreshUniformsStandard( m_uniforms, material ); + refreshUniformsStandard( m_uniforms, material, environment ); } } else if ( material.isMeshMatcapMaterial ) { refreshUniformsCommon( m_uniforms, material ); - refreshUniformsMatcap( m_uniforms, material ); } else if ( material.isMeshDepthMaterial ) { @@ -24684,6 +25182,12 @@ function WebGLRenderer( parameters ) { WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures ); + if ( material.isShaderMaterial ) { + + material.uniformsNeedUpdate = false; // #15581 + + } + } if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) { @@ -24711,7 +25215,7 @@ function WebGLRenderer( parameters ) { // Uniforms (refresh uniforms objects) - function refreshUniformsCommon( uniforms, material ) { + function refreshUniformsCommon( uniforms, material, environment ) { uniforms.opacity.value = material.opacity; @@ -24745,20 +25249,18 @@ function WebGLRenderer( parameters ) { } - if ( material.envMap ) { + var envMap = material.envMap || environment; + + if ( envMap ) { - uniforms.envMap.value = material.envMap; + uniforms.envMap.value = envMap; - // don't flip CubeTexture envMaps, flip everything else: - // WebGLRenderTargetCube will be flipped for backwards compatibility - // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture - // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future - uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1; + uniforms.flipEnvMap.value = envMap.isCubeTexture ? - 1 : 1; uniforms.reflectivity.value = material.reflectivity; uniforms.refractionRatio.value = material.refractionRatio; - uniforms.maxMipLevel.value = properties.get( material.envMap ).__maxMipLevel; + uniforms.maxMipLevel.value = properties.get( envMap ).__maxMipLevel; } @@ -24843,6 +25345,41 @@ function WebGLRenderer( parameters ) { } + // uv repeat and offset setting priorities for uv2 + // 1. ao map + // 2. light map + + var uv2ScaleMap; + + if ( material.aoMap ) { + + uv2ScaleMap = material.aoMap; + + } else if ( material.lightMap ) { + + uv2ScaleMap = material.lightMap; + + } + + if ( uv2ScaleMap !== undefined ) { + + // backwards compatibility + if ( uv2ScaleMap.isWebGLRenderTarget ) { + + uv2ScaleMap = uv2ScaleMap.texture; + + } + + if ( uv2ScaleMap.matrixAutoUpdate === true ) { + + uv2ScaleMap.updateMatrix(); + + } + + uniforms.uv2Transform.value.copy( uv2ScaleMap.matrix ); + + } + } function refreshUniformsLine( uniforms, material ) { @@ -24867,17 +25404,43 @@ function WebGLRenderer( parameters ) { uniforms.size.value = material.size * _pixelRatio; uniforms.scale.value = _height * 0.5; - uniforms.map.value = material.map; + if ( material.map ) { + + uniforms.map.value = material.map; + + } + + if ( material.alphaMap ) { - if ( material.map !== null ) { + uniforms.alphaMap.value = material.alphaMap; - if ( material.map.matrixAutoUpdate === true ) { + } - material.map.updateMatrix(); + // uv repeat and offset setting priorities + // 1. color map + // 2. alpha map + + var uvScaleMap; + + if ( material.map ) { + + uvScaleMap = material.map; + + } else if ( material.alphaMap ) { + + uvScaleMap = material.alphaMap; + + } + + if ( uvScaleMap !== undefined ) { + + if ( uvScaleMap.matrixAutoUpdate === true ) { + + uvScaleMap.updateMatrix(); } - uniforms.uvTransform.value.copy( material.map.matrix ); + uniforms.uvTransform.value.copy( uvScaleMap.matrix ); } @@ -24888,17 +25451,44 @@ function WebGLRenderer( parameters ) { uniforms.diffuse.value.copy( material.color ); uniforms.opacity.value = material.opacity; uniforms.rotation.value = material.rotation; - uniforms.map.value = material.map; - if ( material.map !== null ) { + if ( material.map ) { + + uniforms.map.value = material.map; + + } + + if ( material.alphaMap ) { + + uniforms.alphaMap.value = material.alphaMap; + + } + + // uv repeat and offset setting priorities + // 1. color map + // 2. alpha map + + var uvScaleMap; - if ( material.map.matrixAutoUpdate === true ) { + if ( material.map ) { - material.map.updateMatrix(); + uvScaleMap = material.map; + + } else if ( material.alphaMap ) { + + uvScaleMap = material.alphaMap; + + } + + if ( uvScaleMap !== undefined ) { + + if ( uvScaleMap.matrixAutoUpdate === true ) { + + uvScaleMap.updateMatrix(); } - uniforms.uvTransform.value.copy( material.map.matrix ); + uniforms.uvTransform.value.copy( uvScaleMap.matrix ); } @@ -24970,7 +25560,8 @@ function WebGLRenderer( parameters ) { function refreshUniformsToon( uniforms, material ) { - refreshUniformsPhong( uniforms, material ); + uniforms.specular.value.copy( material.specular ); + uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 ) if ( material.gradientMap ) { @@ -24978,9 +25569,39 @@ function WebGLRenderer( parameters ) { } + if ( material.emissiveMap ) { + + uniforms.emissiveMap.value = material.emissiveMap; + + } + + if ( material.bumpMap ) { + + uniforms.bumpMap.value = material.bumpMap; + uniforms.bumpScale.value = material.bumpScale; + if ( material.side === BackSide ) uniforms.bumpScale.value *= - 1; + + } + + if ( material.normalMap ) { + + uniforms.normalMap.value = material.normalMap; + uniforms.normalScale.value.copy( material.normalScale ); + if ( material.side === BackSide ) uniforms.normalScale.value.negate(); + + } + + if ( material.displacementMap ) { + + uniforms.displacementMap.value = material.displacementMap; + uniforms.displacementScale.value = material.displacementScale; + uniforms.displacementBias.value = material.displacementBias; + + } + } - function refreshUniformsStandard( uniforms, material ) { + function refreshUniformsStandard( uniforms, material, environment ) { uniforms.roughness.value = material.roughness; uniforms.metalness.value = material.metalness; @@ -25027,7 +25648,7 @@ function WebGLRenderer( parameters ) { } - if ( material.envMap ) { + if ( material.envMap || environment ) { //uniforms.envMap.value = material.envMap; // part of uniforms common uniforms.envMapIntensity.value = material.envMapIntensity; @@ -25036,28 +25657,43 @@ function WebGLRenderer( parameters ) { } - function refreshUniformsPhysical( uniforms, material ) { + function refreshUniformsPhysical( uniforms, material, environment ) { - refreshUniformsStandard( uniforms, material ); + refreshUniformsStandard( uniforms, material, environment ); uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common - uniforms.clearCoat.value = material.clearCoat; - uniforms.clearCoatRoughness.value = material.clearCoatRoughness; + uniforms.clearcoat.value = material.clearcoat; + uniforms.clearcoatRoughness.value = material.clearcoatRoughness; + if ( material.sheen ) uniforms.sheen.value.copy( material.sheen ); + + if ( material.clearcoatMap ) { + + uniforms.clearcoatMap.value = material.clearcoatMap; + + } + + if ( material.clearcoatRoughnessMap ) { + + uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap; + + } - if ( material.clearCoatNormalMap ) { + if ( material.clearcoatNormalMap ) { - uniforms.clearCoatNormalScale.value.copy( material.clearCoatNormalScale ); - uniforms.clearCoatNormalMap.value = material.clearCoatNormalMap; + uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale ); + uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap; if ( material.side === BackSide ) { - uniforms.clearCoatNormalScale.value.negate(); + uniforms.clearcoatNormalScale.value.negate(); } } + uniforms.transparency.value = material.transparency; + } function refreshUniformsMatcap( uniforms, material ) { @@ -25158,17 +25794,28 @@ function WebGLRenderer( parameters ) { uniforms.lightProbe.needsUpdate = value; uniforms.directionalLights.needsUpdate = value; + uniforms.directionalLightShadows.needsUpdate = value; uniforms.pointLights.needsUpdate = value; + uniforms.pointLightShadows.needsUpdate = value; uniforms.spotLights.needsUpdate = value; + uniforms.spotLightShadows.needsUpdate = value; uniforms.rectAreaLights.needsUpdate = value; uniforms.hemisphereLights.needsUpdate = value; } + function materialNeedsLights( material ) { + + return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || + material.isMeshStandardMaterial || material.isShadowMaterial || + ( material.isShaderMaterial && material.lights === true ); + + } + // this.setFramebuffer = function ( value ) { - if ( _framebuffer !== value ) _gl.bindFramebuffer( 36160, value ); + if ( _framebuffer !== value && _currentRenderTarget === null ) _gl.bindFramebuffer( 36160, value ); _framebuffer = value; @@ -25211,7 +25858,7 @@ function WebGLRenderer( parameters ) { var __webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer; - if ( renderTarget.isWebGLRenderTargetCube ) { + if ( renderTarget.isWebGLCubeRenderTarget ) { framebuffer = __webglFramebuffer[ activeCubeFace || 0 ]; isCube = true; @@ -25269,7 +25916,7 @@ function WebGLRenderer( parameters ) { var framebuffer = properties.get( renderTarget ).__webglFramebuffer; - if ( renderTarget.isWebGLRenderTargetCube && activeCubeFaceIndex !== undefined ) { + if ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) { framebuffer = framebuffer[ activeCubeFaceIndex ]; @@ -25341,13 +25988,18 @@ function WebGLRenderer( parameters ) { this.copyFramebufferToTexture = function ( position, texture, level ) { - var width = texture.image.width; - var height = texture.image.height; + if ( level === undefined ) level = 0; + + var levelScale = Math.pow( 2, - level ); + var width = Math.floor( texture.image.width * levelScale ); + var height = Math.floor( texture.image.height * levelScale ); var glFormat = utils.convert( texture.format ); textures.setTexture2D( texture, 0 ); - _gl.copyTexImage2D( 3553, level || 0, glFormat, position.x, position.y, width, height, 0 ); + _gl.copyTexImage2D( 3553, level, glFormat, position.x, position.y, width, height, 0 ); + + state.unbindTexture(); }; @@ -25370,6 +26022,16 @@ function WebGLRenderer( parameters ) { } + state.unbindTexture(); + + }; + + this.initTexture = function ( texture ) { + + textures.setTexture2D( texture, 0 ); + + state.unbindTexture(); + }; if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { @@ -25465,7 +26127,7 @@ function InterleavedBuffer( array, stride ) { this.stride = stride; this.count = array !== undefined ? array.length / stride : 0; - this.dynamic = false; + this.usage = StaticDrawUsage; this.updateRange = { offset: 0, count: - 1 }; this.version = 0; @@ -25488,24 +26150,9 @@ Object.assign( InterleavedBuffer.prototype, { onUploadCallback: function () {}, - setArray: function ( array ) { + setUsage: function ( value ) { - if ( Array.isArray( array ) ) { - - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - - } - - this.count = array !== undefined ? array.length / this.stride : 0; - this.array = array; - - return this; - - }, - - setDynamic: function ( value ) { - - this.dynamic = value; + this.usage = value; return this; @@ -25516,7 +26163,7 @@ Object.assign( InterleavedBuffer.prototype, { this.array = new source.array.constructor( source.array ); this.count = source.count; this.stride = source.stride; - this.dynamic = source.dynamic; + this.usage = source.usage; return this; @@ -25567,6 +26214,8 @@ Object.assign( InterleavedBuffer.prototype, { * @author benaadams / https://twitter.com/ben_a_adams */ +var _vector$6 = new Vector3(); + function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) { this.data = interleavedBuffer; @@ -25605,6 +26254,24 @@ Object.assign( InterleavedBufferAttribute.prototype, { isInterleavedBufferAttribute: true, + applyMatrix4: function ( m ) { + + for ( var i = 0, l = this.data.count; i < l; i ++ ) { + + _vector$6.x = this.getX( i ); + _vector$6.y = this.getY( i ); + _vector$6.z = this.getZ( i ); + + _vector$6.applyMatrix4( m ); + + this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z ); + + } + + return this; + + }, + setX: function ( index, x ) { this.data.array[ index * this.data.stride + this.offset ] = x; @@ -25705,6 +26372,7 @@ Object.assign( InterleavedBufferAttribute.prototype, { * parameters = { * color: , * map: new THREE.Texture( ), + * alphaMap: new THREE.Texture( ), * rotation: , * sizeAttenuation: * } @@ -25717,13 +26385,15 @@ function SpriteMaterial( parameters ) { this.type = 'SpriteMaterial'; this.color = new Color( 0xffffff ); + this.map = null; + this.alphaMap = null; + this.rotation = 0; this.sizeAttenuation = true; - this.lights = false; this.transparent = true; this.setValues( parameters ); @@ -25739,8 +26409,11 @@ SpriteMaterial.prototype.copy = function ( source ) { Material.prototype.copy.call( this, source ); this.color.copy( source.color ); + this.map = source.map; + this.alphaMap = source.alphaMap; + this.rotation = source.rotation; this.sizeAttenuation = source.sizeAttenuation; @@ -25792,8 +26465,8 @@ function Sprite( material ) { var interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); - _geometry.addAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); - _geometry.addAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); + _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); } @@ -25943,6 +26616,8 @@ function LOD() { Object3D.call( this ); + this._currentLevel = 0; + this.type = 'LOD'; Object.defineProperties( this, { @@ -25976,6 +26651,8 @@ LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { } + this.autoUpdate = source.autoUpdate; + return this; }, @@ -26006,31 +26683,49 @@ LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { }, + getCurrentLevel: function () { + + return this._currentLevel; + + }, + getObjectForDistance: function ( distance ) { var levels = this.levels; - for ( var i = 1, l = levels.length; i < l; i ++ ) { + if ( levels.length > 0 ) { - if ( distance < levels[ i ].distance ) { + for ( var i = 1, l = levels.length; i < l; i ++ ) { - break; + if ( distance < levels[ i ].distance ) { + + break; + + } } + return levels[ i - 1 ].object; + } - return levels[ i - 1 ].object; + return null; }, raycast: function ( raycaster, intersects ) { - _v1$4.setFromMatrixPosition( this.matrixWorld ); + var levels = this.levels; + + if ( levels.length > 0 ) { + + _v1$4.setFromMatrixPosition( this.matrixWorld ); + + var distance = raycaster.ray.origin.distanceTo( _v1$4 ); - var distance = raycaster.ray.origin.distanceTo( _v1$4 ); + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); - this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + } }, @@ -26043,7 +26738,7 @@ LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { _v1$4.setFromMatrixPosition( camera.matrixWorld ); _v2$2.setFromMatrixPosition( this.matrixWorld ); - var distance = _v1$4.distanceTo( _v2$2 ); + var distance = _v1$4.distanceTo( _v2$2 ) / camera.zoom; levels[ 0 ].object.visible = true; @@ -26062,6 +26757,8 @@ LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { } + this._currentLevel = i - 1; + for ( ; i < l; i ++ ) { levels[ i ].object.visible = false; @@ -26076,6 +26773,8 @@ LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { var data = Object3D.prototype.toJSON.call( this, meta ); + if ( this.autoUpdate === false ) data.object.autoUpdate = false; + data.object.levels = []; var levels = this.levels; @@ -26230,6 +26929,8 @@ function Skeleton( bones, boneInverses ) { this.bones = bones.slice( 0 ); this.boneMatrices = new Float32Array( this.bones.length * 16 ); + this.frame = - 1; + // use the supplied bone inverses or calculate the inverses if ( boneInverses === undefined ) { @@ -26403,6 +27104,94 @@ Bone.prototype = Object.assign( Object.create( Object3D.prototype ), { } ); +/** + * @author mrdoob / http://mrdoob.com/ + */ + +var _instanceLocalMatrix = new Matrix4(); +var _instanceWorldMatrix = new Matrix4(); + +var _instanceIntersects = []; + +var _mesh = new Mesh(); + +function InstancedMesh( geometry, material, count ) { + + Mesh.call( this, geometry, material ); + + this.instanceMatrix = new BufferAttribute( new Float32Array( count * 16 ), 16 ); + + this.count = count; + + this.frustumCulled = false; + +} + +InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), { + + constructor: InstancedMesh, + + isInstancedMesh: true, + + getMatrixAt: function ( index, matrix ) { + + matrix.fromArray( this.instanceMatrix.array, index * 16 ); + + }, + + raycast: function ( raycaster, intersects ) { + + var matrixWorld = this.matrixWorld; + var raycastTimes = this.count; + + _mesh.geometry = this.geometry; + _mesh.material = this.material; + + if ( _mesh.material === undefined ) return; + + for ( var instanceId = 0; instanceId < raycastTimes; instanceId ++ ) { + + // calculate the world matrix for each instance + + this.getMatrixAt( instanceId, _instanceLocalMatrix ); + + _instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix ); + + // the mesh represents this single instance + + _mesh.matrixWorld = _instanceWorldMatrix; + + _mesh.raycast( raycaster, _instanceIntersects ); + + // process the result of raycast + + if ( _instanceIntersects.length > 0 ) { + + _instanceIntersects[ 0 ].instanceId = instanceId; + _instanceIntersects[ 0 ].object = this; + + intersects.push( _instanceIntersects[ 0 ] ); + + _instanceIntersects.length = 0; + + } + + } + + }, + + setMatrixAt: function ( index, matrix ) { + + matrix.toArray( this.instanceMatrix.array, index * 16 ); + + }, + + updateMorphTargets: function () { + + } + +} ); + /** * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ @@ -26429,8 +27218,6 @@ function LineBasicMaterial( parameters ) { this.linecap = 'round'; this.linejoin = 'round'; - this.lights = false; - this.setValues( parameters ); } @@ -26477,7 +27264,7 @@ function Line( geometry, material, mode ) { this.type = 'Line'; this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new LineBasicMaterial( { color: Math.random() * 0xffffff } ); + this.material = material !== undefined ? material : new LineBasicMaterial(); } @@ -26510,7 +27297,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), { } - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); } else { @@ -26540,10 +27327,9 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), { raycast: function ( raycaster, intersects ) { - var precision = raycaster.linePrecision; - var geometry = this.geometry; var matrixWorld = this.matrixWorld; + var threshold = raycaster.params.Line.threshold; // Checking boundingSphere distance to ray @@ -26551,7 +27337,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), { _sphere$2.copy( geometry.boundingSphere ); _sphere$2.applyMatrix4( matrixWorld ); - _sphere$2.radius += precision; + _sphere$2.radius += threshold; if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) return; @@ -26560,8 +27346,8 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), { _inverseMatrix$1.getInverse( matrixWorld ); _ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 ); - var localPrecision = precision / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); - var localPrecisionSq = localPrecision * localPrecision; + var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); + var localThresholdSq = localThreshold * localThreshold; var vStart = new Vector3(); var vEnd = new Vector3(); @@ -26589,7 +27375,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), { var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - if ( distSq > localPrecisionSq ) continue; + if ( distSq > localThresholdSq ) continue; interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation @@ -26621,7 +27407,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), { var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - if ( distSq > localPrecisionSq ) continue; + if ( distSq > localThresholdSq ) continue; interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation @@ -26655,7 +27441,7 @@ Line.prototype = Object.assign( Object.create( Object3D.prototype ), { var distSq = _ray$1.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); - if ( distSq > localPrecisionSq ) continue; + if ( distSq > localThresholdSq ) continue; interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation @@ -26734,7 +27520,7 @@ LineSegments.prototype = Object.assign( Object.create( Line.prototype ), { } - geometry.addAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); + geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) ); } else { @@ -26793,6 +27579,7 @@ LineLoop.prototype = Object.assign( Object.create( Line.prototype ), { * color: , * opacity: , * map: new THREE.Texture( ), + * alphaMap: new THREE.Texture( ), * * size: , * sizeAttenuation: @@ -26811,13 +27598,13 @@ function PointsMaterial( parameters ) { this.map = null; + this.alphaMap = null; + this.size = 1; this.sizeAttenuation = true; this.morphTargets = false; - this.lights = false; - this.setValues( parameters ); } @@ -26835,6 +27622,8 @@ PointsMaterial.prototype.copy = function ( source ) { this.map = source.map; + this.alphaMap = source.alphaMap; + this.size = source.size; this.sizeAttenuation = source.sizeAttenuation; @@ -26860,7 +27649,7 @@ function Points( geometry, material ) { this.type = 'Points'; this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } ); + this.material = material !== undefined ? material : new PointsMaterial(); this.updateMorphTargets(); @@ -27307,7 +28096,7 @@ function WireframeGeometry( geometry ) { // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); } @@ -27319,7 +28108,7 @@ WireframeGeometry.prototype.constructor = WireframeGeometry; * @author Mugen87 / https://github.com/Mugen87 * * Parametric Surfaces Geometry - * based on the brilliant article by @prideout http://prideout.net/blog/?p=44 + * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html */ // ParametricGeometry @@ -27461,9 +28250,9 @@ function ParametricBufferGeometry( func, slices, stacks ) { // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -27537,9 +28326,9 @@ function PolyhedronBufferGeometry( vertices, indices, radius, detail ) { // build non-indexed geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) ); if ( detail === 0 ) { @@ -28150,9 +28939,9 @@ function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, clos // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // functions @@ -28440,9 +29229,9 @@ function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // this function calculates the current position on the torus curve @@ -28590,9 +29379,9 @@ function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -29536,8 +30325,8 @@ function ExtrudeBufferGeometry( shapes, options ) { // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) ); this.computeVertexNormals(); @@ -30504,9 +31293,9 @@ function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -30648,9 +31437,9 @@ function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegment // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -30707,7 +31496,7 @@ function LatheBufferGeometry( points, segments, phiStart, phiLength ) { // clamp phiLength so it's in range of [ 0, 2PI ] - phiLength = _Math.clamp( phiLength, 0, Math.PI * 2 ); + phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 ); // buffers @@ -30780,8 +31569,8 @@ function LatheBufferGeometry( points, segments, phiStart, phiLength ) { // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // generate normals @@ -30929,9 +31718,9 @@ function ShapeBufferGeometry( shapes, curveSegments ) { // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); // helper functions @@ -31070,7 +31859,7 @@ function EdgesGeometry( geometry, thresholdAngle ) { // helper variables - var thresholdDot = Math.cos( _Math.DEG2RAD * thresholdAngle ); + var thresholdDot = Math.cos( MathUtils.DEG2RAD * thresholdAngle ); var edge = [ 0, 0 ], edges = {}, edge1, edge2; var key, keys = [ 'a', 'b', 'c' ]; @@ -31146,7 +31935,7 @@ function EdgesGeometry( geometry, thresholdAngle ) { // build geometry - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); } @@ -31245,9 +32034,9 @@ function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); function generateTorso() { @@ -31615,9 +32404,9 @@ function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) { // build geometry this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); } @@ -31627,6 +32416,7 @@ CircleBufferGeometry.prototype.constructor = CircleBufferGeometry; var Geometries = /*#__PURE__*/Object.freeze({ + __proto__: null, WireframeGeometry: WireframeGeometry, ParametricGeometry: ParametricGeometry, ParametricBufferGeometry: ParametricBufferGeometry, @@ -31785,8 +32575,8 @@ function MeshStandardMaterial( parameters ) { this.type = 'MeshStandardMaterial'; this.color = new Color( 0xffffff ); // diffuse - this.roughness = 0.5; - this.metalness = 0.5; + this.roughness = 1.0; + this.metalness = 0.0; this.map = null; @@ -31831,6 +32621,8 @@ function MeshStandardMaterial( parameters ) { this.morphTargets = false; this.morphNormals = false; + this.vertexTangents = false; + this.setValues( parameters ); } @@ -31893,6 +32685,8 @@ MeshStandardMaterial.prototype.copy = function ( source ) { this.morphTargets = source.morphTargets; this.morphNormals = source.morphNormals; + this.vertexTangents = source.vertexTangents; + return this; }; @@ -31901,12 +32695,18 @@ MeshStandardMaterial.prototype.copy = function ( source ) { * @author WestLangley / http://github.com/WestLangley * * parameters = { - * reflectivity: - * clearCoat: - * clearCoatRoughness: + * clearcoat: , + * clearcoatMap: new THREE.Texture( ), + * clearcoatRoughness: , + * clearcoatRoughnessMap: new THREE.Texture( ), + * clearcoatNormalScale: , + * clearcoatNormalMap: new THREE.Texture( ), + * + * reflectivity: , * - * clearCoatNormalScale: , - * clearCoatNormalMap: new THREE.Texture( ), + * sheen: , + * + * transparency: * } */ @@ -31914,17 +32714,27 @@ function MeshPhysicalMaterial( parameters ) { MeshStandardMaterial.call( this ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; this.type = 'MeshPhysicalMaterial'; + this.clearcoat = 0.0; + this.clearcoatMap = null; + this.clearcoatRoughness = 0.0; + this.clearcoatRoughnessMap = null; + this.clearcoatNormalScale = new Vector2( 1, 1 ); + this.clearcoatNormalMap = null; + this.reflectivity = 0.5; // maps to F0 = 0.04 - this.clearCoat = 0.0; - this.clearCoatRoughness = 0.0; + this.sheen = null; // null will disable sheen bsdf - this.clearCoatNormalScale = new Vector2( 1, 1 ); - this.clearCoatNormalMap = null; + this.transparency = 0.0; this.setValues( parameters ); @@ -31939,15 +32749,33 @@ MeshPhysicalMaterial.prototype.copy = function ( source ) { MeshStandardMaterial.prototype.copy.call( this, source ); - this.defines = { 'PHYSICAL': '' }; + this.defines = { + + 'STANDARD': '', + 'PHYSICAL': '' + + }; + + this.clearcoat = source.clearcoat; + this.clearcoatMap = source.clearcoatMap; + this.clearcoatRoughness = source.clearcoatRoughness; + this.clearcoatRoughnessMap = source.clearcoatRoughnessMap; + this.clearcoatNormalMap = source.clearcoatNormalMap; + this.clearcoatNormalScale.copy( source.clearcoatNormalScale ); this.reflectivity = source.reflectivity; - this.clearCoat = source.clearCoat; - this.clearCoatRoughness = source.clearCoatRoughness; + if ( source.sheen ) { + + this.sheen = ( this.sheen || new Color() ).copy( source.sheen ); - this.clearCoatNormalMap = source.clearCoatNormalMap; - this.clearCoatNormalScale.copy( source.clearCoatNormalScale ); + } else { + + this.sheen = null; + + } + + this.transparency = source.transparency; return this; @@ -31991,7 +32819,7 @@ MeshPhysicalMaterial.prototype.copy = function ( source ) { * alphaMap: new THREE.Texture( ), * * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, + * combine: THREE.MultiplyOperation, * reflectivity: , * refractionRatio: , * @@ -32121,35 +32949,150 @@ MeshPhongMaterial.prototype.copy = function ( source ) { * @author takahirox / http://github.com/takahirox * * parameters = { - * gradientMap: new THREE.Texture( ) + * color: , + * specular: , + * shininess: , + * + * map: new THREE.Texture( ), + * gradientMap: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * emissive: , + * emissiveIntensity: + * emissiveMap: new THREE.Texture( ), + * + * bumpMap: new THREE.Texture( ), + * bumpScale: , + * + * normalMap: new THREE.Texture( ), + * normalMapType: THREE.TangentSpaceNormalMap, + * normalScale: , + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: , + * morphNormals: * } */ function MeshToonMaterial( parameters ) { - MeshPhongMaterial.call( this ); + Material.call( this ); this.defines = { 'TOON': '' }; this.type = 'MeshToonMaterial'; + this.color = new Color( 0xffffff ); + this.specular = new Color( 0x111111 ); + this.shininess = 30; + + this.map = null; this.gradientMap = null; + this.lightMap = null; + this.lightMapIntensity = 1.0; + + this.aoMap = null; + this.aoMapIntensity = 1.0; + + this.emissive = new Color( 0x000000 ); + this.emissiveIntensity = 1.0; + this.emissiveMap = null; + + this.bumpMap = null; + this.bumpScale = 1; + + this.normalMap = null; + this.normalMapType = TangentSpaceNormalMap; + this.normalScale = new Vector2( 1, 1 ); + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.specularMap = null; + + this.alphaMap = null; + + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; + + this.skinning = false; + this.morphTargets = false; + this.morphNormals = false; + this.setValues( parameters ); } -MeshToonMaterial.prototype = Object.create( MeshPhongMaterial.prototype ); +MeshToonMaterial.prototype = Object.create( Material.prototype ); MeshToonMaterial.prototype.constructor = MeshToonMaterial; MeshToonMaterial.prototype.isMeshToonMaterial = true; MeshToonMaterial.prototype.copy = function ( source ) { - MeshPhongMaterial.prototype.copy.call( this, source ); + Material.prototype.copy.call( this, source ); + + this.color.copy( source.color ); + this.specular.copy( source.specular ); + this.shininess = source.shininess; + this.map = source.map; this.gradientMap = source.gradientMap; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.emissive.copy( source.emissive ); + this.emissiveMap = source.emissiveMap; + this.emissiveIntensity = source.emissiveIntensity; + + this.bumpMap = source.bumpMap; + this.bumpScale = source.bumpScale; + + this.normalMap = source.normalMap; + this.normalMapType = source.normalMapType; + this.normalScale.copy( source.normalScale ); + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.specularMap = source.specularMap; + + this.alphaMap = source.alphaMap; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; + + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + this.morphNormals = source.morphNormals; + return this; }; @@ -32202,7 +33145,6 @@ function MeshNormalMaterial( parameters ) { this.wireframeLinewidth = 1; this.fog = false; - this.lights = false; this.skinning = false; this.morphTargets = false; @@ -32429,8 +33371,6 @@ function MeshMatcapMaterial( parameters ) { this.morphTargets = false; this.morphNormals = false; - this.lights = false; - this.setValues( parameters ); } @@ -32522,6 +33462,7 @@ LineDashedMaterial.prototype.copy = function ( source ) { var Materials = /*#__PURE__*/Object.freeze({ + __proto__: null, ShadowMaterial: ShadowMaterial, SpriteMaterial: SpriteMaterial, RawShaderMaterial: RawShaderMaterial, @@ -32702,6 +33643,79 @@ var AnimationUtils = { } + }, + + subclip: function ( sourceClip, name, startFrame, endFrame, fps ) { + + fps = fps || 30; + + var clip = sourceClip.clone(); + + clip.name = name; + + var tracks = []; + + for ( var i = 0; i < clip.tracks.length; ++ i ) { + + var track = clip.tracks[ i ]; + var valueSize = track.getValueSize(); + + var times = []; + var values = []; + + for ( var j = 0; j < track.times.length; ++ j ) { + + var frame = track.times[ j ] * fps; + + if ( frame < startFrame || frame >= endFrame ) continue; + + times.push( track.times[ j ] ); + + for ( var k = 0; k < valueSize; ++ k ) { + + values.push( track.values[ j * valueSize + k ] ); + + } + + } + + if ( times.length === 0 ) continue; + + track.times = AnimationUtils.convertArray( times, track.times.constructor ); + track.values = AnimationUtils.convertArray( values, track.values.constructor ); + + tracks.push( track ); + + } + + clip.tracks = tracks; + + // find minimum .times value across all tracks in the trimmed clip + + var minStartTime = Infinity; + + for ( var i = 0; i < clip.tracks.length; ++ i ) { + + if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) { + + minStartTime = clip.tracks[ i ].times[ 0 ]; + + } + + } + + // shift all tracks such that clip begins at t=0 + + for ( var i = 0; i < clip.tracks.length; ++ i ) { + + clip.tracks[ i ].shift( - 1 * minStartTime ); + + } + + clip.resetDuration(); + + return clip; + } }; @@ -33425,7 +34439,12 @@ Object.assign( KeyframeTrack.prototype, { if ( from !== 0 || to !== nKeys ) { // empty tracks are forbidden, so keep at least one keyframe - if ( from >= to ) to = Math.max( to, 1 ), from = to - 1; + if ( from >= to ) { + + to = Math.max( to, 1 ); + from = to - 1; + + } var stride = this.getValueSize(); this.times = AnimationUtils.arraySlice( times, from, to ); @@ -33518,8 +34537,9 @@ Object.assign( KeyframeTrack.prototype, { // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0) optimize: function () { - var times = this.times, - values = this.values, + // times or values may be shared with other tracks, so overwriting is unsafe + var times = AnimationUtils.arraySlice( this.times ), + values = AnimationUtils.arraySlice( this.values ), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth, @@ -33614,6 +34634,11 @@ Object.assign( KeyframeTrack.prototype, { this.times = AnimationUtils.arraySlice( times, 0, writeIndex ); this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride ); + } else { + + this.times = times; + this.values = values; + } return this; @@ -33875,7 +34900,7 @@ function AnimationClip( name, duration, tracks ) { this.tracks = tracks; this.duration = ( duration !== undefined ) ? duration : - 1; - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); // this means it should figure out its duration by scanning the tracks if ( this.duration < 0 ) { @@ -34300,7 +35325,6 @@ Object.assign( AnimationClip.prototype, { }, - clone: function () { var tracks = []; @@ -34373,6 +35397,7 @@ function LoadingManager( onLoad, onProgress, onError ) { var itemsLoaded = 0; var itemsTotal = 0; var urlModifier = undefined; + var handlers = []; // Refer to #5689 for the reason why we don't set .onStart // in the constructor @@ -34449,14 +35474,101 @@ function LoadingManager( onLoad, onProgress, onError ) { this.setURLModifier = function ( transform ) { urlModifier = transform; + return this; }; + this.addHandler = function ( regex, loader ) { + + handlers.push( regex, loader ); + + return this; + + }; + + this.removeHandler = function ( regex ) { + + var index = handlers.indexOf( regex ); + + if ( index !== - 1 ) { + + handlers.splice( index, 2 ); + + } + + return this; + + }; + + this.getHandler = function ( file ) { + + for ( var i = 0, l = handlers.length; i < l; i += 2 ) { + + var regex = handlers[ i ]; + var loader = handlers[ i + 1 ]; + + if ( regex.global ) regex.lastIndex = 0; // see #17920 + + if ( regex.test( file ) ) { + + return loader; + + } + + } + + return null; + + }; + } var DefaultLoadingManager = new LoadingManager(); +/** + * @author alteredq / http://alteredqualia.com/ + */ + +function Loader( manager ) { + + this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + + this.crossOrigin = 'anonymous'; + this.path = ''; + this.resourcePath = ''; + +} + +Object.assign( Loader.prototype, { + + load: function ( /* url, onLoad, onProgress, onError */ ) {}, + + parse: function ( /* data */ ) {}, + + setCrossOrigin: function ( crossOrigin ) { + + this.crossOrigin = crossOrigin; + return this; + + }, + + setPath: function ( path ) { + + this.path = path; + return this; + + }, + + setResourcePath: function ( resourcePath ) { + + this.resourcePath = resourcePath; + return this; + + } + +} ); + /** * @author mrdoob / http://mrdoob.com/ */ @@ -34465,11 +35577,13 @@ var loading = {}; function FileLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( FileLoader.prototype, { +FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: FileLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -34626,8 +35740,6 @@ Object.assign( FileLoader.prototype, { var response = this.response; - Cache.add( url, response ); - var callbacks = loading[ url ]; delete loading[ url ]; @@ -34639,6 +35751,10 @@ Object.assign( FileLoader.prototype, { if ( this.status === 0 ) console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); + // Add to cache only on HTTP success, so that we do not cache + // error response bodies as proper responses to requests. + Cache.add( url, response ); + for ( var i = 0, il = callbacks.length; i < il; i ++ ) { var callback = callbacks[ i ]; @@ -34734,13 +35850,6 @@ Object.assign( FileLoader.prototype, { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - setResponseType: function ( value ) { this.responseType = value; @@ -34777,11 +35886,13 @@ Object.assign( FileLoader.prototype, { function AnimationLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( AnimationLoader.prototype, { +AnimationLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: AnimationLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -34811,13 +35922,6 @@ Object.assign( AnimationLoader.prototype, { return animations; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -34826,18 +35930,19 @@ Object.assign( AnimationLoader.prototype, { * @author mrdoob / http://mrdoob.com/ * * Abstract Base class to block based textures loader (dds, pvr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). */ function CompressedTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - - // override in sub classes - this._parser = null; + Loader.call( this, manager ); } -Object.assign( CompressedTextureLoader.prototype, { +CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: CompressedTextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -34856,7 +35961,7 @@ Object.assign( CompressedTextureLoader.prototype, { loader.load( url[ i ], function ( buffer ) { - var texDatas = scope._parser( buffer, true ); + var texDatas = scope.parse( buffer, true ); images[ i ] = { width: texDatas.width, @@ -34899,7 +36004,7 @@ Object.assign( CompressedTextureLoader.prototype, { loader.load( url, function ( buffer ) { - var texDatas = scope._parser( buffer, true ); + var texDatas = scope.parse( buffer, true ); if ( texDatas.isCubemap ) { @@ -34945,13 +36050,6 @@ Object.assign( CompressedTextureLoader.prototype, { return texture; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -34960,18 +36058,19 @@ Object.assign( CompressedTextureLoader.prototype, { * @author Nikos M. / https://github.com/foo123/ * * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...) + * + * Sub classes have to implement the parse() method which will be used in load(). */ function DataTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - - // override in sub classes - this._parser = null; + Loader.call( this, manager ); } -Object.assign( DataTextureLoader.prototype, { +DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: DataTextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -34984,7 +36083,7 @@ Object.assign( DataTextureLoader.prototype, { loader.setPath( this.path ); loader.load( url, function ( buffer ) { - var texData = scope._parser( buffer ); + var texData = scope.parse( buffer ); if ( ! texData ) return; @@ -35004,7 +36103,7 @@ Object.assign( DataTextureLoader.prototype, { texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping; texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter; - texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearMipmapLinearFilter; + texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter; texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1; @@ -35022,6 +36121,7 @@ Object.assign( DataTextureLoader.prototype, { if ( texData.mipmaps !== undefined ) { texture.mipmaps = texData.mipmaps; + texture.minFilter = LinearMipmapLinearFilter; // presumably... } @@ -35040,13 +36140,6 @@ Object.assign( DataTextureLoader.prototype, { return texture; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35055,21 +36148,18 @@ Object.assign( DataTextureLoader.prototype, { * @author mrdoob / http://mrdoob.com/ */ - function ImageLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( ImageLoader.prototype, { +ImageLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: ImageLoader, load: function ( url, onLoad, onProgress, onError ) { - if ( url === undefined ) url = ''; - if ( this.path !== undefined ) url = this.path + url; url = this.manager.resolveURL( url ); @@ -35136,20 +36226,6 @@ Object.assign( ImageLoader.prototype, { return image; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35161,13 +36237,13 @@ Object.assign( ImageLoader.prototype, { function CubeTextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( CubeTextureLoader.prototype, { +CubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: CubeTextureLoader, load: function ( urls, onLoad, onProgress, onError ) { @@ -35207,20 +36283,6 @@ Object.assign( CubeTextureLoader.prototype, { return texture; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35229,16 +36291,15 @@ Object.assign( CubeTextureLoader.prototype, { * @author mrdoob / http://mrdoob.com/ */ - function TextureLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( TextureLoader.prototype, { +TextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: TextureLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -35268,20 +36329,6 @@ Object.assign( TextureLoader.prototype, { return texture; - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -35623,7 +36670,7 @@ Object.assign( Curve.prototype, { vec.normalize(); - theta = Math.acos( _Math.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors + theta = Math.acos( MathUtils.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) ); @@ -35637,7 +36684,7 @@ Object.assign( Curve.prototype, { if ( closed === true ) { - theta = Math.acos( _Math.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); + theta = Math.acos( MathUtils.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) ); theta /= segments; if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) { @@ -36736,6 +37783,7 @@ SplineCurve.prototype.fromJSON = function ( json ) { var Curves = /*#__PURE__*/Object.freeze({ + __proto__: null, ArcCurve: ArcCurve, CatmullRomCurve3: CatmullRomCurve3, CubicBezierCurve: CubicBezierCurve, @@ -37039,12 +38087,16 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { } + return this; + }, moveTo: function ( x, y ) { this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying? + return this; + }, lineTo: function ( x, y ) { @@ -37054,6 +38106,8 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { this.currentPoint.set( x, y ); + return this; + }, quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { @@ -37068,6 +38122,8 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { this.currentPoint.set( aX, aY ); + return this; + }, bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { @@ -37083,6 +38139,8 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { this.currentPoint.set( aX, aY ); + return this; + }, splineThru: function ( pts /*Array of Vector*/ ) { @@ -37094,6 +38152,8 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { this.currentPoint.copy( pts[ pts.length - 1 ] ); + return this; + }, arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { @@ -37104,12 +38164,16 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { this.absarc( aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise ); + return this; + }, absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) { this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise ); + return this; + }, ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { @@ -37119,6 +38183,8 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ); + return this; + }, absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) { @@ -37143,6 +38209,8 @@ Path.prototype = Object.assign( Object.create( CurvePath.prototype ), { var lastPoint = curve.getPoint( 1 ); this.currentPoint.copy( lastPoint ); + return this; + }, copy: function ( source ) { @@ -37192,7 +38260,7 @@ function Shape( points ) { Path.call( this, points ); - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); this.type = 'Shape'; @@ -37395,12 +38463,84 @@ function LightShadow( camera ) { this.mapSize = new Vector2( 512, 512 ); this.map = null; + this.mapPass = null; this.matrix = new Matrix4(); + this._frustum = new Frustum(); + this._frameExtents = new Vector2( 1, 1 ); + + this._viewportCount = 1; + + this._viewports = [ + + new Vector4( 0, 0, 1, 1 ) + + ]; + } Object.assign( LightShadow.prototype, { + _projScreenMatrix: new Matrix4(), + + _lightPositionWorld: new Vector3(), + + _lookTarget: new Vector3(), + + getViewportCount: function () { + + return this._viewportCount; + + }, + + getFrustum: function () { + + return this._frustum; + + }, + + updateMatrices: function ( light ) { + + var shadowCamera = this.camera, + shadowMatrix = this.matrix, + projScreenMatrix = this._projScreenMatrix, + lookTarget = this._lookTarget, + lightPositionWorld = this._lightPositionWorld; + + lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + shadowCamera.position.copy( lightPositionWorld ); + + lookTarget.setFromMatrixPosition( light.target.matrixWorld ); + shadowCamera.lookAt( lookTarget ); + shadowCamera.updateMatrixWorld(); + + projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); + this._frustum.setFromProjectionMatrix( projScreenMatrix ); + + shadowMatrix.set( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0 + ); + + shadowMatrix.multiply( shadowCamera.projectionMatrix ); + shadowMatrix.multiply( shadowCamera.matrixWorldInverse ); + + }, + + getViewport: function ( viewportIndex ) { + + return this._viewports[ viewportIndex ]; + + }, + + getFrameExtents: function () { + + return this._frameExtents; + + }, + copy: function ( source ) { this.camera = source.camera.clone(); @@ -37453,11 +38593,11 @@ SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype isSpotLightShadow: true, - update: function ( light ) { + updateMatrices: function ( light ) { var camera = this.camera; - var fov = _Math.RAD2DEG * 2 * light.angle; + var fov = MathUtils.RAD2DEG * 2 * light.angle; var aspect = this.mapSize.width / this.mapSize.height; var far = light.distance || camera.far; @@ -37470,6 +38610,8 @@ SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype } + LightShadow.prototype.updateMatrices.call( this, light ); + } } ); @@ -37540,6 +38682,88 @@ SpotLight.prototype = Object.assign( Object.create( Light.prototype ), { } ); +function PointLightShadow() { + + LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) ); + + this._frameExtents = new Vector2( 4, 2 ); + + this._viewportCount = 6; + + this._viewports = [ + // These viewports map a cube-map onto a 2D texture with the + // following orientation: + // + // xzXZ + // y Y + // + // X - Positive x direction + // x - Negative x direction + // Y - Positive y direction + // y - Negative y direction + // Z - Positive z direction + // z - Negative z direction + + // positive X + new Vector4( 2, 1, 1, 1 ), + // negative X + new Vector4( 0, 1, 1, 1 ), + // positive Z + new Vector4( 3, 1, 1, 1 ), + // negative Z + new Vector4( 1, 1, 1, 1 ), + // positive Y + new Vector4( 3, 0, 1, 1 ), + // negative Y + new Vector4( 1, 0, 1, 1 ) + ]; + + this._cubeDirections = [ + new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ), + new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 ) + ]; + + this._cubeUps = [ + new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), + new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 ) + ]; + +} + +PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { + + constructor: PointLightShadow, + + isPointLightShadow: true, + + updateMatrices: function ( light, viewportIndex ) { + + if ( viewportIndex === undefined ) viewportIndex = 0; + + var camera = this.camera, + shadowMatrix = this.matrix, + lightPositionWorld = this._lightPositionWorld, + lookTarget = this._lookTarget, + projScreenMatrix = this._projScreenMatrix; + + lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + camera.position.copy( lightPositionWorld ); + + lookTarget.copy( camera.position ); + lookTarget.add( this._cubeDirections[ viewportIndex ] ); + camera.up.copy( this._cubeUps[ viewportIndex ] ); + camera.lookAt( lookTarget ); + camera.updateMatrixWorld(); + + shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z ); + + projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); + this._frustum.setFromProjectionMatrix( projScreenMatrix ); + + } + +} ); + /** * @author mrdoob / http://mrdoob.com/ */ @@ -37571,7 +38795,7 @@ function PointLight( color, intensity, distance, decay ) { this.distance = ( distance !== undefined ) ? distance : 0; this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. - this.shadow = new LightShadow( new PerspectiveCamera( 90, 1, 0.5, 500 ) ); + this.shadow = new PointLightShadow(); } @@ -37700,15 +38924,13 @@ OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), if ( this.view !== null && this.view.enabled ) { - var zoomW = this.zoom / ( this.view.width / this.view.fullWidth ); - var zoomH = this.zoom / ( this.view.height / this.view.fullHeight ); - var scaleW = ( this.right - this.left ) / this.view.width; - var scaleH = ( this.top - this.bottom ) / this.view.height; + var scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom; + var scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom; - left += scaleW * ( this.view.offsetX / zoomW ); - right = left + scaleW * ( this.view.width / zoomW ); - top -= scaleH * ( this.view.offsetY / zoomH ); - bottom = top - scaleH * ( this.view.height / zoomH ); + left += scaleW * this.view.offsetX; + right = left + scaleW * this.view.width; + top -= scaleH * this.view.offsetY; + bottom = top - scaleH * this.view.height; } @@ -37742,7 +38964,7 @@ OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), * @author mrdoob / http://mrdoob.com/ */ -function DirectionalLightShadow( ) { +function DirectionalLightShadow() { LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); @@ -37750,7 +38972,15 @@ function DirectionalLightShadow( ) { DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), { - constructor: DirectionalLightShadow + constructor: DirectionalLightShadow, + + isDirectionalLightShadow: true, + + updateMatrices: function ( light ) { + + LightShadow.prototype.updateMatrices.call( this, light ); + + } } ); @@ -37867,12 +39097,15 @@ RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), { function MaterialLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); + this.textures = {}; } -Object.assign( MaterialLoader.prototype, { +MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: MaterialLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -37911,12 +39144,12 @@ Object.assign( MaterialLoader.prototype, { if ( json.color !== undefined ) material.color.setHex( json.color ); if ( json.roughness !== undefined ) material.roughness = json.roughness; if ( json.metalness !== undefined ) material.metalness = json.metalness; + if ( json.sheen !== undefined ) material.sheen = new Color().setHex( json.sheen ); if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive ); if ( json.specular !== undefined ) material.specular.setHex( json.specular ); if ( json.shininess !== undefined ) material.shininess = json.shininess; - if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat; - if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness; - if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors; + if ( json.clearcoat !== undefined ) material.clearcoat = json.clearcoat; + if ( json.clearcoatRoughness !== undefined ) material.clearcoatRoughness = json.clearcoatRoughness; if ( json.fog !== undefined ) material.fog = json.fog; if ( json.flatShading !== undefined ) material.flatShading = json.flatShading; if ( json.blending !== undefined ) material.blending = json.blending; @@ -37928,6 +39161,16 @@ Object.assign( MaterialLoader.prototype, { if ( json.depthTest !== undefined ) material.depthTest = json.depthTest; if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite; if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite; + + if ( json.stencilWrite !== undefined ) material.stencilWrite = json.stencilWrite; + if ( json.stencilWriteMask !== undefined ) material.stencilWriteMask = json.stencilWriteMask; + if ( json.stencilFunc !== undefined ) material.stencilFunc = json.stencilFunc; + if ( json.stencilRef !== undefined ) material.stencilRef = json.stencilRef; + if ( json.stencilFuncMask !== undefined ) material.stencilFuncMask = json.stencilFuncMask; + if ( json.stencilFail !== undefined ) material.stencilFail = json.stencilFail; + if ( json.stencilZFail !== undefined ) material.stencilZFail = json.stencilZFail; + if ( json.stencilZPass !== undefined ) material.stencilZPass = json.stencilZPass; + if ( json.wireframe !== undefined ) material.wireframe = json.wireframe; if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth; if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap; @@ -37949,9 +39192,28 @@ Object.assign( MaterialLoader.prototype, { if ( json.morphNormals !== undefined ) material.morphNormals = json.morphNormals; if ( json.dithering !== undefined ) material.dithering = json.dithering; + if ( json.vertexTangents !== undefined ) material.vertexTangents = json.vertexTangents; + if ( json.visible !== undefined ) material.visible = json.visible; + + if ( json.toneMapped !== undefined ) material.toneMapped = json.toneMapped; + if ( json.userData !== undefined ) material.userData = json.userData; + if ( json.vertexColors !== undefined ) { + + if ( typeof json.vertexColors === 'number' ) { + + material.vertexColors = ( json.vertexColors > 0 ) ? true : false; + + } else { + + material.vertexColors = json.vertexColors; + + } + + } + // Shader Material if ( json.uniforms !== undefined ) { @@ -38028,12 +39290,7 @@ Object.assign( MaterialLoader.prototype, { if ( json.map !== undefined ) material.map = getTexture( json.map ); if ( json.matcap !== undefined ) material.matcap = getTexture( json.matcap ); - if ( json.alphaMap !== undefined ) { - - material.alphaMap = getTexture( json.alphaMap ); - material.transparent = true; - - } + if ( json.alphaMap !== undefined ) material.alphaMap = getTexture( json.alphaMap ); if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap ); if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale; @@ -38082,20 +39339,15 @@ Object.assign( MaterialLoader.prototype, { if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap ); - if ( json.clearCoatNormalMap !== undefined ) material.clearCoatNormalMap = getTexture( json.clearCoatNormalMap ); - if ( json.clearCoatNormalScale !== undefined ) material.clearCoatNormalScale = new Vector2().fromArray( json.clearCoatNormalScale ); + if ( json.clearcoatMap !== undefined ) material.clearcoatMap = getTexture( json.clearcoatMap ); + if ( json.clearcoatRoughnessMap !== undefined ) material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap ); + if ( json.clearcoatNormalMap !== undefined ) material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); + if ( json.clearcoatNormalScale !== undefined ) material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); return material; }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - setTextures: function ( value ) { this.textures = value; @@ -38264,11 +39516,13 @@ InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribu function BufferGeometryLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( BufferGeometryLoader.prototype, { +BufferGeometryLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: BufferGeometryLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -38306,7 +39560,7 @@ Object.assign( BufferGeometryLoader.prototype, { var bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute; var bufferAttribute = new bufferAttributeConstr( typedArray, attribute.itemSize, attribute.normalized ); if ( attribute.name !== undefined ) bufferAttribute.name = attribute.name; - geometry.addAttribute( key, bufferAttribute ); + geometry.setAttribute( key, bufferAttribute ); } @@ -38337,6 +39591,14 @@ Object.assign( BufferGeometryLoader.prototype, { } + var morphTargetsRelative = json.data.morphTargetsRelative; + + if ( morphTargetsRelative ) { + + geometry.morphTargetsRelative = true; + + } + var groups = json.data.groups || json.data.drawcalls || json.data.offsets; if ( groups !== undefined ) { @@ -38372,13 +39634,6 @@ Object.assign( BufferGeometryLoader.prototype, { return geometry; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -38402,20 +39657,19 @@ var TYPED_ARRAYS = { function ObjectLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; - this.resourcePath = ''; + Loader.call( this, manager ); } -Object.assign( ObjectLoader.prototype, { +ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), { - crossOrigin: 'anonymous', + constructor: ObjectLoader, load: function ( url, onLoad, onProgress, onError ) { var scope = this; - var path = ( this.path === undefined ) ? LoaderUtils.extractUrlBase( url ) : this.path; + var path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path; this.resourcePath = this.resourcePath || path; var loader = new FileLoader( scope.manager ); @@ -38453,27 +39707,6 @@ Object.assign( ObjectLoader.prototype, { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - parse: function ( json, onLoad ) { var shapes = this.parseShape( json.shapes ); @@ -38780,17 +40013,7 @@ Object.assign( ObjectLoader.prototype, { case 'Geometry': - if ( 'THREE' in window && 'LegacyJSONLoader' in THREE ) { - - var geometryLoader = new THREE.LegacyJSONLoader(); - geometry = geometryLoader.parse( data, this.resourcePath ).geometry; - - - } else { - - console.error( 'THREE.ObjectLoader: You have to import LegacyJSONLoader in order load geometry data of type "Geometry".' ); - - } + console.error( 'THREE.ObjectLoader: Loading "Geometry" is not supported anymore.' ); break; @@ -39208,7 +40431,17 @@ Object.assign( ObjectLoader.prototype, { } - if ( data.drawMode !== undefined ) object.setDrawMode( data.drawMode ); + break; + + case 'InstancedMesh': + + var geometry = getGeometry( data.geometry ); + var material = getMaterial( data.material ); + var count = data.count; + var instanceMatrix = data.instanceMatrix; + + object = new InstancedMesh( geometry, material, count ); + object.instanceMatrix = new BufferAttribute( new Float32Array( instanceMatrix.array ), 16 ); break; @@ -39313,6 +40546,8 @@ Object.assign( ObjectLoader.prototype, { if ( data.type === 'LOD' ) { + if ( data.autoUpdate !== undefined ) object.autoUpdate = data.autoUpdate; + var levels = data.levels; for ( var l = 0; l < levels.length; l ++ ) { @@ -39381,12 +40616,13 @@ function ImageBitmapLoader( manager ) { } - this.manager = manager !== undefined ? manager : DefaultLoadingManager; + Loader.call( this, manager ); + this.options = undefined; } -ImageBitmapLoader.prototype = { +ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ), { constructor: ImageBitmapLoader, @@ -39462,22 +40698,9 @@ ImageBitmapLoader.prototype = { scope.manager.itemStart( url ); - }, - - setCrossOrigin: function ( /* value */ ) { - - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } -}; +} ); /** * @author zz85 / http://www.lab4games.net/zz85/blog @@ -39503,30 +40726,40 @@ Object.assign( ShapePath.prototype, { this.subPaths.push( this.currentPath ); this.currentPath.moveTo( x, y ); + return this; + }, lineTo: function ( x, y ) { this.currentPath.lineTo( x, y ); + return this; + }, quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) { this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY ); + return this; + }, bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) { this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ); + return this; + }, splineThru: function ( pts ) { this.currentPath.splineThru( pts ); + return this; + }, toShapes: function ( isCCW, noHoles ) { @@ -39797,7 +41030,7 @@ Object.assign( Font.prototype, { function createPaths( text, size, data ) { - var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // see #13988 + var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // workaround for IE11, see #13988 var scale = size / data.resolution; var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale; @@ -39912,11 +41145,13 @@ function createPath( char, scale, offsetX, offsetY, data ) { function FontLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( FontLoader.prototype, { +FontLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: FontLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -39951,332 +41186,10 @@ Object.assign( FontLoader.prototype, { return new Font( json ); - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); -/** - * @author alteredq / http://alteredqualia.com/ - */ - -var _BlendingMode = { - NoBlending: NoBlending, - NormalBlending: NormalBlending, - AdditiveBlending: AdditiveBlending, - SubtractiveBlending: SubtractiveBlending, - MultiplyBlending: MultiplyBlending, - CustomBlending: CustomBlending -}; - -var _color = new Color(); -var _textureLoader = new TextureLoader(); -var _materialLoader = new MaterialLoader(); - -function Loader() {} - -Loader.Handlers = { - - handlers: [], - - add: function ( regex, loader ) { - - this.handlers.push( regex, loader ); - - }, - - get: function ( file ) { - - var handlers = this.handlers; - - for ( var i = 0, l = handlers.length; i < l; i += 2 ) { - - var regex = handlers[ i ]; - var loader = handlers[ i + 1 ]; - - if ( regex.test( file ) ) { - - return loader; - - } - - } - - return null; - - } - -}; - -Object.assign( Loader.prototype, { - - crossOrigin: 'anonymous', - - onLoadStart: function () {}, - - onLoadProgress: function () {}, - - onLoadComplete: function () {}, - - initMaterials: function ( materials, texturePath, crossOrigin ) { - - var array = []; - - for ( var i = 0; i < materials.length; ++ i ) { - - array[ i ] = this.createMaterial( materials[ i ], texturePath, crossOrigin ); - - } - - return array; - - }, - - createMaterial: function ( m, texturePath, crossOrigin ) { - - // convert from old material format - - var textures = {}; - - // - - var json = { - uuid: _Math.generateUUID(), - type: 'MeshLambertMaterial' - }; - - for ( var name in m ) { - - var value = m[ name ]; - - switch ( name ) { - - case 'DbgColor': - case 'DbgIndex': - case 'opticalDensity': - case 'illumination': - break; - case 'DbgName': - json.name = value; - break; - case 'blending': - json.blending = _BlendingMode[ value ]; - break; - case 'colorAmbient': - case 'mapAmbient': - console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); - break; - case 'colorDiffuse': - json.color = _color.fromArray( value ).getHex(); - break; - case 'colorSpecular': - json.specular = _color.fromArray( value ).getHex(); - break; - case 'colorEmissive': - json.emissive = _color.fromArray( value ).getHex(); - break; - case 'specularCoef': - json.shininess = value; - break; - case 'shading': - if ( value.toLowerCase() === 'basic' ) json.type = 'MeshBasicMaterial'; - if ( value.toLowerCase() === 'phong' ) json.type = 'MeshPhongMaterial'; - if ( value.toLowerCase() === 'standard' ) json.type = 'MeshStandardMaterial'; - break; - case 'mapDiffuse': - json.map = loadTexture( value, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapDiffuseRepeat': - case 'mapDiffuseOffset': - case 'mapDiffuseWrap': - case 'mapDiffuseAnisotropy': - break; - case 'mapEmissive': - json.emissiveMap = loadTexture( value, m.mapEmissiveRepeat, m.mapEmissiveOffset, m.mapEmissiveWrap, m.mapEmissiveAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapEmissiveRepeat': - case 'mapEmissiveOffset': - case 'mapEmissiveWrap': - case 'mapEmissiveAnisotropy': - break; - case 'mapLight': - json.lightMap = loadTexture( value, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapLightRepeat': - case 'mapLightOffset': - case 'mapLightWrap': - case 'mapLightAnisotropy': - break; - case 'mapAO': - json.aoMap = loadTexture( value, m.mapAORepeat, m.mapAOOffset, m.mapAOWrap, m.mapAOAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapAORepeat': - case 'mapAOOffset': - case 'mapAOWrap': - case 'mapAOAnisotropy': - break; - case 'mapBump': - json.bumpMap = loadTexture( value, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapBumpScale': - json.bumpScale = value; - break; - case 'mapBumpRepeat': - case 'mapBumpOffset': - case 'mapBumpWrap': - case 'mapBumpAnisotropy': - break; - case 'mapNormal': - json.normalMap = loadTexture( value, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapNormalFactor': - json.normalScale = value; - break; - case 'mapNormalRepeat': - case 'mapNormalOffset': - case 'mapNormalWrap': - case 'mapNormalAnisotropy': - break; - case 'mapSpecular': - json.specularMap = loadTexture( value, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapSpecularRepeat': - case 'mapSpecularOffset': - case 'mapSpecularWrap': - case 'mapSpecularAnisotropy': - break; - case 'mapMetalness': - json.metalnessMap = loadTexture( value, m.mapMetalnessRepeat, m.mapMetalnessOffset, m.mapMetalnessWrap, m.mapMetalnessAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapMetalnessRepeat': - case 'mapMetalnessOffset': - case 'mapMetalnessWrap': - case 'mapMetalnessAnisotropy': - break; - case 'mapRoughness': - json.roughnessMap = loadTexture( value, m.mapRoughnessRepeat, m.mapRoughnessOffset, m.mapRoughnessWrap, m.mapRoughnessAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapRoughnessRepeat': - case 'mapRoughnessOffset': - case 'mapRoughnessWrap': - case 'mapRoughnessAnisotropy': - break; - case 'mapAlpha': - json.alphaMap = loadTexture( value, m.mapAlphaRepeat, m.mapAlphaOffset, m.mapAlphaWrap, m.mapAlphaAnisotropy, textures, texturePath, crossOrigin ); - break; - case 'mapAlphaRepeat': - case 'mapAlphaOffset': - case 'mapAlphaWrap': - case 'mapAlphaAnisotropy': - break; - case 'flipSided': - json.side = BackSide; - break; - case 'doubleSided': - json.side = DoubleSide; - break; - case 'transparency': - console.warn( 'THREE.Loader.createMaterial: transparency has been renamed to opacity' ); - json.opacity = value; - break; - case 'depthTest': - case 'depthWrite': - case 'colorWrite': - case 'opacity': - case 'reflectivity': - case 'transparent': - case 'visible': - case 'wireframe': - json[ name ] = value; - break; - case 'vertexColors': - if ( value === true ) json.vertexColors = VertexColors; - if ( value === 'face' ) json.vertexColors = FaceColors; - break; - default: - console.error( 'THREE.Loader.createMaterial: Unsupported', name, value ); - break; - - } - - } - - if ( json.type === 'MeshBasicMaterial' ) delete json.emissive; - if ( json.type !== 'MeshPhongMaterial' ) delete json.specular; - - if ( json.opacity < 1 ) json.transparent = true; - - _materialLoader.setTextures( textures ); - - return _materialLoader.parse( json ); - - } - -} ); - -function loadTexture( path, repeat, offset, wrap, anisotropy, textures, texturePath, crossOrigin ) { - - var fullPath = texturePath + path; - var loader = Loader.Handlers.get( fullPath ); - - var texture; - - if ( loader !== null ) { - - texture = loader.load( fullPath ); - - } else { - - _textureLoader.setCrossOrigin( crossOrigin ); - texture = _textureLoader.load( fullPath ); - - } - - if ( repeat !== undefined ) { - - texture.repeat.fromArray( repeat ); - - if ( repeat[ 0 ] !== 1 ) texture.wrapS = RepeatWrapping; - if ( repeat[ 1 ] !== 1 ) texture.wrapT = RepeatWrapping; - - } - - if ( offset !== undefined ) { - - texture.offset.fromArray( offset ); - - } - - if ( wrap !== undefined ) { - - if ( wrap[ 0 ] === 'repeat' ) texture.wrapS = RepeatWrapping; - if ( wrap[ 0 ] === 'mirror' ) texture.wrapS = MirroredRepeatWrapping; - - if ( wrap[ 1 ] === 'repeat' ) texture.wrapT = RepeatWrapping; - if ( wrap[ 1 ] === 'mirror' ) texture.wrapT = MirroredRepeatWrapping; - - } - - if ( anisotropy !== undefined ) { - - texture.anisotropy = anisotropy; - - } - - var uuid = _Math.generateUUID(); - - textures[ uuid ] = texture; - - return uuid; - -} - /** * @author mrdoob / http://mrdoob.com/ */ @@ -40311,11 +41224,13 @@ var AudioContext = { function AudioLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager; + Loader.call( this, manager ); } -Object.assign( AudioLoader.prototype, { +AudioLoader.prototype = Object.assign( Object.create( Loader.prototype ), { + + constructor: AudioLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -40337,13 +41252,6 @@ Object.assign( AudioLoader.prototype, { }, onProgress, onError ); - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } } ); @@ -40525,13 +41433,15 @@ Object.assign( SphericalHarmonics3.prototype, { }, - fromArray: function ( array ) { + fromArray: function ( array, offset ) { + + if ( offset === undefined ) offset = 0; var coefficients = this.coefficients; for ( var i = 0; i < 9; i ++ ) { - coefficients[ i ].fromArray( array, i * 3 ); + coefficients[ i ].fromArray( array, offset + ( i * 3 ) ); } @@ -40539,14 +41449,16 @@ Object.assign( SphericalHarmonics3.prototype, { }, - toArray: function () { + toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - var array = []; var coefficients = this.coefficients; for ( var i = 0; i < 9; i ++ ) { - coefficients[ i ].toArray( array, i * 3 ); + coefficients[ i ].toArray( array, offset + ( i * 3 ) ); } @@ -40779,7 +41691,7 @@ Object.assign( StereoCamera.prototype, { var projectionMatrix = camera.projectionMatrix.clone(); var eyeSepHalf = cache.eyeSep / 2; var eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus; - var ymax = ( cache.near * Math.tan( _Math.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom; + var ymax = ( cache.near * Math.tan( MathUtils.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom; var xmin, xmax; // translate xOffset @@ -41045,13 +41957,18 @@ function Audio( listener ) { this.buffer = null; this.detune = 0; this.loop = false; - this.startTime = 0; + this.loopStart = 0; + this.loopEnd = 0; this.offset = 0; + this.duration = undefined; this.playbackRate = 1; this.isPlaying = false; this.hasPlaybackControl = true; this.sourceType = 'empty'; + this._startedAt = 0; + this._pausedAt = 0; + this.filters = []; } @@ -41088,6 +42005,17 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { }, + setMediaStreamSource: function ( mediaStream ) { + + this.hasPlaybackControl = false; + this.sourceType = 'mediaStreamNode'; + this.source = this.context.createMediaStreamSource( mediaStream ); + this.connect(); + + return this; + + }, + setBuffer: function ( audioBuffer ) { this.buffer = audioBuffer; @@ -41099,7 +42027,9 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { }, - play: function () { + play: function ( delay ) { + + if ( delay === undefined ) delay = 0; if ( this.isPlaying === true ) { @@ -41115,13 +42045,15 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { } - var source = this.context.createBufferSource(); + this._startedAt = this.context.currentTime + delay; + var source = this.context.createBufferSource(); source.buffer = this.buffer; source.loop = this.loop; + source.loopStart = this.loopStart; + source.loopEnd = this.loopEnd; source.onended = this.onEnded.bind( this ); - this.startTime = this.context.currentTime; - source.start( this.startTime, this.offset ); + source.start( this._startedAt, this._pausedAt + this.offset, this.duration ); this.isPlaying = true; @@ -41145,9 +42077,11 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { if ( this.isPlaying === true ) { + this._pausedAt += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate; + this.source.stop(); this.source.onended = null; - this.offset += ( this.context.currentTime - this.startTime ) * this.playbackRate; + this.isPlaying = false; } @@ -41165,9 +42099,10 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { } + this._pausedAt = 0; + this.source.stop(); this.source.onended = null; - this.offset = 0; this.isPlaying = false; return this; @@ -41349,6 +42284,22 @@ Audio.prototype = Object.assign( Object.create( Object3D.prototype ), { }, + setLoopStart: function ( value ) { + + this.loopStart = value; + + return this; + + }, + + setLoopEnd: function ( value ) { + + this.loopEnd = value; + + return this; + + }, + getVolume: function () { return this.gain.gain.value; @@ -41942,7 +42893,7 @@ Object.assign( PropertyBinding, { findNode: function ( root, nodeName ) { - if ( ! nodeName || nodeName === "" || nodeName === "root" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { + if ( ! nodeName || nodeName === "" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) { return root; @@ -42488,7 +43439,7 @@ Object.assign( PropertyBinding.prototype, { function AnimationObjectGroup() { - this.uuid = _Math.generateUUID(); + this.uuid = MathUtils.generateUUID(); // cached objects followed by the active ones this._objects = Array.prototype.slice.call( arguments ); @@ -44163,6 +45114,20 @@ AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototy }, + // Allows you to seek to a specific time in an animation. + setTime: function ( timeInSeconds ) { + + this.time = 0; // Zero out time attribute for AnimationMixer object; + for ( var i = 0; i < this._actions.length; i ++ ) { + + this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects. + + } + + return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object. + + }, + // return this mixer's root target object getRoot: function () { @@ -44332,10 +45297,11 @@ function Raycaster( origin, direction, near, far ) { this.near = near || 0; this.far = far || Infinity; this.camera = null; + this.layers = new Layers(); this.params = { Mesh: {}, - Line: {}, + Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} @@ -44362,9 +45328,11 @@ function ascSort( a, b ) { function intersectObject( object, raycaster, intersects, recursive ) { - if ( object.visible === false ) return; + if ( object.layers.test( raycaster.layers ) ) { + + object.raycast( raycaster, intersects ); - object.raycast( raycaster, intersects ); + } if ( recursive === true ) { @@ -44382,8 +45350,6 @@ function intersectObject( object, raycaster, intersects, recursive ) { Object.assign( Raycaster.prototype, { - linePrecision: 1, - set: function ( origin, direction ) { // direction is assumed to be normalized (for accurate distance calculations) @@ -44458,7 +45424,7 @@ Object.assign( Raycaster.prototype, { * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system * * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up. - * The azimuthal angle (theta) is measured from the positive z-axiz. + * The azimuthal angle (theta) is measured from the positive z-axis. */ function Spherical( radius, phi, theta ) { @@ -44527,7 +45493,7 @@ Object.assign( Spherical.prototype, { } else { this.theta = Math.atan2( x, z ); - this.phi = Math.acos( _Math.clamp( y / this.radius, - 1, 1 ) ); + this.phi = Math.acos( MathUtils.clamp( y / this.radius, - 1, 1 ) ); } @@ -44604,7 +45570,7 @@ Object.assign( Cylindrical.prototype, { * @author bhouston / http://clara.io */ -var _vector$6 = new Vector2(); +var _vector$7 = new Vector2(); function Box2( min, max ) { @@ -44640,7 +45606,7 @@ Object.assign( Box2.prototype, { setFromCenterAndSize: function ( center, size ) { - var halfSize = _vector$6.copy( size ).multiplyScalar( 0.5 ); + var halfSize = _vector$7.copy( size ).multiplyScalar( 0.5 ); this.min.copy( center ).sub( halfSize ); this.max.copy( center ).add( halfSize ); @@ -44790,7 +45756,7 @@ Object.assign( Box2.prototype, { distanceToPoint: function ( point ) { - var clampedPoint = _vector$6.copy( point ).clamp( this.min, this.max ); + var clampedPoint = _vector$7.copy( point ).clamp( this.min, this.max ); return clampedPoint.sub( point ).length(); }, @@ -44933,7 +45899,7 @@ Object.assign( Line3.prototype, { if ( clampToLine ) { - t = _Math.clamp( t, 0, 1 ); + t = MathUtils.clamp( t, 0, 1 ); } @@ -44991,152 +45957,13 @@ ImmediateRenderObject.prototype.constructor = ImmediateRenderObject; ImmediateRenderObject.prototype.isImmediateRenderObject = true; -/** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ - -var _v1$5 = new Vector3(); -var _v2$3 = new Vector3(); -var _normalMatrix$1 = new Matrix3(); -var _keys = [ 'a', 'b', 'c' ]; - -function VertexNormalsHelper( object, size, hex, linewidth ) { - - this.object = object; - - this.size = ( size !== undefined ) ? size : 1; - - var color = ( hex !== undefined ) ? hex : 0xff0000; - - var width = ( linewidth !== undefined ) ? linewidth : 1; - - // - - var nNormals = 0; - - var objGeometry = this.object.geometry; - - if ( objGeometry && objGeometry.isGeometry ) { - - nNormals = objGeometry.faces.length * 3; - - } else if ( objGeometry && objGeometry.isBufferGeometry ) { - - nNormals = objGeometry.attributes.normal.count; - - } - - // - - var geometry = new BufferGeometry(); - - var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); - - geometry.addAttribute( 'position', positions ); - - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); - - // - - this.matrixAutoUpdate = false; - - this.update(); - -} - -VertexNormalsHelper.prototype = Object.create( LineSegments.prototype ); -VertexNormalsHelper.prototype.constructor = VertexNormalsHelper; - -VertexNormalsHelper.prototype.update = function () { - - this.object.updateMatrixWorld( true ); - - _normalMatrix$1.getNormalMatrix( this.object.matrixWorld ); - - var matrixWorld = this.object.matrixWorld; - - var position = this.geometry.attributes.position; - - // - - var objGeometry = this.object.geometry; - - if ( objGeometry && objGeometry.isGeometry ) { - - var vertices = objGeometry.vertices; - - var faces = objGeometry.faces; - - var idx = 0; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - - var vertex = vertices[ face[ _keys[ j ] ] ]; - - var normal = face.vertexNormals[ j ]; - - _v1$5.copy( vertex ).applyMatrix4( matrixWorld ); - - _v2$3.copy( normal ).applyMatrix3( _normalMatrix$1 ).normalize().multiplyScalar( this.size ).add( _v1$5 ); - - position.setXYZ( idx, _v1$5.x, _v1$5.y, _v1$5.z ); - - idx = idx + 1; - - position.setXYZ( idx, _v2$3.x, _v2$3.y, _v2$3.z ); - - idx = idx + 1; - - } - - } - - } else if ( objGeometry && objGeometry.isBufferGeometry ) { - - var objPos = objGeometry.attributes.position; - - var objNorm = objGeometry.attributes.normal; - - var idx = 0; - - // for simplicity, ignore index and drawcalls, and render every normal - - for ( var j = 0, jl = objPos.count; j < jl; j ++ ) { - - _v1$5.set( objPos.getX( j ), objPos.getY( j ), objPos.getZ( j ) ).applyMatrix4( matrixWorld ); - - _v2$3.set( objNorm.getX( j ), objNorm.getY( j ), objNorm.getZ( j ) ); - - _v2$3.applyMatrix3( _normalMatrix$1 ).normalize().multiplyScalar( this.size ).add( _v1$5 ); - - position.setXYZ( idx, _v1$5.x, _v1$5.y, _v1$5.z ); - - idx = idx + 1; - - position.setXYZ( idx, _v2$3.x, _v2$3.y, _v2$3.z ); - - idx = idx + 1; - - } - - } - - position.needsUpdate = true; - -}; - /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ * @author WestLangley / http://github.com/WestLangley */ -var _vector$7 = new Vector3(); +var _vector$8 = new Vector3(); function SpotLightHelper( light, color ) { @@ -45172,7 +45999,7 @@ function SpotLightHelper( light, color ) { } - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); var material = new LineBasicMaterial( { fog: false } ); @@ -45202,9 +46029,9 @@ SpotLightHelper.prototype.update = function () { this.cone.scale.set( coneWidth, coneWidth, coneLength ); - _vector$7.setFromMatrixPosition( this.light.target.matrixWorld ); + _vector$8.setFromMatrixPosition( this.light.target.matrixWorld ); - this.cone.lookAt( _vector$7 ); + this.cone.lookAt( _vector$8 ); if ( this.color !== undefined ) { @@ -45226,7 +46053,7 @@ SpotLightHelper.prototype.update = function () { * @author Mugen87 / https://github.com/Mugen87 */ -var _vector$8 = new Vector3(); +var _vector$9 = new Vector3(); var _boneMatrix = new Matrix4(); var _matrixWorldInv = new Matrix4(); @@ -45277,10 +46104,10 @@ function SkeletonHelper( object ) { } - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors, depthTest: false, depthWrite: false, transparent: true } ); + var material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, transparent: true } ); LineSegments.call( this, geometry, material ); @@ -45295,6 +46122,8 @@ function SkeletonHelper( object ) { SkeletonHelper.prototype = Object.create( LineSegments.prototype ); SkeletonHelper.prototype.constructor = SkeletonHelper; +SkeletonHelper.prototype.isSkeletonHelper = true; + SkeletonHelper.prototype.updateMatrixWorld = function ( force ) { var bones = this.bones; @@ -45311,12 +46140,12 @@ SkeletonHelper.prototype.updateMatrixWorld = function ( force ) { if ( bone.parent && bone.parent.isBone ) { _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld ); - _vector$8.setFromMatrixPosition( _boneMatrix ); - position.setXYZ( j, _vector$8.x, _vector$8.y, _vector$8.z ); + _vector$9.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j, _vector$9.x, _vector$9.y, _vector$9.z ); _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld ); - _vector$8.setFromMatrixPosition( _boneMatrix ); - position.setXYZ( j + 1, _vector$8.x, _vector$8.y, _vector$8.z ); + _vector$9.setFromMatrixPosition( _boneMatrix ); + position.setXYZ( j + 1, _vector$9.x, _vector$9.y, _vector$9.z ); j += 2; @@ -45416,89 +46245,13 @@ PointLightHelper.prototype.update = function () { }; -/** - * @author abelnation / http://github.com/abelnation - * @author Mugen87 / http://github.com/Mugen87 - * @author WestLangley / http://github.com/WestLangley - * - * This helper must be added as a child of the light - */ - -function RectAreaLightHelper( light, color ) { - - this.type = 'RectAreaLightHelper'; - - this.light = light; - - this.color = color; // optional hardwired color for the helper - - var positions = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ]; - - var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); - geometry.computeBoundingSphere(); - - var material = new LineBasicMaterial( { fog: false } ); - - Line.call( this, geometry, material ); - - // - - var positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ]; - - var geometry2 = new BufferGeometry(); - geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); - geometry2.computeBoundingSphere(); - - this.add( new Mesh( geometry2, new MeshBasicMaterial( { side: BackSide, fog: false } ) ) ); - - this.update(); - -} - -RectAreaLightHelper.prototype = Object.create( Line.prototype ); -RectAreaLightHelper.prototype.constructor = RectAreaLightHelper; - -RectAreaLightHelper.prototype.update = function () { - - this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 ); - - if ( this.color !== undefined ) { - - this.material.color.set( this.color ); - this.children[ 0 ].material.color.set( this.color ); - - } else { - - this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - // prevent hue shift - var c = this.material.color; - var max = Math.max( c.r, c.g, c.b ); - if ( max > 1 ) c.multiplyScalar( 1 / max ); - - this.children[ 0 ].material.color.copy( this.material.color ); - - } - -}; - -RectAreaLightHelper.prototype.dispose = function () { - - this.geometry.dispose(); - this.material.dispose(); - this.children[ 0 ].geometry.dispose(); - this.children[ 0 ].material.dispose(); - -}; - /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ * @author Mugen87 / https://github.com/Mugen87 */ -var _vector$9 = new Vector3(); +var _vector$a = new Vector3(); var _color1 = new Color(); var _color2 = new Color(); @@ -45518,12 +46271,12 @@ function HemisphereLightHelper( light, size, color ) { geometry.rotateY( Math.PI * 0.5 ); this.material = new MeshBasicMaterial( { wireframe: true, fog: false } ); - if ( this.color === undefined ) this.material.vertexColors = VertexColors; + if ( this.color === undefined ) this.material.vertexColors = true; var position = geometry.getAttribute( 'position' ); var colors = new Float32Array( position.count * 3 ); - geometry.addAttribute( 'color', new BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) ); this.add( new Mesh( geometry, this.material ) ); @@ -45568,153 +46321,7 @@ HemisphereLightHelper.prototype.update = function () { } - mesh.lookAt( _vector$9.setFromMatrixPosition( this.light.matrixWorld ).negate() ); - -}; - -/** - * @author WestLangley / http://github.com/WestLangley - */ - -function LightProbeHelper( lightProbe, size ) { - - this.lightProbe = lightProbe; - - this.size = size; - - var defines = {}; - defines[ 'GAMMA_OUTPUT' ] = ""; - - // material - var material = new ShaderMaterial( { - - defines: defines, - - uniforms: { - - sh: { value: this.lightProbe.sh.coefficients }, // by reference - - intensity: { value: this.lightProbe.intensity } - - }, - - vertexShader: [ - - 'varying vec3 vNormal;', - - 'void main() {', - - ' vNormal = normalize( normalMatrix * normal );', - - ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', - - '}', - - ].join( '\n' ), - - fragmentShader: [ - - '#define RECIPROCAL_PI 0.318309886', - - 'vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {', - - ' // matrix is assumed to be orthogonal', - - ' return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );', - - '}', - - 'vec3 linearToOutput( in vec3 a ) {', - - ' #ifdef GAMMA_OUTPUT', - - ' return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );', - - ' #else', - - ' return a;', - - ' #endif', - - '}', - - '// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf', - 'vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {', - - ' // normal is assumed to have unit length', - - ' float x = normal.x, y = normal.y, z = normal.z;', - - ' // band 0', - ' vec3 result = shCoefficients[ 0 ] * 0.886227;', - - ' // band 1', - ' result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;', - ' result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;', - ' result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;', - - ' // band 2', - ' result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;', - ' result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;', - ' result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );', - ' result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;', - ' result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );', - - ' return result;', - - '}', - - 'uniform vec3 sh[ 9 ]; // sh coefficients', - - 'uniform float intensity; // light probe intensity', - - 'varying vec3 vNormal;', - - 'void main() {', - - ' vec3 normal = normalize( vNormal );', - - ' vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );', - - ' vec3 irradiance = shGetIrradianceAt( worldNormal, sh );', - - ' vec3 outgoingLight = RECIPROCAL_PI * irradiance * intensity;', - - ' outgoingLight = linearToOutput( outgoingLight );', - - ' gl_FragColor = vec4( outgoingLight, 1.0 );', - - '}' - - ].join( '\n' ) - - } ); - - var geometry = new SphereBufferGeometry( 1, 32, 16 ); - - Mesh.call( this, geometry, material ); - - this.onBeforeRender(); - -} - -LightProbeHelper.prototype = Object.create( Mesh.prototype ); -LightProbeHelper.prototype.constructor = LightProbeHelper; - -LightProbeHelper.prototype.dispose = function () { - - this.geometry.dispose(); - this.material.dispose(); - -}; - -LightProbeHelper.prototype.onBeforeRender = function () { - - this.position.copy( this.lightProbe.position ); - - this.scale.set( 1, 1, 1 ).multiplyScalar( this.size ); - - this.material.uniforms.intensity.value = this.lightProbe.intensity; + mesh.lookAt( _vector$a.setFromMatrixPosition( this.light.matrixWorld ).negate() ); }; @@ -45750,10 +46357,10 @@ function GridHelper( size, divisions, color1, color2 ) { } var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: true } ); LineSegments.call( this, geometry, material ); @@ -45857,10 +46464,10 @@ function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) } var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: true } ); LineSegments.call( this, geometry, material ); @@ -45869,219 +46476,14 @@ function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) PolarGridHelper.prototype = Object.create( LineSegments.prototype ); PolarGridHelper.prototype.constructor = PolarGridHelper; -/** - * @author Mugen87 / http://github.com/Mugen87 - */ - -function PositionalAudioHelper( audio, range, divisionsInnerAngle, divisionsOuterAngle ) { - - this.audio = audio; - this.range = range || 1; - this.divisionsInnerAngle = divisionsInnerAngle || 16; - this.divisionsOuterAngle = divisionsOuterAngle || 2; - - var geometry = new BufferGeometry(); - var divisions = this.divisionsInnerAngle + this.divisionsOuterAngle * 2; - var positions = new Float32Array( ( divisions * 3 + 3 ) * 3 ); - geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); - - var materialInnerAngle = new LineBasicMaterial( { color: 0x00ff00 } ); - var materialOuterAngle = new LineBasicMaterial( { color: 0xffff00 } ); - - Line.call( this, geometry, [ materialOuterAngle, materialInnerAngle ] ); - - this.update(); - -} - -PositionalAudioHelper.prototype = Object.create( Line.prototype ); -PositionalAudioHelper.prototype.constructor = PositionalAudioHelper; - -PositionalAudioHelper.prototype.update = function () { - - var audio = this.audio; - var range = this.range; - var divisionsInnerAngle = this.divisionsInnerAngle; - var divisionsOuterAngle = this.divisionsOuterAngle; - - var coneInnerAngle = _Math.degToRad( audio.panner.coneInnerAngle ); - var coneOuterAngle = _Math.degToRad( audio.panner.coneOuterAngle ); - - var halfConeInnerAngle = coneInnerAngle / 2; - var halfConeOuterAngle = coneOuterAngle / 2; - - var start = 0; - var count = 0; - var i, stride; - - var geometry = this.geometry; - var positionAttribute = geometry.attributes.position; - - geometry.clearGroups(); - - // - - function generateSegment( from, to, divisions, materialIndex ) { - - var step = ( to - from ) / divisions; - - positionAttribute.setXYZ( start, 0, 0, 0 ); - count ++; - - for ( i = from; i < to; i += step ) { - - stride = start + count; - - positionAttribute.setXYZ( stride, Math.sin( i ) * range, 0, Math.cos( i ) * range ); - positionAttribute.setXYZ( stride + 1, Math.sin( Math.min( i + step, to ) ) * range, 0, Math.cos( Math.min( i + step, to ) ) * range ); - positionAttribute.setXYZ( stride + 2, 0, 0, 0 ); - - count += 3; - - } - - geometry.addGroup( start, count, materialIndex ); - - start += count; - count = 0; - - } - - // - - generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 ); - generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 ); - generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 ); - - // - - positionAttribute.needsUpdate = true; - - if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false; - -}; - -PositionalAudioHelper.prototype.dispose = function () { - - this.geometry.dispose(); - this.material[ 0 ].dispose(); - this.material[ 1 ].dispose(); - -}; - -/** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - */ - -var _v1$6 = new Vector3(); -var _v2$4 = new Vector3(); -var _normalMatrix$2 = new Matrix3(); - -function FaceNormalsHelper( object, size, hex, linewidth ) { - - // FaceNormalsHelper only supports THREE.Geometry - - this.object = object; - - this.size = ( size !== undefined ) ? size : 1; - - var color = ( hex !== undefined ) ? hex : 0xffff00; - - var width = ( linewidth !== undefined ) ? linewidth : 1; - - // - - var nNormals = 0; - - var objGeometry = this.object.geometry; - - if ( objGeometry && objGeometry.isGeometry ) { - - nNormals = objGeometry.faces.length; - - } else { - - console.warn( 'THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.' ); - - } - - // - - var geometry = new BufferGeometry(); - - var positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 ); - - geometry.addAttribute( 'position', positions ); - - LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, linewidth: width } ) ); - - // - - this.matrixAutoUpdate = false; - this.update(); - -} - -FaceNormalsHelper.prototype = Object.create( LineSegments.prototype ); -FaceNormalsHelper.prototype.constructor = FaceNormalsHelper; - -FaceNormalsHelper.prototype.update = function () { - - this.object.updateMatrixWorld( true ); - - _normalMatrix$2.getNormalMatrix( this.object.matrixWorld ); - - var matrixWorld = this.object.matrixWorld; - - var position = this.geometry.attributes.position; - - // - - var objGeometry = this.object.geometry; - - var vertices = objGeometry.vertices; - - var faces = objGeometry.faces; - - var idx = 0; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - var face = faces[ i ]; - - var normal = face.normal; - - _v1$6.copy( vertices[ face.a ] ) - .add( vertices[ face.b ] ) - .add( vertices[ face.c ] ) - .divideScalar( 3 ) - .applyMatrix4( matrixWorld ); - - _v2$4.copy( normal ).applyMatrix3( _normalMatrix$2 ).normalize().multiplyScalar( this.size ).add( _v1$6 ); - - position.setXYZ( idx, _v1$6.x, _v1$6.y, _v1$6.z ); - - idx = idx + 1; - - position.setXYZ( idx, _v2$4.x, _v2$4.y, _v2$4.z ); - - idx = idx + 1; - - } - - position.needsUpdate = true; - -}; - /** * @author alteredq / http://alteredqualia.com/ * @author mrdoob / http://mrdoob.com/ * @author WestLangley / http://github.com/WestLangley */ -var _v1$7 = new Vector3(); -var _v2$5 = new Vector3(); +var _v1$5 = new Vector3(); +var _v2$3 = new Vector3(); var _v3$1 = new Vector3(); function DirectionalLightHelper( light, size, color ) { @@ -46099,7 +46501,7 @@ function DirectionalLightHelper( light, size, color ) { if ( size === undefined ) size = 1; var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( [ + geometry.setAttribute( 'position', new Float32BufferAttribute( [ - size, size, 0, size, size, 0, size, - size, 0, @@ -46113,7 +46515,7 @@ function DirectionalLightHelper( light, size, color ) { this.add( this.lightPlane ); geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); this.targetLine = new Line( geometry, material ); this.add( this.targetLine ); @@ -46136,11 +46538,11 @@ DirectionalLightHelper.prototype.dispose = function () { DirectionalLightHelper.prototype.update = function () { - _v1$7.setFromMatrixPosition( this.light.matrixWorld ); - _v2$5.setFromMatrixPosition( this.light.target.matrixWorld ); - _v3$1.subVectors( _v2$5, _v1$7 ); + _v1$5.setFromMatrixPosition( this.light.matrixWorld ); + _v2$3.setFromMatrixPosition( this.light.target.matrixWorld ); + _v3$1.subVectors( _v2$3, _v1$5 ); - this.lightPlane.lookAt( _v2$5 ); + this.lightPlane.lookAt( _v2$3 ); if ( this.color !== undefined ) { @@ -46154,7 +46556,7 @@ DirectionalLightHelper.prototype.update = function () { } - this.targetLine.lookAt( _v2$5 ); + this.targetLine.lookAt( _v2$3 ); this.targetLine.scale.z = _v3$1.length(); }; @@ -46169,13 +46571,13 @@ DirectionalLightHelper.prototype.update = function () { * http://evanw.github.com/lightgl.js/tests/shadowmap.html */ -var _vector$a = new Vector3(); +var _vector$b = new Vector3(); var _camera = new Camera(); function CameraHelper( camera ) { var geometry = new BufferGeometry(); - var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: FaceColors } ); + var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true } ); var vertices = []; var colors = []; @@ -46259,8 +46661,8 @@ function CameraHelper( camera ) { } - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); LineSegments.call( this, geometry, material ); @@ -46334,7 +46736,7 @@ CameraHelper.prototype.update = function () { function setPoint( point, pointMap, geometry, camera, x, y, z ) { - _vector$a.set( x, y, z ).unproject( camera ); + _vector$b.set( x, y, z ).unproject( camera ); var points = pointMap[ point ]; @@ -46344,7 +46746,7 @@ function setPoint( point, pointMap, geometry, camera, x, y, z ) { for ( var i = 0, l = points.length; i < l; i ++ ) { - position.setXYZ( points[ i ], _vector$a.x, _vector$a.y, _vector$a.z ); + position.setXYZ( points[ i ], _vector$b.x, _vector$b.y, _vector$b.z ); } @@ -46357,7 +46759,7 @@ function setPoint( point, pointMap, geometry, camera, x, y, z ) { * @author Mugen87 / http://github.com/Mugen87 */ -var _box$2 = new Box3(); +var _box$3 = new Box3(); function BoxHelper( object, color ) { @@ -46370,7 +46772,7 @@ function BoxHelper( object, color ) { var geometry = new BufferGeometry(); geometry.setIndex( new BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) ); LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); @@ -46393,14 +46795,14 @@ BoxHelper.prototype.update = function ( object ) { if ( this.object !== undefined ) { - _box$2.setFromObject( this.object ); + _box$3.setFromObject( this.object ); } - if ( _box$2.isEmpty() ) return; + if ( _box$3.isEmpty() ) return; - var min = _box$2.min; - var max = _box$2.max; + var min = _box$3.min; + var max = _box$3.max; /* 5____4 @@ -46482,7 +46884,7 @@ function Box3Helper( box, color ) { geometry.setIndex( new BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); LineSegments.call( this, geometry, new LineBasicMaterial( { color: color } ) ); @@ -46526,7 +46928,7 @@ function PlaneHelper( plane, size, hex ) { var positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ]; var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) ); geometry.computeBoundingSphere(); Line.call( this, geometry, new LineBasicMaterial( { color: color } ) ); @@ -46536,7 +46938,7 @@ function PlaneHelper( plane, size, hex ) { var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ]; var geometry2 = new BufferGeometry(); - geometry2.addAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); + geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) ); geometry2.computeBoundingSphere(); this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false } ) ) ); @@ -46597,7 +46999,7 @@ function ArrowHelper( dir, origin, length, color, headLength, headWidth ) { if ( _lineGeometry === undefined ) { _lineGeometry = new BufferGeometry(); - _lineGeometry.addAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); + _lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); _coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); _coneGeometry.translate( 0, - 0.5, 0 ); @@ -46651,7 +47053,7 @@ ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) { if ( headLength === undefined ) headLength = 0.2 * length; if ( headWidth === undefined ) headWidth = 0.2 * headLength; - this.line.scale.set( 1, Math.max( 0, length - headLength ), 1 ); + this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458 this.line.updateMatrix(); this.cone.scale.set( headWidth, headLength, headWidth ); @@ -46706,10 +47108,10 @@ function AxesHelper( size ) { ]; var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); - var material = new LineBasicMaterial( { vertexColors: VertexColors } ); + var material = new LineBasicMaterial( { vertexColors: true } ); LineSegments.call( this, geometry, material ); @@ -46718,6 +47120,817 @@ function AxesHelper( size ) { AxesHelper.prototype = Object.create( LineSegments.prototype ); AxesHelper.prototype.constructor = AxesHelper; +/** + * @author Emmett Lalish / elalish + * + * This class generates a Prefiltered, Mipmapped Radiance Environment Map + * (PMREM) from a cubeMap environment texture. This allows different levels of + * blur to be quickly accessed based on material roughness. It is packed into a + * special CubeUV format that allows us to perform custom interpolation so that + * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap + * chain, it only goes down to the LOD_MIN level (above), and then creates extra + * even more filtered 'mips' at the same LOD_MIN resolution, associated with + * higher roughness levels. In this way we maintain resolution to smoothly + * interpolate diffuse lighting while limiting sampling computation. + */ + +var LOD_MIN = 4; +var LOD_MAX = 8; +var SIZE_MAX = Math.pow( 2, LOD_MAX ); +// The standard deviations (radians) associated with the extra mips. These are +// chosen to approximate a Trowbridge-Reitz distribution function times the +// geometric shadowing function. These sigma values squared must match the +// variance #defines in cube_uv_reflection_fragment.glsl.js. +var EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ]; +var TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; +// The maximum length of the blur for loop. Smaller sigmas will use fewer +// samples and exit early, but not recompile the shader. +var MAX_SAMPLES = 20; +var ENCODINGS = { + [ LinearEncoding ]: 0, + [ sRGBEncoding ]: 1, + [ RGBEEncoding ]: 2, + [ RGBM7Encoding ]: 3, + [ RGBM16Encoding ]: 4, + [ RGBDEncoding ]: 5, + [ GammaEncoding ]: 6 +}; + +var _flatCamera = new OrthographicCamera(); +var _blurMaterial = _getBlurShader( MAX_SAMPLES ); +var _equirectShader = null; +var _cubemapShader = null; + +var { _lodPlanes, _sizeLods, _sigmas } = _createPlanes(); +var _pingPongRenderTarget = null; +var _renderer = null; + +var _oldTarget = null; + +// Golden Ratio +var PHI = ( 1 + Math.sqrt( 5 ) ) / 2; +var INV_PHI = 1 / PHI; +// Vertices of a dodecahedron (except the opposites, which represent the +// same axis), used as axis directions evenly spread on a sphere. +var _axisDirections = [ + new Vector3( 1, 1, 1 ), + new Vector3( - 1, 1, 1 ), + new Vector3( 1, 1, - 1 ), + new Vector3( - 1, 1, - 1 ), + new Vector3( 0, PHI, INV_PHI ), + new Vector3( 0, PHI, - INV_PHI ), + new Vector3( INV_PHI, 0, PHI ), + new Vector3( - INV_PHI, 0, PHI ), + new Vector3( PHI, INV_PHI, 0 ), + new Vector3( - PHI, INV_PHI, 0 ) ]; + +function PMREMGenerator( renderer ) { + + _renderer = renderer; + _compileMaterial( _blurMaterial ); + +} + +PMREMGenerator.prototype = { + + constructor: PMREMGenerator, + + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an + * image if networking bandwidth is low. Optional sigma specifies a blur radius + * in radians to be applied to the scene before PMREM generation. Optional near + * and far planes ensure the scene is rendered in its entirety (the cubeCamera + * is placed at the origin). + */ + fromScene: function ( scene, sigma = 0, near = 0.1, far = 100 ) { + + _oldTarget = _renderer.getRenderTarget(); + var cubeUVRenderTarget = _allocateTargets(); + _sceneToCubeUV( scene, near, far, cubeUVRenderTarget ); + if ( sigma > 0 ) { + + _blur( cubeUVRenderTarget, 0, 0, sigma ); + + } + _applyPMREM( cubeUVRenderTarget ); + _cleanup( cubeUVRenderTarget ); + + return cubeUVRenderTarget; + + }, + + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR + * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512), + * as this matches best with the 256 x 256 cubemap output. + */ + fromEquirectangular: function ( equirectangular ) { + + equirectangular.magFilter = NearestFilter; + equirectangular.minFilter = NearestFilter; + equirectangular.generateMipmaps = false; + + return this.fromCubemap( equirectangular ); + + }, + + /** + * Generates a PMREM from an cubemap texture, which can be either LDR + * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256, + * as this matches best with the 256 x 256 cubemap output. + */ + fromCubemap: function ( cubemap ) { + + _oldTarget = _renderer.getRenderTarget(); + var cubeUVRenderTarget = _allocateTargets( cubemap ); + _textureToCubeUV( cubemap, cubeUVRenderTarget ); + _applyPMREM( cubeUVRenderTarget ); + _cleanup( cubeUVRenderTarget ); + + return cubeUVRenderTarget; + + }, + + /** + * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + compileCubemapShader: function () { + + if ( _cubemapShader == null ) { + + _cubemapShader = _getCubemapShader(); + _compileMaterial( _cubemapShader ); + + } + + }, + + /** + * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + compileEquirectangularShader: function () { + + if ( _equirectShader == null ) { + + _equirectShader = _getEquirectShader(); + _compileMaterial( _equirectShader ); + + } + + }, + + /** + * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, + * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on + * one of them will cause any others to also become unusable. + */ + dispose: function () { + + _blurMaterial.dispose(); + + if ( _cubemapShader != null ) _cubemapShader.dispose(); + if ( _equirectShader != null ) _equirectShader.dispose(); + + for ( var i = 0; i < _lodPlanes.length; i ++ ) { + + _lodPlanes[ i ].dispose(); + + } + + }, + +}; + +function _createPlanes() { + + var _lodPlanes = []; + var _sizeLods = []; + var _sigmas = []; + + var lod = LOD_MAX; + for ( var i = 0; i < TOTAL_LODS; i ++ ) { + + var sizeLod = Math.pow( 2, lod ); + _sizeLods.push( sizeLod ); + var sigma = 1.0 / sizeLod; + if ( i > LOD_MAX - LOD_MIN ) { + + sigma = EXTRA_LOD_SIGMA[ i - LOD_MAX + LOD_MIN - 1 ]; + + } else if ( i == 0 ) { + + sigma = 0; + + } + _sigmas.push( sigma ); + + var texelSize = 1.0 / ( sizeLod - 1 ); + var min = - texelSize / 2; + var max = 1 + texelSize / 2; + var uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ]; + + var cubeFaces = 6; + var vertices = 6; + var positionSize = 3; + var uvSize = 2; + var faceIndexSize = 1; + + var position = new Float32Array( positionSize * vertices * cubeFaces ); + var uv = new Float32Array( uvSize * vertices * cubeFaces ); + var faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces ); + + for ( var face = 0; face < cubeFaces; face ++ ) { + + var x = ( face % 3 ) * 2 / 3 - 1; + var y = face > 2 ? 0 : - 1; + var coordinates = [ + x, y, 0, + x + 2 / 3, y, 0, + x + 2 / 3, y + 1, 0, + x, y, 0, + x + 2 / 3, y + 1, 0, + x, y + 1, 0 + ]; + position.set( coordinates, positionSize * vertices * face ); + uv.set( uv1, uvSize * vertices * face ); + var fill = [ face, face, face, face, face, face ]; + faceIndex.set( fill, faceIndexSize * vertices * face ); + + } + var planes = new BufferGeometry(); + planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) ); + planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) ); + planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) ); + _lodPlanes.push( planes ); + + if ( lod > LOD_MIN ) { + + lod --; + + } + + } + return { _lodPlanes, _sizeLods, _sigmas }; + +} + +function _allocateTargets( equirectangular ) { + + var params = { + magFilter: NearestFilter, + minFilter: NearestFilter, + generateMipmaps: false, + type: equirectangular ? equirectangular.type : UnsignedByteType, + format: equirectangular ? equirectangular.format : RGBEFormat, + encoding: equirectangular ? equirectangular.encoding : RGBEEncoding, + depthBuffer: false, + stencilBuffer: false + }; + var cubeUVRenderTarget = _createRenderTarget( params ); + cubeUVRenderTarget.depthBuffer = equirectangular ? false : true; + _pingPongRenderTarget = _createRenderTarget( params ); + return cubeUVRenderTarget; + +} + +function _cleanup( outputTarget ) { + + _pingPongRenderTarget.dispose(); + _renderer.setRenderTarget( _oldTarget ); + outputTarget.scissorTest = false; + // reset viewport and scissor + outputTarget.setSize( outputTarget.width, outputTarget.height ); + +} + +function _sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) { + + var fov = 90; + var aspect = 1; + var cubeCamera = new PerspectiveCamera( fov, aspect, near, far ); + var upSign = [ 1, 1, 1, 1, - 1, 1 ]; + var forwardSign = [ 1, 1, - 1, - 1, - 1, 1 ]; + + var outputEncoding = _renderer.outputEncoding; + var toneMapping = _renderer.toneMapping; + var toneMappingExposure = _renderer.toneMappingExposure; + var clearColor = _renderer.getClearColor(); + var clearAlpha = _renderer.getClearAlpha(); + + _renderer.toneMapping = LinearToneMapping; + _renderer.toneMappingExposure = 1.0; + _renderer.outputEncoding = LinearEncoding; + scene.scale.z *= - 1; + + var background = scene.background; + if ( background && background.isColor ) { + + background.convertSRGBToLinear(); + // Convert linear to RGBE + var maxComponent = Math.max( background.r, background.g, background.b ); + var fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 ); + background = background.multiplyScalar( Math.pow( 2.0, - fExp ) ); + var alpha = ( fExp + 128.0 ) / 255.0; + _renderer.setClearColor( background, alpha ); + scene.background = null; + + } + + for ( var i = 0; i < 6; i ++ ) { + + var col = i % 3; + if ( col == 0 ) { + + cubeCamera.up.set( 0, upSign[ i ], 0 ); + cubeCamera.lookAt( forwardSign[ i ], 0, 0 ); + + } else if ( col == 1 ) { + + cubeCamera.up.set( 0, 0, upSign[ i ] ); + cubeCamera.lookAt( 0, forwardSign[ i ], 0 ); + + } else { + + cubeCamera.up.set( 0, upSign[ i ], 0 ); + cubeCamera.lookAt( 0, 0, forwardSign[ i ] ); + + } + _setViewport( cubeUVRenderTarget, + col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX ); + _renderer.setRenderTarget( cubeUVRenderTarget ); + _renderer.render( scene, cubeCamera ); + + } + + _renderer.toneMapping = toneMapping; + _renderer.toneMappingExposure = toneMappingExposure; + _renderer.outputEncoding = outputEncoding; + _renderer.setClearColor( clearColor, clearAlpha ); + scene.scale.z *= - 1; + +} + +function _textureToCubeUV( texture, cubeUVRenderTarget ) { + + var scene = new Scene(); + if ( texture.isCubeTexture ) { + + if ( _cubemapShader == null ) { + + _cubemapShader = _getCubemapShader(); + + } + + } else { + + if ( _equirectShader == null ) { + + _equirectShader = _getEquirectShader(); + + } + + } + var material = texture.isCubeTexture ? _cubemapShader : _equirectShader; + scene.add( new Mesh( _lodPlanes[ 0 ], material ) ); + var uniforms = material.uniforms; + + uniforms[ 'envMap' ].value = texture; + if ( ! texture.isCubeTexture ) { + + uniforms[ 'texelSize' ].value.set( 1.0 / texture.image.width, 1.0 / texture.image.height ); + + } + uniforms[ 'inputEncoding' ].value = ENCODINGS[ texture.encoding ]; + uniforms[ 'outputEncoding' ].value = ENCODINGS[ texture.encoding ]; + + _setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX ); + _renderer.setRenderTarget( cubeUVRenderTarget ); + _renderer.render( scene, _flatCamera ); + +} + +function _compileMaterial( material ) { + + var tmpScene = new Scene(); + tmpScene.add( new Mesh( _lodPlanes[ 0 ], material ) ); + _renderer.compile( tmpScene, _flatCamera ); + +} + +function _createRenderTarget( params ) { + + var cubeUVRenderTarget = new WebGLRenderTarget( 3 * SIZE_MAX, 3 * SIZE_MAX, params ); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; + +} + +function _setViewport( target, x, y, width, height ) { + + target.viewport.set( x, y, width, height ); + target.scissor.set( x, y, width, height ); + +} + +function _applyPMREM( cubeUVRenderTarget ) { + + var autoClear = _renderer.autoClear; + _renderer.autoClear = false; + + for ( var i = 1; i < TOTAL_LODS; i ++ ) { + + var sigma = Math.sqrt( + _sigmas[ i ] * _sigmas[ i ] - + _sigmas[ i - 1 ] * _sigmas[ i - 1 ] ); + var poleAxis = + _axisDirections[ ( i - 1 ) % _axisDirections.length ]; + _blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis ); + + } + + _renderer.autoClear = autoClear; + +} + +/** + * This is a two-pass Gaussian blur for a cubemap. Normally this is done + * vertically and horizontally, but this breaks down on a cube. Here we apply + * the blur latitudinally (around the poles), and then longitudinally (towards + * the poles) to approximate the orthogonally-separable blur. It is least + * accurate at the poles, but still does a decent job. + */ +function _blur( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) { + + _halfBlur( + cubeUVRenderTarget, + _pingPongRenderTarget, + lodIn, + lodOut, + sigma, + 'latitudinal', + poleAxis ); + + _halfBlur( + _pingPongRenderTarget, + cubeUVRenderTarget, + lodOut, + lodOut, + sigma, + 'longitudinal', + poleAxis ); + +} + +function _halfBlur( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) { + + if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) { + + console.error( + 'blur direction must be either latitudinal or longitudinal!' ); + + } + + // Number of standard deviations at which to cut off the discrete approximation. + var STANDARD_DEVIATIONS = 3; + + var blurScene = new Scene(); + blurScene.add( new Mesh( _lodPlanes[ lodOut ], _blurMaterial ) ); + var blurUniforms = _blurMaterial.uniforms; + + var pixels = _sizeLods[ lodIn ] - 1; + var radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 ); + var sigmaPixels = sigmaRadians / radiansPerPixel; + var samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES; + + if ( samples > MAX_SAMPLES ) { + + console.warn( `sigmaRadians, ${ + sigmaRadians}, is too large and will clip, as it requested ${ + samples} samples when the maximum is set to ${MAX_SAMPLES}` ); + + } + + var weights = []; + var sum = 0; + + for ( var i = 0; i < MAX_SAMPLES; ++ i ) { + + var x = i / sigmaPixels; + var weight = Math.exp( - x * x / 2 ); + weights.push( weight ); + + if ( i == 0 ) { + + sum += weight; + + } else if ( i < samples ) { + + sum += 2 * weight; + + } + + } + + for ( var i = 0; i < weights.length; i ++ ) { + + weights[ i ] = weights[ i ] / sum; + + } + + blurUniforms[ 'envMap' ].value = targetIn.texture; + blurUniforms[ 'samples' ].value = samples; + blurUniforms[ 'weights' ].value = weights; + blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal'; + if ( poleAxis ) { + + blurUniforms[ 'poleAxis' ].value = poleAxis; + + } + blurUniforms[ 'dTheta' ].value = radiansPerPixel; + blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn; + blurUniforms[ 'inputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ]; + blurUniforms[ 'outputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ]; + + var outputSize = _sizeLods[ lodOut ]; + var x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize ); + var y = ( lodOut === 0 ? 0 : 2 * SIZE_MAX ) + + 2 * outputSize * + ( lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0 ); + + _setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize ); + _renderer.setRenderTarget( targetOut ); + _renderer.render( blurScene, _flatCamera ); + +} + +function _getBlurShader( maxSamples ) { + + var weights = new Float32Array( maxSamples ); + var poleAxis = new Vector3( 0, 1, 0 ); + var shaderMaterial = new RawShaderMaterial( { + + defines: { 'n': maxSamples }, + + uniforms: { + 'envMap': { value: null }, + 'samples': { value: 1 }, + 'weights': { value: weights }, + 'latitudinal': { value: false }, + 'dTheta': { value: 0 }, + 'mipInt': { value: 0 }, + 'poleAxis': { value: poleAxis }, + 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, + 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } + }, + + vertexShader: _getCommonVertexShader(), + + fragmentShader: ` +precision mediump float; +precision mediump int; +varying vec3 vOutputDirection; +uniform sampler2D envMap; +uniform int samples; +uniform float weights[n]; +uniform bool latitudinal; +uniform float dTheta; +uniform float mipInt; +uniform vec3 poleAxis; + +${_getEncodings()} + +#define ENVMAP_TYPE_CUBE_UV +#include + +void main() { + gl_FragColor = vec4(0.0); + for (int i = 0; i < n; i++) { + if (i >= samples) + break; + for (int dir = -1; dir < 2; dir += 2) { + if (i == 0 && dir == 1) + continue; + vec3 axis = latitudinal ? poleAxis : cross(poleAxis, vOutputDirection); + if (all(equal(axis, vec3(0.0)))) + axis = cross(vec3(0.0, 1.0, 0.0), vOutputDirection); + axis = normalize(axis); + float theta = dTheta * float(dir * i); + float cosTheta = cos(theta); + // Rodrigues' axis-angle rotation + vec3 sampleDirection = vOutputDirection * cosTheta + + cross(axis, vOutputDirection) * sin(theta) + + axis * dot(axis, vOutputDirection) * (1.0 - cosTheta); + gl_FragColor.rgb += + weights[i] * bilinearCubeUV(envMap, sampleDirection, mipInt); + } + } + gl_FragColor = linearToOutputTexel(gl_FragColor); +} + `, + + blending: NoBlending, + depthTest: false, + depthWrite: false + + } ); + + shaderMaterial.type = 'SphericalGaussianBlur'; + + return shaderMaterial; + +} + +function _getEquirectShader() { + + var texelSize = new Vector2( 1, 1 ); + var shaderMaterial = new RawShaderMaterial( { + + uniforms: { + 'envMap': { value: null }, + 'texelSize': { value: texelSize }, + 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, + 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } + }, + + vertexShader: _getCommonVertexShader(), + + fragmentShader: ` +precision mediump float; +precision mediump int; +varying vec3 vOutputDirection; +uniform sampler2D envMap; +uniform vec2 texelSize; + +${_getEncodings()} + +#define RECIPROCAL_PI 0.31830988618 +#define RECIPROCAL_PI2 0.15915494 + +void main() { + gl_FragColor = vec4(0.0); + vec3 outputDirection = normalize(vOutputDirection); + vec2 uv; + uv.y = asin(clamp(outputDirection.y, -1.0, 1.0)) * RECIPROCAL_PI + 0.5; + uv.x = atan(outputDirection.z, outputDirection.x) * RECIPROCAL_PI2 + 0.5; + vec2 f = fract(uv / texelSize - 0.5); + uv -= f * texelSize; + vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb; + uv.x += texelSize.x; + vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb; + uv.y += texelSize.y; + vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb; + uv.x -= texelSize.x; + vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb; + vec3 tm = mix(tl, tr, f.x); + vec3 bm = mix(bl, br, f.x); + gl_FragColor.rgb = mix(tm, bm, f.y); + gl_FragColor = linearToOutputTexel(gl_FragColor); +} + `, + + blending: NoBlending, + depthTest: false, + depthWrite: false + + } ); + + shaderMaterial.type = 'EquirectangularToCubeUV'; + + return shaderMaterial; + +} + +function _getCubemapShader() { + + var shaderMaterial = new RawShaderMaterial( { + + uniforms: { + 'envMap': { value: null }, + 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] }, + 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] } + }, + + vertexShader: _getCommonVertexShader(), + + fragmentShader: ` +precision mediump float; +precision mediump int; +varying vec3 vOutputDirection; +uniform samplerCube envMap; + +${_getEncodings()} + +void main() { + gl_FragColor = vec4(0.0); + gl_FragColor.rgb = envMapTexelToLinear(textureCube(envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ))).rgb; + gl_FragColor = linearToOutputTexel(gl_FragColor); +} + `, + + blending: NoBlending, + depthTest: false, + depthWrite: false + + } ); + + shaderMaterial.type = 'CubemapToCubeUV'; + + return shaderMaterial; + +} + +function _getCommonVertexShader() { + + return ` +precision mediump float; +precision mediump int; +attribute vec3 position; +attribute vec2 uv; +attribute float faceIndex; +varying vec3 vOutputDirection; +vec3 getDirection(vec2 uv, float face) { + uv = 2.0 * uv - 1.0; + vec3 direction = vec3(uv, 1.0); + if (face == 0.0) { + direction = direction.zyx; + direction.z *= -1.0; + } else if (face == 1.0) { + direction = direction.xzy; + direction.z *= -1.0; + } else if (face == 3.0) { + direction = direction.zyx; + direction.x *= -1.0; + } else if (face == 4.0) { + direction = direction.xzy; + direction.y *= -1.0; + } else if (face == 5.0) { + direction.xz *= -1.0; + } + return direction; +} +void main() { + vOutputDirection = getDirection(uv, faceIndex); + gl_Position = vec4( position, 1.0 ); +} + `; + +} + +function _getEncodings() { + + return ` +uniform int inputEncoding; +uniform int outputEncoding; + +#include + +vec4 inputTexelToLinear(vec4 value){ + if(inputEncoding == 0){ + return value; + }else if(inputEncoding == 1){ + return sRGBToLinear(value); + }else if(inputEncoding == 2){ + return RGBEToLinear(value); + }else if(inputEncoding == 3){ + return RGBMToLinear(value, 7.0); + }else if(inputEncoding == 4){ + return RGBMToLinear(value, 16.0); + }else if(inputEncoding == 5){ + return RGBDToLinear(value, 256.0); + }else{ + return GammaToLinear(value, 2.2); + } +} + +vec4 linearToOutputTexel(vec4 value){ + if(outputEncoding == 0){ + return value; + }else if(outputEncoding == 1){ + return LinearTosRGB(value); + }else if(outputEncoding == 2){ + return LinearToRGBE(value); + }else if(outputEncoding == 3){ + return LinearToRGBM(value, 7.0); + }else if(outputEncoding == 4){ + return LinearToRGBM(value, 16.0); + }else if(outputEncoding == 5){ + return LinearToRGBD(value, 256.0); + }else{ + return LinearToGamma(value, 2.2); + } +} + +vec4 envMapTexelToLinear(vec4 color) { + return inputTexelToLinear(color); +} + `; + +} + /** * @author mrdoob / http://mrdoob.com/ */ @@ -46730,8 +47943,10 @@ function Face4( a, b, c, d, normal, color, materialIndex ) { } var LineStrip = 0; - var LinePieces = 1; +var NoColors = 0; +var FaceColors = 1; +var VertexColors = 2; function MeshFaceMaterial( materials ) { @@ -46809,8 +48024,8 @@ function Vertex( x, y, z ) { function DynamicBufferAttribute( array, itemSize ) { - console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.' ); - return new BufferAttribute( array, itemSize ).setDynamic( true ); + console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.' ); + return new BufferAttribute( array, itemSize ).setUsage( DynamicDrawUsage ); } @@ -46943,7 +48158,7 @@ Object.assign( Path.prototype, { fromPoints: function ( points ) { console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' ); - this.setFromPoints( points ); + return this.setFromPoints( points ); } @@ -47064,6 +48279,22 @@ Object.assign( Loader.prototype, { } ); +Loader.Handlers = { + + add: function ( /* regex, loader */ ) { + + console.error( 'THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.' ); + + }, + + get: function ( /* file */ ) { + + console.error( 'THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.' ); + + } + +}; + function XHRLoader( manager ) { console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' ); @@ -47153,6 +48384,13 @@ Object.assign( Box3.prototype, { } } ); +Frustum.prototype.setFromMatrix = function ( m ) { + + console.warn( 'THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().' ); + return this.setFromProjectionMatrix( m ); + +}; + Line3.prototype.center = function ( optionalTarget ) { console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' ); @@ -47160,7 +48398,7 @@ Line3.prototype.center = function ( optionalTarget ) { }; -Object.assign( _Math, { +Object.assign( MathUtils, { random16: function () { @@ -47172,14 +48410,14 @@ Object.assign( _Math, { nearestPowerOfTwo: function ( value ) { console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' ); - return _Math.floorPowerOfTwo( value ); + return MathUtils.floorPowerOfTwo( value ); }, nextPowerOfTwo: function ( value ) { console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' ); - return _Math.ceilPowerOfTwo( value ); + return MathUtils.ceilPowerOfTwo( value ); } @@ -47204,10 +48442,10 @@ Object.assign( Matrix3.prototype, { console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' ); }, - applyToBuffer: function ( buffer /*, offset, length */ ) { + applyToBufferAttribute: function ( attribute ) { - console.warn( 'THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); - return this.applyToBufferAttribute( buffer ); + console.warn( 'THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.' ); + return attribute.applyMatrix3( this ); }, applyToVector3Array: function ( /* array, offset, length */ ) { @@ -47303,10 +48541,10 @@ Object.assign( Matrix4.prototype, { console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); }, - applyToBuffer: function ( buffer /*, offset, length */ ) { + applyToBufferAttribute: function ( attribute ) { - console.warn( 'THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.' ); - return this.applyToBufferAttribute( buffer ); + console.warn( 'THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.' ); + return attribute.applyMatrix4( this ); }, applyToVector3Array: function ( /* array, offset, length */ ) { @@ -47545,6 +48783,12 @@ Object.assign( Geometry.prototype, { console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' ); + }, + applyMatrix: function ( matrix ) { + + console.warn( 'THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().' ); + return this.applyMatrix4( matrix ); + } } ); @@ -47572,6 +48816,12 @@ Object.assign( Object3D.prototype, { console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' ); + }, + applyMatrix: function ( matrix ) { + + console.warn( 'THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().' ); + return this.applyMatrix4( matrix ); + } } ); @@ -47607,6 +48857,34 @@ Object.defineProperties( Object3D.prototype, { } ); +Object.assign( Mesh.prototype, { + + setDrawMode: function () { + + console.error( 'THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' ); + + }, + +} ); + +Object.defineProperties( Mesh.prototype, { + + drawMode: { + get: function () { + + console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.' ); + return TrianglesDrawMode; + + }, + set: function () { + + console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' ); + + } + } + +} ); + Object.defineProperties( LOD.prototype, { objects: { @@ -47788,12 +49066,41 @@ Object.defineProperties( BufferAttribute.prototype, { } }, + dynamic: { + get: function () { + + console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' ); + return this.usage === DynamicDrawUsage; + + }, + set: function ( /* value */ ) { + + console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' ); + this.setUsage( DynamicDrawUsage ); + + } + } + +} ); + +Object.assign( BufferAttribute.prototype, { + setDynamic: function ( value ) { + + console.warn( 'THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.' ); + this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage ); + return this; + + }, copyIndicesArray: function ( /* indices */ ) { console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' ); - } + }, + setArray: function ( /* array */ ) { + + console.error( 'THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' ); + } } ); Object.assign( BufferGeometry.prototype, { @@ -47803,6 +49110,30 @@ Object.assign( BufferGeometry.prototype, { console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); this.setIndex( index ); + }, + addAttribute: function ( name, attribute ) { + + console.warn( 'THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().' ); + + if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { + + console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); + + return this.setAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); + + } + + if ( name === 'index' ) { + + console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); + this.setIndex( attribute ); + + return this; + + } + + return this.setAttribute( name, attribute ); + }, addDrawCall: function ( start, count, indexOffset ) { @@ -47830,6 +49161,19 @@ Object.assign( BufferGeometry.prototype, { console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); + }, + removeAttribute: function ( name ) { + + console.warn( 'THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().' ); + + return this.deleteAttribute( name ); + + }, + applyMatrix: function ( matrix ) { + + console.warn( 'THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().' ); + return this.applyMatrix4( matrix ); + } } ); @@ -47855,6 +49199,59 @@ Object.defineProperties( BufferGeometry.prototype, { } ); +Object.defineProperties( Raycaster.prototype, { + + linePrecision: { + get: function () { + + console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' ); + return this.params.Line.threshold; + + }, + set: function ( value ) { + + console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' ); + this.params.Line.threshold = value; + + } + } + +} ); + +Object.defineProperties( InterleavedBuffer.prototype, { + + dynamic: { + get: function () { + + console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' ); + return this.usage === DynamicDrawUsage; + + }, + set: function ( value ) { + + console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' ); + this.setUsage( value ); + + } + } + +} ); + +Object.assign( InterleavedBuffer.prototype, { + setDynamic: function ( value ) { + + console.warn( 'THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.' ); + this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage ); + return this; + + }, + setArray: function ( /* array */ ) { + + console.error( 'THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' ); + + } +} ); + // Object.assign( ExtrudeBufferGeometry.prototype, { @@ -47951,6 +49348,21 @@ Object.defineProperties( Material.prototype, { console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); this.flatShading = ( value === FlatShading ); + } + }, + + stencilMask: { + get: function () { + + console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' ); + return this.stencilFuncMask; + + }, + set: function ( value ) { + + console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' ); + this.stencilFuncMask = value; + } } @@ -48189,6 +49601,41 @@ Object.defineProperties( WebGLRenderer.prototype, { console.warn( 'THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.' ); return this.getContext(); + } + }, + vr: { + get: function () { + + console.warn( 'THREE.WebGLRenderer: .vr has been renamed to .xr' ); + return this.xr; + + } + }, + gammaInput: { + get: function () { + + console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' ); + return false; + + }, + set: function () { + + console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' ); + + } + }, + gammaOutput: { + get: function () { + + console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' ); + return false; + + }, + set: function ( value ) { + + console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' ); + this.outputEncoding = ( value === true ) ? sRGBEncoding : LinearEncoding; + } } @@ -48238,26 +49685,12 @@ Object.defineProperties( WebGLShadowMap.prototype, { } ); -// - -Object.defineProperties( WebGLRenderTargetCube.prototype, { - - activeCubeFace: { - set: function ( /* value */ ) { - - console.warn( 'THREE.WebGLRenderTargetCube: .activeCubeFace has been removed. It is now the second parameter of WebGLRenderer.setRenderTarget().' ); - - } - }, - activeMipMapLevel: { - set: function ( /* value */ ) { - - console.warn( 'THREE.WebGLRenderTargetCube: .activeMipMapLevel has been removed. It is now the third parameter of WebGLRenderer.setRenderTarget().' ); +function WebGLRenderTargetCube( width, height, options ) { - } - } + console.warn( 'THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).' ); + return new WebGLCubeRenderTarget( width, options ); -} ); +} // @@ -48408,41 +49841,33 @@ Object.defineProperties( WebGLRenderTarget.prototype, { // -Object.defineProperties( WebVRManager.prototype, { +Object.defineProperties( Audio.prototype, { - standing: { - set: function ( /* value */ ) { + load: { + value: function ( file ) { + + console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); + var scope = this; + var audioLoader = new AudioLoader(); + audioLoader.load( file, function ( buffer ) { + + scope.setBuffer( buffer ); - console.warn( 'THREE.WebVRManager: .standing has been removed.' ); + } ); + return this; } }, - userHeight: { - set: function ( /* value */ ) { + startTime: { + set: function () { - console.warn( 'THREE.WebVRManager: .userHeight has been removed.' ); + console.warn( 'THREE.Audio: .startTime is now .play( delay ).' ); } } } ); -// - -Audio.prototype.load = function ( file ) { - - console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' ); - var scope = this; - var audioLoader = new AudioLoader(); - audioLoader.load( file, function ( buffer ) { - - scope.setBuffer( buffer ); - - } ); - return this; - -}; - AudioAnalyser.prototype.getData = function () { console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); @@ -48556,19 +49981,19 @@ var SceneUtils = { createMultiMaterialObject: function ( /* geometry, materials */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); }, detach: function ( /* child, parent, scene */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); }, attach: function ( /* child, scene, parent */ ) { - console.error( 'THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.js' ); + console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' ); } @@ -48578,8 +50003,18 @@ var SceneUtils = { function LensFlare() { - console.error( 'THREE.LensFlare has been moved to /examples/js/objects/Lensflare.js' ); + console.error( 'THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js' ); + +} + +if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + /* eslint-disable no-undef */ + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: { + revision: REVISION, + } } ) ); + /* eslint-enable no-undef */ } -export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, AxisHelper, BackSide, BasicDepthPacking, BasicShadowMap, BinaryTextureLoader, Bone, BooleanKeyframeTrack, BoundingBoxHelper, Box2, Box3, Box3Helper, BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasRenderer, CanvasTexture, CatmullRomCurve3, CineonToneMapping, CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, ClosedSplineCurve3, Color, ColorKeyframeTrack, CompressedTexture, CompressedTextureLoader, ConeBufferGeometry, ConeGeometry, CubeCamera, BoxGeometry as CubeGeometry, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubeUVRefractionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CylinderBufferGeometry, CylinderGeometry, Cylindrical, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DirectionalLightShadow, DiscreteInterpolant, DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicBufferAttribute, EdgesGeometry, EdgesHelper, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeBufferGeometry, ExtrudeGeometry, Face3, Face4, FaceColors, FaceNormalsHelper, FileLoader, FlatShading, Float32Attribute, Float32BufferAttribute, Float64Attribute, Float64BufferAttribute, FloatType, Fog, FogExp2, Font, FontLoader, FrontFaceDirectionCCW, FrontFaceDirectionCW, FrontSide, Frustum, GammaEncoding, Geometry, GeometryUtils, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, Int16Attribute, Int16BufferAttribute, Int32Attribute, Int32BufferAttribute, Int8Attribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, JSONLoader, KeepStencilOp, KeyframeTrack, LOD, LatheBufferGeometry, LatheGeometry, Layers, LensFlare, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, LightProbeHelper, LightShadow, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LinePieces, LineSegments, LineStrip, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LogLuvEncoding, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, _Math as Math, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshFaceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiMaterial, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColors, NoToneMapping, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, ParametricBufferGeometry, ParametricGeometry, Particle, ParticleBasicMaterial, ParticleSystem, ParticleSystemMaterial, Path, PerspectiveCamera, Plane, PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointCloud, PointCloudMaterial, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PositionalAudioHelper, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBDEncoding, RGBEEncoding, RGBEFormat, RGBFormat, RGBM16Encoding, RGBM7Encoding, RGB_ETC1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RectAreaLightHelper, RedFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingBufferGeometry, RingGeometry, Scene, SceneUtils, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, SmoothShading, Sphere, SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, SphericalReflectionMapping, Spline, SplineCurve, SplineCurve3, SpotLight, SpotLightHelper, SpotLightShadow, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StereoCamera, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronBufferGeometry, TetrahedronGeometry, TextBufferGeometry, TextGeometry, Texture, TextureLoader, TorusBufferGeometry, TorusGeometry, TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeBufferGeometry, TubeGeometry, UVMapping, Uint16Attribute, Uint16BufferAttribute, Uint32Attribute, Uint32BufferAttribute, Uint8Attribute, Uint8BufferAttribute, Uint8ClampedAttribute, Uint8ClampedBufferAttribute, Uncharted2ToneMapping, Uniform, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShort565Type, UnsignedShortType, Vector2, Vector3, Vector4, VectorKeyframeTrack, Vertex, VertexColors, VertexNormalsHelper, VideoTexture, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderTargetCube, WebGLRenderer, WebGLUtils, WireframeGeometry, WireframeHelper, WrapAroundEnding, XHRLoader, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, sRGBEncoding }; +export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveBlending, AlphaFormat, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightProbe, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, AxisHelper, BackSide, BasicDepthPacking, BasicShadowMap, BinaryTextureLoader, Bone, BooleanKeyframeTrack, BoundingBoxHelper, Box2, Box3, Box3Helper, BoxBufferGeometry, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasRenderer, CanvasTexture, CatmullRomCurve3, CineonToneMapping, CircleBufferGeometry, CircleGeometry, ClampToEdgeWrapping, Clock, ClosedSplineCurve3, Color, ColorKeyframeTrack, CompressedTexture, CompressedTextureLoader, ConeBufferGeometry, ConeGeometry, CubeCamera, BoxGeometry as CubeGeometry, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubeUVRefractionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CylinderBufferGeometry, CylinderGeometry, Cylindrical, DataTexture, DataTexture2DArray, DataTexture3D, DataTextureLoader, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightHelper, DirectionalLightShadow, DiscreteInterpolant, DodecahedronBufferGeometry, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicBufferAttribute, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EdgesHelper, EllipseCurve, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExtrudeBufferGeometry, ExtrudeGeometry, Face3, Face4, FaceColors, FileLoader, FlatShading, Float32Attribute, Float32BufferAttribute, Float64Attribute, Float64BufferAttribute, FloatType, Fog, FogExp2, Font, FontLoader, FrontFaceDirectionCCW, FrontFaceDirectionCW, FrontSide, Frustum, GammaEncoding, Geometry, GeometryUtils, GreaterDepth, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, HemisphereLightProbe, IcosahedronBufferGeometry, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, ImmediateRenderObject, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16Attribute, Int16BufferAttribute, Int32Attribute, Int32BufferAttribute, Int8Attribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InvertStencilOp, JSONLoader, KeepStencilOp, KeyframeTrack, LOD, LatheBufferGeometry, LatheGeometry, Layers, LensFlare, LessDepth, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, LightShadow, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LinePieces, LineSegments, LineStrip, LinearEncoding, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearToneMapping, Loader, LoaderUtils, LoadingManager, LogLuvEncoding, LoopOnce, LoopPingPong, LoopRepeat, LuminanceAlphaFormat, LuminanceFormat, MOUSE, Material, MaterialLoader, MathUtils as Math, MathUtils, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshFaceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiMaterial, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeverDepth, NeverStencilFunc, NoBlending, NoColors, NoToneMapping, NormalBlending, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronBufferGeometry, OctahedronGeometry, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, ParametricBufferGeometry, ParametricGeometry, Particle, ParticleBasicMaterial, ParticleSystem, ParticleSystemMaterial, Path, PerspectiveCamera, Plane, PlaneBufferGeometry, PlaneGeometry, PlaneHelper, PointCloud, PointCloudMaterial, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronBufferGeometry, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, REVISION, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBDEncoding, RGBEEncoding, RGBEFormat, RGBFormat, RGBIntegerFormat, RGBM16Encoding, RGBM7Encoding, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingBufferGeometry, RingGeometry, SRGB8_ALPHA8_ASTC_10x10_Format, SRGB8_ALPHA8_ASTC_10x5_Format, SRGB8_ALPHA8_ASTC_10x6_Format, SRGB8_ALPHA8_ASTC_10x8_Format, SRGB8_ALPHA8_ASTC_12x10_Format, SRGB8_ALPHA8_ASTC_12x12_Format, SRGB8_ALPHA8_ASTC_4x4_Format, SRGB8_ALPHA8_ASTC_5x4_Format, SRGB8_ALPHA8_ASTC_5x5_Format, SRGB8_ALPHA8_ASTC_6x5_Format, SRGB8_ALPHA8_ASTC_6x6_Format, SRGB8_ALPHA8_ASTC_8x5_Format, SRGB8_ALPHA8_ASTC_8x6_Format, SRGB8_ALPHA8_ASTC_8x8_Format, Scene, SceneUtils, ShaderChunk, ShaderLib, ShaderMaterial, ShadowMaterial, Shape, ShapeBufferGeometry, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, SmoothShading, Sphere, SphereBufferGeometry, SphereGeometry, Spherical, SphericalHarmonics3, SphericalReflectionMapping, Spline, SplineCurve, SplineCurve3, SpotLight, SpotLightHelper, SpotLightShadow, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronBufferGeometry, TetrahedronGeometry, TextBufferGeometry, TextGeometry, Texture, TextureLoader, TorusBufferGeometry, TorusGeometry, TorusKnotBufferGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeBufferGeometry, TubeGeometry, UVMapping, Uint16Attribute, Uint16BufferAttribute, Uint32Attribute, Uint32BufferAttribute, Uint8Attribute, Uint8BufferAttribute, Uint8ClampedAttribute, Uint8ClampedBufferAttribute, Uncharted2ToneMapping, Uniform, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt248Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShort565Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, Vertex, VertexColors, VideoTexture, WebGLCubeRenderTarget, WebGLMultisampleRenderTarget, WebGLRenderTarget, WebGLRenderTargetCube, WebGLRenderer, WebGLUtils, WireframeGeometry, WireframeHelper, WrapAroundEnding, XHRLoader, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, sRGBEncoding }; diff --git a/docs/api/en/Polyfills.html b/docs/api/en/Polyfills.html index 32402166cf0833..e9de1bf276f7c1 100644 --- a/docs/api/en/Polyfills.html +++ b/docs/api/en/Polyfills.html @@ -41,6 +41,8 @@

[page:Object.assign Object.assign]( [page:Object target], [page:Object ...so

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/polyfills.js src/polyfills.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/polyfills.js src/polyfills.js] +

diff --git a/docs/api/en/Template.html b/docs/api/en/Template.html index aa44df9badaaef..d0dbbe16ffe67d 100644 --- a/docs/api/en/Template.html +++ b/docs/api/en/Template.html @@ -43,6 +43,8 @@

[method:null todo]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/AnimationAction.html b/docs/api/en/animation/AnimationAction.html index 68cab6ed2b24c2..fb3471a63205b4 100644 --- a/docs/api/en/animation/AnimationAction.html +++ b/docs/api/en/animation/AnimationAction.html @@ -357,6 +357,8 @@

Events

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/AnimationClip.html b/docs/api/en/animation/AnimationClip.html index 258cde59c5a8cf..4b1a4660ff77f1 100644 --- a/docs/api/en/animation/AnimationClip.html +++ b/docs/api/en/animation/AnimationClip.html @@ -138,6 +138,8 @@

[method:Object toJSON]( [param:AnimationClip clip] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/AnimationMixer.html b/docs/api/en/animation/AnimationMixer.html index 617891328b5463..66b8195cd90c70 100644 --- a/docs/api/en/animation/AnimationMixer.html +++ b/docs/api/en/animation/AnimationMixer.html @@ -85,6 +85,13 @@

[method:AnimationMixer update]([param:Number deltaTimeInSeconds])

This is usually done in the render loop, passing [page:Clock.getDelta clock.getDelta] scaled by the mixer's [page:.timeScale timeScale]).

+

[method:AnimationMixer setTime]([param:Number timeInSeconds])

+

+ Sets the global mixer to a specific time and updates the animation accordingly.

+ + This is useful when you need to jump to an exact time in an animation. The input parameter will be scaled by the mixer's [page:.timeScale timeScale]. +

+

[method:null uncacheClip]([param:AnimationClip clip])

@@ -105,6 +112,8 @@

[method:null uncacheAction]([param:AnimationClip clip], [param:Object3D opti

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/AnimationObjectGroup.html b/docs/api/en/animation/AnimationObjectGroup.html index d1fb4f6d0a6fab..6a2124e41db3e2 100644 --- a/docs/api/en/animation/AnimationObjectGroup.html +++ b/docs/api/en/animation/AnimationObjectGroup.html @@ -37,10 +37,10 @@

Limitations

Constructor

-

[name]( [param:object obj1], [param:object obj2], [param:object obj3], ... )

- [page:object obj] - an abitrary number of meshes that share the same animation state.
- +

+ [page:object obj] - an abitrary number of meshes that share the same animation state. +

Properties

@@ -80,6 +80,8 @@

[method:null uncache]( [param:object obj1], [param:object obj2], [param:obje

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/AnimationUtils.html b/docs/api/en/animation/AnimationUtils.html index cbd826190e62a2..617160f1235a0e 100644 --- a/docs/api/en/animation/AnimationUtils.html +++ b/docs/api/en/animation/AnimationUtils.html @@ -48,10 +48,16 @@

[method:Array sortedArray]( values, stride, order )

Sorts the array previously returned by [page:AnimationUtils.getKeyframeOrder getKeyframeOrder].

+

[method:AnimationClip subclip]( [param:AnimationClip clip], [param:String name], [param:Number startFrame], [param:Number endFrame], [param:Number fps] )

+

+ Creates a new clip, containing only the segment of the original clip between the given frames. +

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/KeyframeTrack.html b/docs/api/en/animation/KeyframeTrack.html index 553463646a7365..35a31b995a19c6 100644 --- a/docs/api/en/animation/KeyframeTrack.html +++ b/docs/api/en/animation/KeyframeTrack.html @@ -58,7 +58,7 @@

[name]

Some examples of how to manually create [page:AnimationClip AnimationClips] with different sorts - of KeyframeTracks can be found in the [link:https://threejs.org/examples/js/animation/AnimationClipCreator.js AnimationClipCreator] + of KeyframeTracks can be found in the [link:https://threejs.org/examples/jsm/animation/AnimationClipCreator.js AnimationClipCreator] file.

@@ -264,6 +264,8 @@

[method:JSON toJSON]( [param:KeyframeTrack track] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/PropertyBinding.html b/docs/api/en/animation/PropertyBinding.html index a41b7bf0a886e7..876fec0d5948d2 100644 --- a/docs/api/en/animation/PropertyBinding.html +++ b/docs/api/en/animation/PropertyBinding.html @@ -126,6 +126,8 @@

[method:Constructor findNode]( root, nodeName )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/PropertyMixer.html b/docs/api/en/animation/PropertyMixer.html index 5627b4cec563fe..05f10e854ccbae 100644 --- a/docs/api/en/animation/PropertyMixer.html +++ b/docs/api/en/animation/PropertyMixer.html @@ -93,6 +93,8 @@

[method:null restoreOriginalState]( )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/tracks/BooleanKeyframeTrack.html b/docs/api/en/animation/tracks/BooleanKeyframeTrack.html index bde94180807f44..3c9e78db1fc037 100644 --- a/docs/api/en/animation/tracks/BooleanKeyframeTrack.html +++ b/docs/api/en/animation/tracks/BooleanKeyframeTrack.html @@ -73,6 +73,8 @@

[method:null InterpolantFactoryMethodSmooth ]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/tracks/ColorKeyframeTrack.html b/docs/api/en/animation/tracks/ColorKeyframeTrack.html index 898f0b5d7fed80..e18b8fe04fc4c9 100644 --- a/docs/api/en/animation/tracks/ColorKeyframeTrack.html +++ b/docs/api/en/animation/tracks/ColorKeyframeTrack.html @@ -57,6 +57,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/tracks/NumberKeyframeTrack.html b/docs/api/en/animation/tracks/NumberKeyframeTrack.html index e17acfdda78496..a5d782e235498c 100644 --- a/docs/api/en/animation/tracks/NumberKeyframeTrack.html +++ b/docs/api/en/animation/tracks/NumberKeyframeTrack.html @@ -57,6 +57,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/tracks/QuaternionKeyframeTrack.html b/docs/api/en/animation/tracks/QuaternionKeyframeTrack.html index ffc56bcdeb4dd9..683cc920d4511e 100644 --- a/docs/api/en/animation/tracks/QuaternionKeyframeTrack.html +++ b/docs/api/en/animation/tracks/QuaternionKeyframeTrack.html @@ -68,6 +68,8 @@

[method:null InterpolantFactoryMethodLinear]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/tracks/StringKeyframeTrack.html b/docs/api/en/animation/tracks/StringKeyframeTrack.html index a34648f6733655..4d84863b228f5d 100644 --- a/docs/api/en/animation/tracks/StringKeyframeTrack.html +++ b/docs/api/en/animation/tracks/StringKeyframeTrack.html @@ -76,6 +76,8 @@

[method:null InterpolantFactoryMethodSmooth]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/animation/tracks/VectorKeyframeTrack.html b/docs/api/en/animation/tracks/VectorKeyframeTrack.html index 22d2ce310ff8ff..06a101158410b7 100644 --- a/docs/api/en/animation/tracks/VectorKeyframeTrack.html +++ b/docs/api/en/animation/tracks/VectorKeyframeTrack.html @@ -56,6 +56,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/audio/Audio.html b/docs/api/en/audio/Audio.html index b4f91083ac7e07..115d66f3c27c0f 100644 --- a/docs/api/en/audio/Audio.html +++ b/docs/api/en/audio/Audio.html @@ -18,13 +18,7 @@

[name]

This uses the [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API].

- -

Example

- -

- [example:webaudio_sandbox webaudio / sandbox ]
- [example:webaudio_visualizer webaudio / visualizer ] -

+

Code Example

// create an AudioListener and add it to the camera @@ -44,6 +38,12 @@

Example

});
+

Examples

+ +

+ [example:webaudio_sandbox webaudio / sandbox ]
+ [example:webaudio_visualizer webaudio / visualizer ] +

Constructor

@@ -85,14 +85,11 @@

[property:AudioListener listener]

[property:Number playbackRate]

Speed of playback. Default is *1*.

-

[property:Number startTime]

-

The time at which the sound should begin to play. Same as the *when* paramter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *0*.

-

[property:Number offset]

-

An offset to the time within the audio buffer that playback should begin. Same as the *offset* paramter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *0*.

+

An offset to the time within the audio buffer that playback should begin. Same as the *offset* parameter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *0*.

[property:Number duration]

-

Overrides the duration of the audio. Same as the *duration* paramter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *undefined* to play the whole buffer.

+

Overrides the duration of the audio. Same as the *duration* parameter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *undefined* to play the whole buffer.

[property:String source]

An [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode] created @@ -150,7 +147,7 @@

[method:Float getVolume]( value )

Return the current volume.

-

[method:Audio play]()

+

[method:Audio play]( delay )

If [page:Audio.hasPlaybackControl hasPlaybackControl] is true, starts playback.

@@ -162,7 +159,7 @@

[method:Audio pause]()

[method:null onEnded]()

- Called automatically when playback finished. Sets If [page:Audio.isPlaying isPlaying] to false. + Called automatically when playback finished.

[method:Audio setBuffer]( audioBuffer )

@@ -188,11 +185,26 @@

[method:Audio setLoop]( [param:Boolean value] )

(whether playback should loop).

+

[method:Audio setLoopStart]( [param:Float value] )

+

+ Set [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart source.loopStart] to *value*. +

+ +

[method:Audio setLoopEnd]( [param:Float value] )

+

+ Set [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd source.loopEnd] to *value*. +

+

[method:Audio setMediaElementSource]( mediaElement )

Applies the given object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement] as the source of this audio.
Also sets [page:Audio.hasPlaybackControl hasPlaybackControl] to false. +

+

[method:Audio setMediaStreamSource]( mediaStream )

+

+ Applies the given object of type [link:https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream] as the source of this audio.
+ Also sets [page:Audio.hasPlaybackControl hasPlaybackControl] to false.

[method:Audio setNodeSource]( audioNode )

@@ -214,12 +226,13 @@

[method:Audio setVolume]( [param:Float value] )

[method:Audio stop]()

- If [page:Audio.hasPlaybackControl hasPlaybackControl] is enabled, stops playback, - resets [page:Audio.startTime startTime] to *0* and sets [page:Audio.isPlaying isPlaying] to false. + If [page:Audio.hasPlaybackControl hasPlaybackControl] is enabled, stops playback.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/audio/AudioAnalyser.html b/docs/api/en/audio/AudioAnalyser.html index bde5724f44be31..70a8a6a83c76db 100644 --- a/docs/api/en/audio/AudioAnalyser.html +++ b/docs/api/en/audio/AudioAnalyser.html @@ -18,13 +18,7 @@

[name]

- -

Example

- -

- [example:webaudio_sandbox webaudio / sandbox ]
- [example:webaudio_visualizer webaudio / visualizer ] -

+

Code Example

// create an AudioListener and add it to the camera @@ -50,6 +44,12 @@

Example

var data = analyser.getAverageFrequency();
+

Examples

+ +

+ [example:webaudio_sandbox webaudio / sandbox ]
+ [example:webaudio_visualizer webaudio / visualizer ] +

Constructor

@@ -94,6 +94,8 @@

[method:Number getAverageFrequency]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/audio/AudioContext.html b/docs/api/en/audio/AudioContext.html index 6cd87af103ce9c..913db1bf3dd33f 100644 --- a/docs/api/en/audio/AudioContext.html +++ b/docs/api/en/audio/AudioContext.html @@ -37,6 +37,8 @@

[method:AudioContext setContext]( [param:AudioConetxt value] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/audio/AudioListener.html b/docs/api/en/audio/AudioListener.html index 20784a307a6f0b..bf5ab6b9ce0308 100644 --- a/docs/api/en/audio/AudioListener.html +++ b/docs/api/en/audio/AudioListener.html @@ -18,14 +18,7 @@

[name]

In most cases, the listener object is a child of the camera. So the 3D transformation of the camera represents the 3D transformation of the listener.

- -

Example

- -

- [example:webaudio_sandbox webaudio / sandbox ]
- [example:webaudio_timing webaudio / timing ]
- [example:webaudio_visualizer webaudio / visualizer ] -

+

Code Example

// create an AudioListener and add it to the camera @@ -45,6 +38,13 @@

Example

});
+

Examples

+ +

+ [example:webaudio_sandbox webaudio / sandbox ]
+ [example:webaudio_timing webaudio / timing ]
+ [example:webaudio_visualizer webaudio / visualizer ] +

Constructor

@@ -106,6 +106,8 @@

[method:AudioListener setMasterVolume]( [param:Number value] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/audio/PositionalAudio.html b/docs/api/en/audio/PositionalAudio.html index ddfe62b938d907..5b244da2dc7b79 100644 --- a/docs/api/en/audio/PositionalAudio.html +++ b/docs/api/en/audio/PositionalAudio.html @@ -18,14 +18,7 @@

[name]

This uses the [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API].

- -

Example

- -

- [example:webaudio_orientation webaudio / orientation ]
- [example:webaudio_sandbox webaudio / sandbox ]
- [example:webaudio_timing webaudio / timing ] -

+

Code Example

// create an AudioListener and add it to the camera @@ -44,7 +37,7 @@

Example

}); // create an object for the sound to play from - var sphere = new THREE.SphereGeometry( 20, 32, 16 ); + var sphere = new THREE.SphereBufferGeometry( 20, 32, 16 ); var material = new THREE.MeshPhongMaterial( { color: 0xff2200 } ); var mesh = new THREE.Mesh( sphere, material ); scene.add( mesh ); @@ -53,6 +46,13 @@

Example

mesh.add( sound );
+

Examples

+ +

+ [example:webaudio_orientation webaudio / orientation ]
+ [example:webaudio_sandbox webaudio / sandbox ]
+ [example:webaudio_timing webaudio / timing ] +

Constructor

@@ -130,6 +130,8 @@

[method:PositionalAudio setDirectionalCone]( [param:Float coneInnerAngle], [

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/cameras/ArrayCamera.html b/docs/api/en/cameras/ArrayCamera.html index 0cdc8f9ffcf7ba..bb6fab9839d238 100644 --- a/docs/api/en/cameras/ArrayCamera.html +++ b/docs/api/en/cameras/ArrayCamera.html @@ -17,7 +17,7 @@

[name]

An instance of [name] always has an array of sub cameras. It's mandatory to define for each sub camera the *viewport* property which determines the part of the viewport that is rendered with this camera.

-

Example

+

Examples

[example:webgl_camera_array camera / array ]

@@ -42,6 +42,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/cameras/Camera.html b/docs/api/en/cameras/Camera.html index 143f9f7e27a61d..871f8e98b6772d 100644 --- a/docs/api/en/cameras/Camera.html +++ b/docs/api/en/cameras/Camera.html @@ -30,13 +30,6 @@

[name]()

Properties

See the base [page:Object3D] class for common properties.

-

[property:Boolean isCamera]

-

- Used to check whether this or derived classes are cameras. Default is *true*.

- - You should not change this, as it used internally by the renderer for optimisation. -

-

[property:Layers layers]

The [page:Layers layers] that the camera is a member of. This is an inherited @@ -82,6 +75,8 @@

[method:Vector3 getWorldDirection]( [param:Vector3 target] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/cameras/CubeCamera.html b/docs/api/en/cameras/CubeCamera.html index fd7b7683dfd00a..1c64ea2da9b9ac 100644 --- a/docs/api/en/cameras/CubeCamera.html +++ b/docs/api/en/cameras/CubeCamera.html @@ -12,12 +12,9 @@

[name]

-

Creates 6 cameras that render to a [page:WebGLRenderTargetCube].

+

Creates 6 cameras that render to a [page:WebGLCubeRenderTarget].

-

Examples

- -

[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]

-

[example:webgl_shading_physical shading / physical ]

+

Code Example

// Create cube camera var cubeCamera = new THREE.CubeCamera( 1, 100000, 128 ); @@ -38,6 +35,12 @@

Examples

renderer.render( scene, camera );
+

Examples

+ +

+ [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
+ [example:webgl_shading_physical shading / physical ] +

Constructor

@@ -47,7 +50,7 @@

[name]( [param:Number near], [param:Number far], [param:Number cubeResolutio near -- The near clipping distance.
far -- The far clipping distance
cubeResolution -- Sets the length of the cube's edges.
- options - (optional) object that holds texture parameters passed to the auto-generated WebGLRenderTargetCube. + options - (optional) object that holds texture parameters passed to the auto-generated WebGLCubeRenderTarget. If not specified, the options default to: { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter } @@ -56,14 +59,14 @@

[name]( [param:Number near], [param:Number far], [param:Number cubeResolutio

Constructs a CubeCamera that contains 6 [page:PerspectiveCamera PerspectiveCameras] that - render to a [page:WebGLRenderTargetCube]. + render to a [page:WebGLCubeRenderTarget].

Properties

See the base [page:Object3D] class for common properties.

-

[property:WebGLRenderTargetCube renderTarget]

+

[property:WebGLCubeRenderTarget renderTarget]

The cube texture that gets generated.

@@ -89,6 +92,8 @@

[method:null clear]( [param:WebGLRenderer renderer], [param:Boolean color],

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/cameras/OrthographicCamera.html b/docs/api/en/cameras/OrthographicCamera.html index b7ebe4a369ede4..7fce781236a1c4 100644 --- a/docs/api/en/cameras/OrthographicCamera.html +++ b/docs/api/en/cameras/OrthographicCamera.html @@ -21,23 +21,26 @@

[name]

This can be useful for rendering 2D scenes and UI elements, amongst other things.

+

Code Example

-

Example

+ + var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); + scene.add( camera ); + -

[example:webgl_camera camera ]

-

[example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]

-

[example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]

-

[example:webgl_postprocessing_advanced postprocessing / advanced ]

-

[example:webgl_postprocessing_dof2 postprocessing / dof2 ]

-

[example:webgl_postprocessing_godrays postprocessing / godrays ]

-

[example:webgl_rtt rtt ]

-

[example:webgl_shaders_tonemapping shaders / tonemapping ]

-

[example:webgl_shadowmap shadowmap ]

-

[example:webgl_terrain_dynamic terrain / dynamic ]

- - var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); -scene.add( camera ); +

Examples

+

+ [example:webgl_camera camera ]
+ [example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]
+ [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
+ [example:webgl_postprocessing_advanced postprocessing / advanced ]
+ [example:webgl_postprocessing_dof2 postprocessing / dof2 ]
+ [example:webgl_postprocessing_godrays postprocessing / godrays ]
+ [example:webgl_rtt rtt ]
+ [example:webgl_shaders_tonemapping shaders / tonemapping ]
+ [example:webgl_shadowmap shadowmap ] +

Constructor

@@ -72,13 +75,6 @@

[property:Float far]

The valid range is between the current value of the [page:.near near] plane and infinity.

-

[property:Boolean isOrthographicCamera]

-

- Used to test whether this or derived classes are OrthographicCameras. Default is *true*.

- - This should not be changed as it is used internally by the renderer for optimisation. -

-

[property:Float left]

Camera frustum left plane.

@@ -138,6 +134,8 @@

[method:Object toJSON]([param:object meta])

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/cameras/PerspectiveCamera.html b/docs/api/en/cameras/PerspectiveCamera.html index 8d2a6edb5a75c2..85c656d4b00a3c 100644 --- a/docs/api/en/cameras/PerspectiveCamera.html +++ b/docs/api/en/cameras/PerspectiveCamera.html @@ -19,18 +19,22 @@

[name]

common projection mode used for rendering a 3D scene.

+

Code Example

-

Example

+ + var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); + scene.add( camera ); + -

[example:webgl_animation_skinning_blending animation / skinning / blending ]

-

[example:webgl_animation_skinning_morph animation / skinning / blending ]

-

[example:webgl_effects_stereo effects / stereo ]

-

[example:webgl_interactive_cubes interactive / cubes ]

-

[example:webgl_loader_collada_skinning loader / collada / skinning ]

- - var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); -scene.add( camera ); +

Examples

+

+ [example:webgl_animation_skinning_blending animation / skinning / blending ]
+ [example:webgl_animation_skinning_morph animation / skinning / blending ]
+ [example:webgl_effects_stereo effects / stereo ]
+ [example:webgl_interactive_cubes interactive / cubes ]
+ [example:webgl_loader_collada_skinning loader / collada / skinning ] +

Constructor

@@ -77,13 +81,6 @@

[property:Float focus]

[property:Float fov]

Camera frustum vertical field of view, from bottom to top of view, in degrees. Default is *50*.

-

[property:Boolean isPerspectiveCamera]

-

- Used to test whether this or derived classes are PerspectiveCameras. Default is *true*.

- - This should not be changed as it is used internally by the renderer for optimisation. -

-

[property:Float near]

@@ -198,6 +195,8 @@

[method:Object toJSON]([param:object meta])

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/cameras/StereoCamera.html b/docs/api/en/cameras/StereoCamera.html index 529290606ee451..ddb7c6d94f5970 100644 --- a/docs/api/en/cameras/StereoCamera.html +++ b/docs/api/en/cameras/StereoCamera.html @@ -16,22 +16,14 @@

[name]

[link:https://en.wikipedia.org/wiki/Anaglyph_3D 3D Anaglyph] or [link:https://en.wikipedia.org/wiki/parallax_barrier Parallax Barrier].

- -

Example

- -

[example:webgl_effects_anaglyph effects / anaglyph ]

-

[example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]

-

[example:webgl_effects_stereo effects / stereo ]

+

Examples

- This class is used internally in the files

- [link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/AnaglyphEffect.js examples/js/effects/AnaglyphEffect.js]

- [link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/ParallaxBarrierEffect.js examples/js/effects/ParallaxBarrierEffect.js]

- [link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/StereoEffect.js examples/js/effects/StereoEffect.js]

- used in the above examples. + [example:webgl_effects_anaglyph effects / anaglyph ]
+ [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
+ [example:webgl_effects_stereo effects / stereo ]

-

Constructor

[name]( )

@@ -62,6 +54,8 @@

[method:null update]( [param:PerspectiveCamera camera] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/constants/Animation.html b/docs/api/en/constants/Animation.html index 0549f59a1b7439..1bb5bf38019a9b 100644 --- a/docs/api/en/constants/Animation.html +++ b/docs/api/en/constants/Animation.html @@ -11,7 +11,7 @@

Animation Constants

Loop Modes

- + THREE.LoopOnce THREE.LoopRepeat @@ -34,6 +34,8 @@

Ending Modes

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

diff --git a/docs/api/en/constants/Core.html b/docs/api/en/constants/Core.html index fab4146e84d133..9e85e815bc71f7 100644 --- a/docs/api/en/constants/Core.html +++ b/docs/api/en/constants/Core.html @@ -29,8 +29,9 @@

Mouse Buttons

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] - +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

diff --git a/docs/api/en/constants/CustomBlendingEquations.html b/docs/api/en/constants/CustomBlendingEquations.html index 1c115fd4b2c7f5..4f6abdc60f920c 100644 --- a/docs/api/en/constants/CustomBlendingEquations.html +++ b/docs/api/en/constants/CustomBlendingEquations.html @@ -10,15 +10,12 @@

Custom Blending Equation Constants

- -

Example

-

[example:webgl_materials_blending_custom materials / blending / custom ]

- -

Usage

These work with all material types. First set the material's blending mode to THREE.CustomBlending, then set the desired Blending Equation, Source Factor and Destination Factor.

+

Code Example

+ var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); material.blending = THREE.CustomBlending; @@ -27,6 +24,9 @@

Usage

material.blendDst = THREE.OneMinusSrcAlphaFactor; //default
+

Examples

+

[example:webgl_materials_blending_custom materials / blending / custom ]

+

Blending Equations

THREE.AddEquation @@ -58,6 +58,8 @@

Destination Factors

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

diff --git a/docs/api/en/constants/DrawModes.html b/docs/api/en/constants/DrawModes.html deleted file mode 100644 index 613a10bd9ff372..00000000000000 --- a/docs/api/en/constants/DrawModes.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - -

Draw Mode Constants

- -

- These are valid values for [page:Mesh.drawMode], and control how the list of vertices is interpeted once sent to the GPU.

- - Note that these only work when [page:Mesh.geometry] is a [page:BufferGeometry]. Changing this - when [page:Mesh.geometry] is a [page:Geometry] will have no effect.

- - - -

- -

Draw Modes

- - - THREE.TrianglesDrawMode - -

- This is the default, and results in every three consecutive vertices (v0, v1, v2), (v2, v3, v5), ... - being interpreted as a separate triangle.
- If the number of vertices is not a multiple of 3, excess vertices are ignored. -

- - - THREE.TriangleStripDrawMode - -

- This will result in a series of triangles connected in a strip, given by (v0, v1, v2), (v2, v1, v3), (v2, v3, v4), ... - so that every subsequent triangle shares two vertices with the previous triangle. -

- - - THREE.TriangleFanDrawMode - -

- This will result in a series of triangles each sharing the first vertex (like a fan), - given by (v0, v1, v2), (v0, v2, v3), (v0, v3, v4), ...

- - Note: As of [link:https://en.wikipedia.org/wiki/DirectX#DirectX_10 DirectX10], this mode is not supported. As Chrome and Firefox - render WebGL using [link:https://en.wikipedia.org/wiki/ANGLE_(software) ANGLE] on Windows, - internally this mode will be converted to a supported mode, which will likely lead to lowered - performance on those browsers. -

- - -

Usage

- - - var geometry = new THREE.Geometry(); - - geometry.vertices.push( - new THREE.Vector3( -10, 10, 0 ), - new THREE.Vector3( -10, -10, 0 ), - new THREE.Vector3( 10, -10, 0 ), - ... - ); - geometry.faces.push( new THREE.Face3( 0, 1, 2 ), ... ); - - var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); - - var mesh = new THREE.Mesh( geometry, material ); - mesh.drawMode = THREE.TrianglesDrawMode; //default - - scene.add( mesh ); - - - - -

Source

- - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] - - diff --git a/docs/api/en/constants/Materials.html b/docs/api/en/constants/Materials.html index a167e34aee85e7..5ab138f32f9971 100644 --- a/docs/api/en/constants/Materials.html +++ b/docs/api/en/constants/Materials.html @@ -27,20 +27,6 @@

Side

Default is [page:Constant FrontSide].

- -

Colors

- - THREE.NoColors - THREE.FaceColors - THREE.VertexColors - -

- [page:Constant NoColors] is the default and applies the material's color to all faces.
- [page:Constant FaceColors] colors faces according to each [page:Face3 Face3] [page:Color Color] value.
- [page:Constant VertexColors] colors faces according to each [page:Face3 Face3] vertexColors value. This is an array of three [page:Color Color]s, one for each vertex in the face.
- See the [example:webgl_geometry_colors geometry / colors] example. -

-

Blending Mode

THREE.NoBlending @@ -92,7 +78,7 @@

Texture Combine Operations

[page:Constant MixOperation] uses reflectivity to blend between the two colors.
[page:Constant AddOperation] adds the two colors.

- +

Stencil Functions

THREE.NeverStencilFunc @@ -141,6 +127,8 @@

Stencil Operations

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

diff --git a/docs/api/en/constants/Renderer.html b/docs/api/en/constants/Renderer.html index 3e5c9ff48dafa1..e270458fb21d00 100644 --- a/docs/api/en/constants/Renderer.html +++ b/docs/api/en/constants/Renderer.html @@ -39,13 +39,15 @@

Shadow Types

THREE.BasicShadowMap THREE.PCFShadowMap THREE.PCFSoftShadowMap + THREE.VSMShadowMap

These define the WebGLRenderer's [page:WebGLRenderer.shadowMap.type shadowMap.type] property.

[page:constant BasicShadowMap] gives unfiltered shadow maps - fastest, but lowest quality.
[page:constant PCFShadowMap] filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm (default).
- [page:constant PCFSoftShadowMap] filters shadow maps using the Percentage-Closer Soft Shadows (PCSS) algorithm. + [page:constant PCFSoftShadowMap] filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm with better soft shadows especially when using low-resolution shadow maps.
+ [page:constant VSMShadowMap] filters shadow maps using the Variance Shadow Map (VSM) algorithm. When using VSMShadowMap all shadow receivers will also cast shadows.

Tone Mapping

@@ -72,6 +74,8 @@

Tone Mapping

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

diff --git a/docs/api/en/constants/Textures.html b/docs/api/en/constants/Textures.html index fde3ef806708c4..b9908bf42891eb 100644 --- a/docs/api/en/constants/Textures.html +++ b/docs/api/en/constants/Textures.html @@ -147,8 +147,14 @@

Types

Formats

THREE.AlphaFormat + THREE.RedFormat + THREE.RedIntegerFormat + THREE.RGFormat + THREE.RGIntegerFormat THREE.RGBFormat + THREE.RGBIntegerFormat THREE.RGBAFormat + THREE.RGBAIntegerFormat THREE.LuminanceFormat THREE.LuminanceAlphaFormat THREE.RGBEFormat @@ -161,10 +167,35 @@

Formats

[page:constant AlphaFormat] discards the red, green and blue components and reads just the alpha component.

+ [page:constant RedFormat] discards the green and blue components and reads just the red component.

+ + [page:constant RedIntegerFormat] discards the green and blue components and reads just the red component. + The texels are read as integers instead of floating point. + (can only be used with a WebGL 2 rendering context). +

+ + [page:constant RGFormat] discards the alpha, and blue components and reads the red, and green components. + (can only be used with a WebGL 2 rendering context). +

+ + [page:constant RGIntegerFormat] discards the alpha, and blue components and reads the red, and green components. + The texels are read as integers instead of floating point. + (can only be used with a WebGL 2 rendering context). +

+ [page:constant RGBFormat] discards the alpha components and reads the red, green and blue components.

+ [page:constant RGBIntegerFormat] discards the alpha components and reads the red, green and blue components. + (can only be used with a WebGL 2 rendering context). +

+ [page:constant RGBAFormat] is the default and reads the red, green, blue and alpha components.

+ [page:constant RGBAIntegerFormat] is the default and reads the red, green, blue and alpha components. + The texels are read as integers instead of floating point. + (can only be used with a WebGL 2 rendering context). +

+ [page:constant LuminanceFormat] reads each element as a single luminance component. This is then converted to a floating point, clamped to the range [0,1], and then assembled into an RGBA element by placing the luminance value in the red, green and blue channels, @@ -231,11 +262,303 @@

PVRTC Compressed Texture Formats

ETC Compressed Texture Format

THREE.RGB_ETC1_Format + THREE.RGB_ETC2_Format + THREE.RGBA_ETC2_EAC_Format

For use with a [page:CompressedTexture CompressedTexture]'s [page:Texture.format format] property, these require support for the [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/ WEBGL_compressed_texture_etc1] - extension.

+ (ETC1) or [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/ WEBGL_compressed_texture_etc] + (ETC2) extensions.

+

+ +

ASTC Compressed Texture Format

+ + THREE.RGBA_ASTC_4x4_Format + THREE.RGBA_ASTC_5x4_Format + THREE.RGBA_ASTC_5x5_Format + THREE.RGBA_ASTC_6x5_Format + THREE.RGBA_ASTC_6x6_Format + THREE.RGBA_ASTC_8x5_Format + THREE.RGBA_ASTC_8x6_Format + THREE.RGBA_ASTC_8x8_Format + THREE.RGBA_ASTC_10x5_Format + THREE.RGBA_ASTC_10x6_Format + THREE.RGBA_ASTC_10x8_Format + THREE.RGBA_ASTC_10x10_Format + THREE.RGBA_ASTC_12x10_Format + THREE.RGBA_ASTC_12x12_Format + THREE.SRGB8_ALPHA8_ASTC_4x4_Format + THREE.SRGB8_ALPHA8_ASTC_5x4_Format + THREE.SRGB8_ALPHA8_ASTC_5x5_Format + THREE.SRGB8_ALPHA8_ASTC_6x5_Format + THREE.SRGB8_ALPHA8_ASTC_6x6_Format + THREE.SRGB8_ALPHA8_ASTC_8x5_Format + THREE.SRGB8_ALPHA8_ASTC_8x6_Format + THREE.SRGB8_ALPHA8_ASTC_8x8_Format + THREE.SRGB8_ALPHA8_ASTC_10x5_Format + THREE.SRGB8_ALPHA8_ASTC_10x6_Format + THREE.SRGB8_ALPHA8_ASTC_10x8_Format + THREE.SRGB8_ALPHA8_ASTC_10x10_Format + THREE.SRGB8_ALPHA8_ASTC_12x10_Format + THREE.SRGB8_ALPHA8_ASTC_12x12_Format + +

+ For use with a [page:CompressedTexture CompressedTexture]'s [page:Texture.format format] property, + these require support for the [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ WEBGL_compressed_texture_astc] extension.

+

+ +

Internal Formats

+ + 'ALPHA' + 'RGB' + 'RGBA' + 'LUMINANCE' + 'LUMINANCE_ALPHA' + 'RED_INTEGER' + 'R8' + 'R8_SNORM' + 'R8I' + 'R8UI' + 'R16I' + 'R16UI' + 'R16F' + 'R32I' + 'R32UI' + 'R32F' + 'RG8' + 'RG8_SNORM' + 'RG8I' + 'RG8UI' + 'RG16I' + 'RG16UI' + 'RG16F' + 'RG32I' + 'RG32UI' + 'RG32F' + 'RGB565' + 'RGB8' + 'RGB8_SNORM' + 'RGB8I' + 'RGB8UI' + 'RGB16I' + 'RGB16UI' + 'RGB16F' + 'RGB32I' + 'RGB32UI' + 'RGB32F' + 'RGB9_E5' + 'SRGB8' + 'R11F_G11F_B10F' + 'RGBA4' + 'RGBA8' + 'RGBA8_SNORM' + 'RGBA8I' + 'RGBA8UI' + 'RGBA16I' + 'RGBA16UI' + 'RGBA16F' + 'RGBA32I' + 'RGBA32UI' + 'RGBA32F' + 'RGB5_A1' + 'RGB10_A2' + 'RGB10_A2UI' + 'SRGB8_ALPHA8' + 'DEPTH_COMPONENT16' + 'DEPTH_COMPONENT24' + 'DEPTH_COMPONENT32F' + 'DEPTH24_STENCIL8' + 'DEPTH32F_STENCIL8' + + +

+ + Heads up: changing the internal format of a texture will only affect the + texture when using a WebGL 2 rendering context.

+ + For use with a texture's [page:Texture.internalFormat internalFormat] property, + these define how elements of a texture, or *texels*, are stored on the GPU.

+ + [page:constant R8] stores the red component on 8 bits.

+ + [page:constant R8_SNORM] stores the red component on 8 bits. The component is stored as normalized.

+ + [page:constant R8I] stores the red component on 8 bits. The component is stored as an integer.

+ + [page:constant R8UI] stores the red component on 8 bits. The component is stored as an unsigned integer.

+ + [page:constant R16I] stores the red component on 16 bits. The component is stored as an integer.

+ + [page:constant R16UI] stores the red component on 16 bits. The component is stored as an unsigned integer.

+ + [page:constant R16F] stores the red component on 16 bits. The component is stored as floating point.

+ + [page:constant R32I] stores the red component on 32 bits. The component is stored as an integer.

+ + [page:constant R32UI] stores the red component on 32 bits. The component is stored as an unsigned integer.

+ + [page:constant R32F] stores the red component on 32 bits. The component is stored as floating point.

+ + [page:constant RG8] stores the red and green components on 8 bits each.

+ + [page:constant RG8_SNORM] stores the red and green components on 8 bits each. + Every component is stored as normalized. +

+ + [page:constant RG8I] stores the red and green components on 8 bits each. + Every component is stored as an integer. +

+ + [page:constant RG8UI] stores the red and green components on 8 bits each. + Every component is stored as an unsigned integer. +

+ + [page:constant RG16I] stores the red and green components on 16 bits each. + Every component is stored as an integer. +

+ + [page:constant RG16UI] stores the red and green components on 16 bits each. + Every component is stored as an unsigned integer. +

+ + [page:constant RG16F] stores the red and green components on 16 bits each. + Every component is stored as floating point. +

+ + [page:constant RG32I] stores the red and green components on 32 bits each. + Every component is stored as an integer. +

+ + [page:constant RG32UI] stores the red and green components on 32 bits. + Every component is stored as an unsigned integer. +

+ + [page:constant RG32F] stores the red and green components on 32 bits. + Every component is stored as floating point. +

+ + [page:constant RGB8] stores the red, green, and blue components on 8 bits each. + + [page:constant RGB8_SNORM] stores the red, green, and blue components on 8 bits each. + Every component is stored as normalized. +

+ + [page:constant RGB8I] stores the red, green, and blue components on 8 bits each. + Every component is stored as an integer. +

+ + [page:constant RGB8UI] stores the red, green, and blue components on 8 bits each. + Every component is stored as an unsigned integer. +

+ + [page:constant RGB16I] stores the red, green, and blue components on 16 bits each. + Every component is stored as an integer. +

+ + [page:constant RGB16UI] stores the red, green, and blue components on 16 bits each. + Every component is stored as an unsigned integer. +

+ + [page:constant RGB16F] stores the red, green, and blue components on 16 bits each. + Every component is stored as floating point +

+ + [page:constant RGB32I] stores the red, green, and blue components on 32 bits each. + Every component is stored as an integer. +

+ + [page:constant RGB32UI] stores the red, green, and blue components on 32 bits each. + Every component is stored as an unsigned integer. +

+ + [page:constant RGB32F] stores the red, green, and blue components on 32 bits each. + Every component is stored as floating point +

+ + [page:constant R11F_G11F_B10F] stores the red, green, and blue components respectively on 11 bits, 11 bits, and 10bits. + Every component is stored as floating point. +

+ + [page:constant RGB565] stores the red, green, and blue components respectively on 5 bits, 6 bits, and 5 bits.

+ + [page:constant RGB9_E5] stores the red, green, and blue components on 9 bits each.

+ + [page:constant RGBA8] stores the red, green, blue, and alpha components on 8 bits each.

+ + [page:constant RGBA8_SNORM] stores the red, green, blue, and alpha components on 8 bits. + Every component is stored as normalized. +

+ + [page:constant RGBA8I] stores the red, green, blue, and alpha components on 8 bits each. + Every component is stored as an integer. +

+ + [page:constant RGBA8UI] stores the red, green, blue, and alpha components on 8 bits. + Every component is stored as an unsigned integer. +

+ + [page:constant RGBA16I] stores the red, green, blue, and alpha components on 16 bits. + Every component is stored as an integer. +

+ + [page:constant RGBA16UI] stores the red, green, blue, and alpha components on 16 bits. + Every component is stored as an unsigned integer. +

+ + [page:constant RGBA16F] stores the red, green, blue, and alpha components on 16 bits. + Every component is stored as floating point. +

+ + [page:constant RGBA32I] stores the red, green, blue, and alpha components on 32 bits. + Every component is stored as an integer. +

+ + [page:constant RGBA32UI] stores the red, green, blue, and alpha components on 32 bits. + Every component is stored as an unsigned integer. +

+ + [page:constant RGBA32F] stores the red, green, blue, and alpha components on 32 bits. + Every component is stored as floating point. +

+ + [page:constant RGB5_A1] stores the red, green, blue, and alpha components respectively on 5 bits, 5 bits, 5 bits, and 1 bit.

+ + [page:constant RGB10_A2] stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits.

+ + [page:constant RGB10_A2UI] stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. + Every component is stored as an unsigned integer. +

+ + [page:constant SRGB8] stores the red, green, and blue components on 8 bits each.

+ + [page:constant SRGB8_ALPHA8] stores the red, green, blue, and alpha components on 8 bits each.

+ + [page:constant DEPTH_COMPONENT16] stores the depth component on 16bits.

+ + [page:constant DEPTH_COMPONENT24] stores the depth component on 24bits.

+ + [page:constant DEPTH_COMPONENT32F] stores the depth component on 32bits. The component is stored as floating point.

+ + [page:constant DEPTH24_STENCIL8] stores the depth, and stencil components respectively on 24 bits and 8 bits. + The stencil component is stored as an unsigned integer. +

+ + [page:constant DEPTH32F_STENCIL8] stores the depth, and stencil components respectively on 32 bits and 8 bits. + The depth component is stored as floating point, and the stencil component as an unsigned integer. +

+ + Note that the texture must have the correct [page:Texture.type type] set, + as well as the correct [page:Texture.format format]. + + See [link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D], and + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texImage3D WebGL2RenderingContext.texImage3D], + for more details regarding the possible combination of [page:Texture.format format], [page:Texture.internalFormat internalFormat], + and [page:Texture.type type].

+ + For more in-depth information regarding internal formats, you can also refer directly + to the [link:https://www.khronos.org/registry/webgl/specs/latest/2.0/ WebGL2 Specification] and + to the [link:https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf OpenGL ES 3.0 Specification].

Encoding

@@ -263,6 +586,8 @@

Encoding

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

diff --git a/docs/api/en/core/BufferAttribute.html b/docs/api/en/core/BufferAttribute.html index e4c1bcf1bdd590..0fd7a244508810 100644 --- a/docs/api/en/core/BufferAttribute.html +++ b/docs/api/en/core/BufferAttribute.html @@ -58,23 +58,6 @@

[property:Integer count]

then this will count the number of such vectors stored.

-

[property:Boolean dynamic]

-

- Whether the buffer is dynamic or not. Default is *false*.
- - If false, the GPU is informed that contents of the buffer are likely to be used often and not change often. - This corresponds to the [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData gl.STATIC_DRAW] flag.
- if true, the GPU is informed that contents of the buffer are likely to be used often and change often. - This corresponds to the [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData gl.DYNAMIC_DRAW] flag. -

- -

[property:Boolean isBufferAttribute]

-

- Used to check whether this or derived classes are BufferAttributes. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Integer itemSize]

The length of vectors that are being stored in the [page:BufferAttribute.array array].

@@ -111,12 +94,30 @@

[property:Object updateRange]

related to color).

+

[property:Usage usage]

+

+ Defines the intended usage pattern of the data store for optimization purposes. Corresponds to the *usage* parameter of + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData WebGLRenderingContext.bufferData](). + Default is *THREE.StaticDrawUsage*. +

+

[property:Integer version]

A version number, incremented every time the [page:BufferAttribute.needsUpdate needsUpdate] property is set to true.

-

Methods

+

[method:this applyMatrix3]( [param:Matrix3 m] )

+

Applies matrix [page:Matrix3 m] to every Vector3 element of this BufferAttribute.

+ +

[method:this applyMatrix4]( [param:Matrix4 m] )

+

Applies matrix [page:Matrix4 m] to every Vector3 element of this BufferAttribute.

+ +

[method:this applyNormalMatrix]( [param:Matrix3 m] )

+

Applies normal matrix [page:Matrix3 m] to every Vector3 element of this BufferAttribute.

+ +

[method:this transformDirection]( [param:Matrix4 m] )

+

Applies matrix [page:Matrix4 m] to every Vector3 element of this BufferAttribute, interpreting the elements as a direction vectors.

+

[method:BufferAttribute clone]()

Return a copy of this bufferAttribute.

@@ -178,15 +179,8 @@

[method:BufferAttribute set] ( [param:Array value], [param:Integer offset] ) being a [page:TypedArray].

-

[method:BufferAttribute setArray] ( [param:TypedArray array] )

-

- [page:BufferAttribute.array array] to the TypedArray passed in here.

- - After setting the array, [page:BufferAttribute.needsUpdate needsUpdate] should be set to true. -

- -

[method:BufferAttribute setDynamic] ( [param:Boolean value] )

-

Set [page:BufferAttribute.dynamic dynamic] to value.

+

[method:BufferAttribute setUsage] ( [param:Usage value] )

+

Set [page:BufferAttribute.usage usage] to value.

[method:BufferAttribute setX]( [param:Integer index], [param:Float x] )

Sets the x component of the vector at the given index.

@@ -213,6 +207,8 @@

[method:BufferAttribute setXYZW]( [param:Integer index], [param:Float x], [p

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/BufferGeometry.html b/docs/api/en/core/BufferGeometry.html index 3171cc2e21c44b..da402461ce1450 100644 --- a/docs/api/en/core/BufferGeometry.html +++ b/docs/api/en/core/BufferGeometry.html @@ -22,7 +22,7 @@

[name]

For a less efficient but easier-to-use representation of geometry, see [page:Geometry].

-

Example

+

Code Example

var geometry = new THREE.BufferGeometry(); // create a simple square shape. We duplicate the top left and bottom right @@ -38,10 +38,12 @@

Example

] ); // itemSize = 3 because there are 3 values (components) per vertex - geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); var mesh = new THREE.Mesh( geometry, material );
+ +

Examples

[example:webgl_buffergeometry Mesh with non-indexed faces]
[example:webgl_buffergeometry_indexed Mesh with indexed faces]
@@ -65,7 +67,7 @@

Properties

[property:Object attributes]

This hashmap has as id the name of the attribute to be set and as value the [page:BufferAttribute buffer] to set it to. - Rather than accessing this property directly, use [page:.addAttribute] and [page:.getAttribute] to access attributes of this geometry. + Rather than accessing this property directly, use [page:.setAttribute] and [page:.getAttribute] to access attributes of this geometry.

[property:Box3 boundingBox]

@@ -132,16 +134,16 @@

[property:BufferAttribute index]

Default is *null*.

-

[property:Boolean isBufferGeometry]

+

[property:Object morphAttributes]

- Used to check whether this or derived classes are BufferGeometries. Default is *true*.

- - You should not change this, as it used internally for optimisation. + Hashmap of [page:BufferAttribute]s holding details of the geometry's [page:Geometry.morphTargets morphTargets].

-

[property:Object morphAttributes]

+

[property:Boolean morphTargetsRelative]

- Hashmap of [page:BufferAttribute]s holding details of the geometry's [page:Geometry.morphTargets morphTargets]. + Used to control the morph target behavior; when set to true, the morph target data is treated as relative offsets, rather than as absolute positions/normals. + + Default is *false*.

[property:String name]

@@ -165,9 +167,9 @@

Methods

[page:EventDispatcher EventDispatcher] methods are available on this class.

-

[method:BufferGeometry addAttribute]( [param:String name], [param:BufferAttribute attribute] )

+

[method:BufferGeometry setAttribute]( [param:String name], [param:BufferAttribute attribute] )

- Adds an attribute to this geometry. Use this rather than the attributes property, + Sets an attribute to this geometry. Use this rather than the attributes property, because an internal hashmap of [page:.attributes] is maintained to speed up iterating over attributes.

@@ -179,7 +181,7 @@

[method:null addGroup]( [param:Integer start], [param:Integer count], [param

-

[method:null applyMatrix]( [param:Matrix4 matrix] )

+

[method:null applyMatrix4]( [param:Matrix4 matrix] )

Bakes matrix transform directly into vertex coordinates.

[method:BufferGeometry center] ()

@@ -249,8 +251,8 @@

[method:null normalizeNormals]()

This will correct lighting on the geometry surfaces.

-

[method:BufferAttribute removeAttribute]( [param:String name] )

-

Removes the [page:BufferAttribute attribute] with the specified name.

+

[method:BufferAttribute deleteAttribute]( [param:String name] )

+

Deletes the [page:BufferAttribute attribute] with the specified name.

[method:BufferGeometry rotateX] ( [param:Float radians] )

@@ -322,6 +324,8 @@

[method:BufferGeometry updateFromObject] ( [param:Object3D object] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/Clock.html b/docs/api/en/core/Clock.html index 9d05273d2f6262..56b8ce649fcba5 100644 --- a/docs/api/en/core/Clock.html +++ b/docs/api/en/core/Clock.html @@ -82,6 +82,8 @@

[method:Float getDelta]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/DirectGeometry.html b/docs/api/en/core/DirectGeometry.html index c94f455079ed4c..9cc0927f0b1362 100644 --- a/docs/api/en/core/DirectGeometry.html +++ b/docs/api/en/core/DirectGeometry.html @@ -103,6 +103,8 @@

[property:null fromGeometry]( [param:Geometry geometry] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/EventDispatcher.html b/docs/api/en/core/EventDispatcher.html index f276946c431a02..57e52bfbc1a562 100644 --- a/docs/api/en/core/EventDispatcher.html +++ b/docs/api/en/core/EventDispatcher.html @@ -15,36 +15,36 @@

[name]

[link:https://github.com/mrdoob/eventdispatcher.js Eventdispatcher on GitHub]

-

Example

+

Code Example

-// Adding events to a custom object + // Adding events to a custom object -var Car = function () { + var Car = function () { - this.start = function () { + this.start = function () { - this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); + this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); - }; + }; -}; + }; -// Mixing the EventDispatcher.prototype with the custom object prototype + // Mixing the EventDispatcher.prototype with the custom object prototype -Object.assign( Car.prototype, EventDispatcher.prototype ); + Object.assign( Car.prototype, EventDispatcher.prototype ); -// Using events with the custom object + // Using events with the custom object -var car = new Car(); + var car = new Car(); -car.addEventListener( 'start', function ( event ) { + car.addEventListener( 'start', function ( event ) { - alert( event.message ); + alert( event.message ); -} ); + } ); -car.start(); + car.start();

Constructor

@@ -95,6 +95,8 @@

[method:null dispatchEvent]( [param:object event] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/Face3.html b/docs/api/en/core/Face3.html index c75d5a1635b0c1..a4c6a7388ac989 100644 --- a/docs/api/en/core/Face3.html +++ b/docs/api/en/core/Face3.html @@ -16,39 +16,40 @@

[name]

create them manually.

- -

Examples

- -

[example:svg_sandbox svg / sandbox ]

-

[example:misc_exporter_obj exporter / obj ]

-

[example:webgl_shaders_vector WebGL / shaders / vector ]

- +

Code Example

-var material = new THREE.MeshStandardMaterial( { color : 0x00cc00 } ); + var material = new THREE.MeshStandardMaterial( { color : 0x00cc00 } ); -//create a triangular geometry -var geometry = new THREE.Geometry(); -geometry.vertices.push( new THREE.Vector3( -50, -50, 0 ) ); -geometry.vertices.push( new THREE.Vector3( 50, -50, 0 ) ); -geometry.vertices.push( new THREE.Vector3( 50, 50, 0 ) ); + //create a triangular geometry + var geometry = new THREE.Geometry(); + geometry.vertices.push( new THREE.Vector3( -50, -50, 0 ) ); + geometry.vertices.push( new THREE.Vector3( 50, -50, 0 ) ); + geometry.vertices.push( new THREE.Vector3( 50, 50, 0 ) ); -//create a new face using vertices 0, 1, 2 -var normal = new THREE.Vector3( 0, 1, 0 ); //optional -var color = new THREE.Color( 0xffaa00 ); //optional -var materialIndex = 0; //optional -var face = new THREE.Face3( 0, 1, 2, normal, color, materialIndex ); + //create a new face using vertices 0, 1, 2 + var normal = new THREE.Vector3( 0, 0, 1 ); //optional + var color = new THREE.Color( 0xffaa00 ); //optional + var materialIndex = 0; //optional + var face = new THREE.Face3( 0, 1, 2, normal, color, materialIndex ); -//add the face to the geometry's faces array -geometry.faces.push( face ); + //add the face to the geometry's faces array + geometry.faces.push( face ); -//the face normals and vertex normals can be calculated automatically if not supplied above -geometry.computeFaceNormals(); -geometry.computeVertexNormals(); + //the face normals and vertex normals can be calculated automatically if not supplied above + geometry.computeFaceNormals(); + geometry.computeVertexNormals(); -scene.add( new THREE.Mesh( geometry, material ) ); + scene.add( new THREE.Mesh( geometry, material ) ); +

Examples

+ +

+ [example:svg_sandbox svg / sandbox ]
+ [example:misc_exporter_obj exporter / obj ]
+ [example:webgl_shaders_vector WebGL / shaders / vector ] +

Constructor

@@ -97,7 +98,7 @@

[property:Vector3 normal]

[property:Color color]

Face color - for this to be used a material's [page:Material.vertexColors vertexColors] property - must be set to [page:Materials THREE.FaceColors]. + must be set to *true*.

[property:Array vertexNormals]

@@ -108,7 +109,7 @@

[property:Array vertexNormals]

[property:Array vertexColors]

Array of 3 vertex colors - for these to be used a material's [page:Material.vertexColors vertexColors] property - must be set to [page:Materials THREE.VertexColors]. + must be set to *true*.

@@ -128,6 +129,8 @@

[method:Face3 copy]( [param:Face3 face3] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/Geometry.html b/docs/api/en/core/Geometry.html index 56e95a2784adfe..809e1b384ed85b 100644 --- a/docs/api/en/core/Geometry.html +++ b/docs/api/en/core/Geometry.html @@ -21,20 +21,10 @@

[name]

+

Code Example

-

Example

- -
[example:webgl_geometry_minecraft WebGL / geometry / minecraft ]
-
[example:webgl_geometry_minecraft_ao WebGL / geometry / minecraft / ao ]
-
[example:webgl_geometry_nurbs WebGL / geometry / nurbs ]
-
[example:webgl_geometry_spline_editor WebGL / geometry / spline / editor ]
-
[example:webgl_interactive_cubes_gpu WebGL / interactive / cubes / gpu ]
-
[example:webgl_interactive_lines WebGL / interactive / lines ]
-
[example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points ]
-
[example:webgl_interactive_voxelpainter WebGL / interactive / voxelpainter ]
- - - var geometry = new THREE.Geometry(); + + var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3( -10, 10, 0 ), @@ -47,6 +37,20 @@

Example

geometry.computeBoundingSphere();
+ +

Examples

+ +

+ [example:webgl_geometry_minecraft WebGL / geometry / minecraft ]
+ [example:webgl_geometry_minecraft_ao WebGL / geometry / minecraft / ao ]
+ [example:webgl_geometry_nurbs WebGL / geometry / nurbs ]
+ [example:webgl_geometry_spline_editor WebGL / geometry / spline / editor ]
+ [example:webgl_interactive_cubes_gpu WebGL / interactive / cubes / gpu ]
+ [example:webgl_interactive_lines WebGL / interactive / lines ]
+ [example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points ]
+ [example:webgl_interactive_voxelpainter WebGL / interactive / voxelpainter ] +

+

Constructor

@@ -98,13 +102,6 @@

[property:Array faceVertexUvs]

[property:Integer id]

Unique number for this geometry instance.

-

[property:Boolean isGeometry]

-

- Used to check whether this or derived classes are Geometries. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:array lineDistances]

An array containing distances between vertices for Line geometries. @@ -210,7 +207,7 @@

Methods

[page:EventDispatcher EventDispatcher] methods are available on this class.

-

[method:null applyMatrix]( [param:Matrix4 matrix] )

+

[method:null applyMatrix4]( [param:Matrix4 matrix] )

Bakes matrix transform directly into vertex coordinates.

[method:Geometry center] ()

@@ -341,6 +338,8 @@

[method:Geometry translate] ( [param:Float x], [param:Float y], [param:Float

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/InstancedBufferAttribute.html b/docs/api/en/core/InstancedBufferAttribute.html index ea73b28433f5c3..ed97d7bee9c911 100644 --- a/docs/api/en/core/InstancedBufferAttribute.html +++ b/docs/api/en/core/InstancedBufferAttribute.html @@ -22,23 +22,20 @@

[name]( [param:TypedArray array], [param:Integer itemSize], [param:Boolean n

Properties

- See [page:BufferAttribute] for inherited properties. +

See [page:BufferAttribute] for inherited properties.

[property:Number meshPerAttribute]

Default is *1*.

-

[property:Boolean isInstancedBufferAttribute]

-

- Default is *true*. -

-

Methods

See [page:BufferAttribute] for inherited methods.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/InstancedBufferGeometry.html b/docs/api/en/core/InstancedBufferGeometry.html index f0d901c344f5ab..19f63eddfeaced 100644 --- a/docs/api/en/core/InstancedBufferGeometry.html +++ b/docs/api/en/core/InstancedBufferGeometry.html @@ -22,29 +22,20 @@

[name]( )

Properties

- See [page:BufferGeometry] for inherited properties. +

See [page:BufferGeometry] for inherited properties.

[property:Number maxInstancedCount]

Default is *undefined*.

-

[property:Boolean isInstancedBufferGeometry]

-

- Default is *true*. -

-

Methods

-

See [page:BufferAttribute] for inherited methods.

- -

[property:Number addGroup]( start, count, materialIndex )

-

- -

- +

See [page:BufferGeometry] for inherited methods.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/InstancedInterleavedBuffer.html b/docs/api/en/core/InstancedInterleavedBuffer.html index f375a9e6bab14a..1783bf00289279 100644 --- a/docs/api/en/core/InstancedInterleavedBuffer.html +++ b/docs/api/en/core/InstancedInterleavedBuffer.html @@ -31,11 +31,6 @@

[property:Number meshPerAttribute]

Default is *1*.

-

[property:Boolean isInstancedInterleavedBuffer]

-

- Default is *true*. -

-

Methods

See [page:InterleavedBuffer] for inherited methods. @@ -43,6 +38,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/InterleavedBuffer.html b/docs/api/en/core/InterleavedBuffer.html index f0a25adaa28021..7e9fb4aaabfbfa 100644 --- a/docs/api/en/core/InterleavedBuffer.html +++ b/docs/api/en/core/InterleavedBuffer.html @@ -16,7 +16,7 @@

[name]

An introduction into interleaved arrays can be found here: [link:https://blog.tojicode.com/2011/05/interleaved-array-basics.html Interleaved array basics]

-

Example

+

Examples

[example:webgl_buffergeometry_points_interleaved webgl / buffergeometry / points / interleaved]

@@ -44,11 +44,6 @@

[property:Integer count]

Gives the total number of elements in the array.

-

[property:Boolean dynamic]

-

- Default is *false*. -

-

[property:Object updateRange]

Object containing offset and count. @@ -69,27 +64,18 @@

[property:Integer version]

A version number, incremented every time the needsUpdate property is set to true.

-

[property:Boolean isInterleavedBuffer]

-

- Default is *true*. -

-

[property:Boolean needsUpdate]

Default is *false*. Setting this to true increments [page:InterleavedBuffer.version version].

-

Methods

- -

[method:InterleavedBuffer setArray] ( [param:TypedArray array] )

+

[property:Usage usage]

- array - must be a Typed Array. + Defines the intended usage pattern of the data store for optimization purposes. Corresponds to the *usage* parameter of + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData WebGLRenderingContext.bufferData]().

-

[method:InterleavedBuffer setDynamic] ( [param:Boolean value] )

-

- Set [page:InterleavedBuffer.dynamic dynamic] to value. -

+

Methods

[method:InterleavedBuffer copy]( [param:InterleavedBuffer source] )

@@ -112,8 +98,13 @@

[method:InterleavedBuffer clone]()

Creates a clone of this [name].

+

[method:BufferAttribute setUsage] ( [param:Usage value] )

+

Set [page:BufferAttribute.usage usage] to value.

+

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/InterleavedBufferAttribute.html b/docs/api/en/core/InterleavedBufferAttribute.html index b065e7cc60c27f..14f4fa113bc3f8 100644 --- a/docs/api/en/core/InterleavedBufferAttribute.html +++ b/docs/api/en/core/InterleavedBufferAttribute.html @@ -55,13 +55,11 @@

[property:Boolean normalized]

Default is *false*.

-

[property:Boolean isInterleavedBufferAttribute]

-

- Default is *true*. -

-

Methods

+

[method:this applyMatrix4]( [param:Matrix4 m] )

+

Applies matrix [page:Matrix4 m] to every Vector3 element of this InterleavedBufferAttribute.

+

[method:Number getX]( [param:Integer index] )

Returns the x component of the item at the given index.

@@ -99,6 +97,8 @@

[method:null setXYZW]( [param:Integer index], [param:Float x], [param:Float

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/Layers.html b/docs/api/en/core/Layers.html index 6a83d2b7d9301e..66161e84878147 100644 --- a/docs/api/en/core/Layers.html +++ b/docs/api/en/core/Layers.html @@ -80,8 +80,20 @@

[method:null toggle]( [param:Integer layer] )

Toggle membership of *layer*.

+

[method:null enableAll]()

+

+ Add membership to all layers. +

+ +

[method:null disableAll]()

+

+ Remove membership from all layers. +

+

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/Object3D.html b/docs/api/en/core/Object3D.html index 3ef1268c0dc5d7..9f31fce8eb3e8c 100644 --- a/docs/api/en/core/Object3D.html +++ b/docs/api/en/core/Object3D.html @@ -58,17 +58,11 @@

[property:Boolean frustumCulled]

[property:Integer id]

readonly – Unique number for this object instance.

-

[property:Boolean isObject3D]

-

- Used to check whether this or derived classes are Object3Ds. Default is *true*.

- - You should not change this, as it is used internally for optimisation. -

-

[property:Layers layers]

The layer membership of the object. The object is only visible if it has at least one - layer in common with the [page:Camera] in use. + layer in common with the [page:Camera] in use. This property can also be used to filter out + unwanted objects in ray-intersection tests when using [page:Raycaster].

[property:Matrix4 matrix]

@@ -192,7 +186,7 @@

[property:Vector3 DefaultUp]

Set to ( 0, 1, 0 ) by default.

-

[property:Vector3 DefaultMatrixAutoUpdate]

+

[property:Boolean DefaultMatrixAutoUpdate]

The default setting for [page:.matrixAutoUpdate matrixAutoUpdate] for newly created Object3Ds.
@@ -211,7 +205,7 @@

[method:this add]( [param:Object3D object], ... )

See [page:Group] for info on manually grouping objects.

-

[method:null applyMatrix]( [param:Matrix4 matrix] )

+

[method:null applyMatrix4]( [param:Matrix4 matrix] )

Applies the matrix transform to the object and updates the object's position, rotation and scale.

[method:this applyQuaternion]( [param:Quaternion quaternion] )

@@ -240,7 +234,7 @@

[method:Object3D getObjectById]( [param:Integer id] )

id -- Unique number of the object instance

- Searches through the object's children and returns the first with a matching id.
+ Searches through an object and its children, starting with the object itself, and returns the first with a matching id.
Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object.

@@ -248,7 +242,7 @@

[method:Object3D getObjectByName]( [param:String name] )

name -- String to match to the children's Object3D.name property.

- Searches through the object's children and returns the first with a matching name.
+ Searches through an object and its children, starting with the object itself, and returns the first with a matching name.
Note that for most objects the name is an empty string by default. You will have to set it manually to make use of this method.

@@ -258,7 +252,7 @@

[method:Object3D getObjectByProperty]( [param:String name], [param:Float val name -- the property name to search for.
value -- value of the given property.

- Searches through the object's children and returns the first with a property that matches the value given. + Searches through an object and its children, starting with the object itself, and returns the first with a property that matches the value given.

[method:Vector3 getWorldPosition]( [param:Vector3 target] )

@@ -438,11 +432,18 @@

[method:null traverseAncestors]( [param:Function callback] )

[method:null updateMatrix]()

-

Update the local transform.

+

Updates the local transform.

[method:null updateMatrixWorld]( [param:Boolean force] )

-

Update the global transform of the object and its children.

+

Updates the global transform of the object and its descendants.

+

[method:null updateWorldMatrix]( [param:Boolean updateParents], [param:Boolean updateChildren] )

+

+ updateParents - recursively updates global transform of ancestors.
+ updateChildren - recursively updates global transform of descendants.

+ + Updates the global transform of the object. +

[method:Vector3 worldToLocal]( [param:Vector3 vector] )

@@ -453,6 +454,8 @@

[method:Vector3 worldToLocal]( [param:Vector3 vector] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/Raycaster.html b/docs/api/en/core/Raycaster.html index 2d15cdbc03c9d7..2ca591a703af29 100644 --- a/docs/api/en/core/Raycaster.html +++ b/docs/api/en/core/Raycaster.html @@ -16,7 +16,7 @@

[name]

other things.

-

Example

+

Code Example

var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); @@ -54,22 +54,21 @@

Example

window.requestAnimationFrame(render);
-
- Examples: [example:webgl_interactive_cubes Raycasting to a Mesh]
+ +

Examples

+ +

+ [example:webgl_interactive_cubes Raycasting to a Mesh]
[example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]
[example:webgl_interactive_buffergeometry Raycasting to a Mesh with BufferGeometry]
+ [example:webgl_instancing_raycast Raycasting to a InstancedMesh]
[example:webgl_interactive_lines Raycasting to a Line]
[example:webgl_interactive_raycasting_points Raycasting to Points]
[example:webgl_geometry_terrain_raycast Terrain raycasting]
[example:webgl_interactive_voxelpainter Raycasting to paint voxels]
[example:webgl_raycast_texture Raycast to a Texture] -

- - -

-

Constructor

[name]( [param:Vector3 origin], [param:Vector3 direction], [param:Float near], [param:Float far] ) {

@@ -92,11 +91,6 @@

[property:float far]

This value shouldn't be negative and should be larger than the near property.

-

[property:float linePrecision]

-

- The precision factor of the raycaster when intersecting [page:Line] objects. -

-

[property:float near]

The near factor of the raycaster. This value indicates which objects can be discarded based on the distance. @@ -111,6 +105,18 @@

[property:Camera camera]

Defaults to null.

+

[property:Layers layers]

+

+ Used by [name] to selectively ignore 3D objects when performing intersection tests. The following code example ensures that + only 3D objects on layer *1* will be honored by the instance of [name]. + + + raycaster.layers.set( 1 ); + object.layers.enable( 1 ); + + +

+

[property:Object params]

An object with the following properties: @@ -118,13 +124,14 @@

[property:Object params]

{ Mesh: {}, - Line: {}, + Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} } + Where threshold is the precision of the raycaster when intersecting objects, in world units.

[property:Ray ray]

@@ -170,7 +177,8 @@

[method:Array intersectObject]( [param:Object3D object], [param:Boolean recu [page:Integer faceIndex] – index of the intersected face
[page:Object3D object] – the intersected object
[page:Vector2 uv] - U,V coordinates at point of intersection
- [page:Vector2 uv2] - Second set of U,V coordinates at point of intersection + [page:Vector2 uv2] - Second set of U,V coordinates at point of intersection
+ [page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh

*Raycaster* delegates to the [page:Object3D.raycast raycast] method of the passed object, when evaluating whether the ray intersects the object or not. This allows [page:Mesh meshes] to respond differently to ray casting than [page:Line lines] and [page:Points pointclouds]. @@ -192,6 +200,8 @@

[method:Array intersectObjects]( [param:Array objects], [param:Boolean recur

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/Uniform.html b/docs/api/en/core/Uniform.html index a34ab47136b3df..a70c9c3c2bf409 100644 --- a/docs/api/en/core/Uniform.html +++ b/docs/api/en/core/Uniform.html @@ -13,7 +13,7 @@

[name]

Uniforms are global [link:https://www.opengl.org/documentation/glsl/ GLSL] variables. They are passed to shader programs.

-

Example

+

Code Example

When declaring a uniform of a [page:ShaderMaterial], it is declared by value or by object.

@@ -24,7 +24,7 @@

Example

}
-

Uniform types

+

Uniform types

Each uniform must have a *value* property. The type of the value must correspond to the @@ -50,6 +50,10 @@

Uniform types

int [page:Number] + + uint (WebGL 2) + [page:Number] + float [page:Number] @@ -202,12 +206,13 @@

[method:Uniform clone]()

Returns a clone of this uniform.
If the uniform's value property is an [page:Object] with a clone() method, this is used, otherwise the value is copied by assignment. - Array values are shared between cloned [page:Uniform]s.

- See [example:webgldeferred_animation WebGL deferred animation] for an example of this method in use. + Array values are shared between cloned [page:Uniform]s.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/core/bufferAttributeTypes/BufferAttributeTypes.html b/docs/api/en/core/bufferAttributeTypes/BufferAttributeTypes.html index 9c6e587327b8cd..6559473e9c0133 100644 --- a/docs/api/en/core/bufferAttributeTypes/BufferAttributeTypes.html +++ b/docs/api/en/core/bufferAttributeTypes/BufferAttributeTypes.html @@ -33,9 +33,11 @@

Constructor

All of the above are called in the same way.

-

TypedBufferAttribute( [param:Array array], [param:Integer itemSize], [param:Boolean normalized] )

+

TypedBufferAttribute( [param:Array_or_Integer array], [param:Integer itemSize], [param:Boolean normalized] )

- array -- this can be a typed or untyped (normal) array. It will be converted to the Type specified.

+ array -- this can be a typed or untyped (normal) array or an integer length. + An array value will be converted to the Type specified. + If a length is given a new TypedArray will created, initialized with all elements set to zero.

itemSize -- the number of values of the array that should be associated with a particular vertex.

@@ -44,14 +46,20 @@

TypedBufferAttribute( [param:Array array], [param:Integer itemSize], [param:

Properties

- See the [page:BufferAttribute] page for inherited properties. +

+ See the [page:BufferAttribute] page for inherited properties. +

Methods

- See the [page:BufferAttribute] page for inherited methods. +

+ See the [page:BufferAttribute] page for inherited methods. +

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js src/core/BufferAttribute.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js src/core/BufferAttribute.js] +

diff --git a/docs/api/en/deprecated/DeprecatedList.html b/docs/api/en/deprecated/DeprecatedList.html index 9a3cc045034d6e..c6daef4d0c1256 100644 --- a/docs/api/en/deprecated/DeprecatedList.html +++ b/docs/api/en/deprecated/DeprecatedList.html @@ -55,7 +55,7 @@

[page:BufferAttribute]

[page:DynamicBufferAttribute]

-

DynamicBufferAttribute has been removed. Use [page:BufferAttribute.setDynamic]( true ) instead.

+

DynamicBufferAttribute has been removed. Use [page:BufferAttribute.setUsage]( THREE.DynamicDrawUsage ) instead.

[page:Int8Attribute]

Int8Attribute has been removed. Use [page:BufferAttributeTypes Int8BufferAttribute] instead.

@@ -152,14 +152,6 @@

[page:SplineCurve3]

-

Geometry

- -

- Geometry.computeTangents() has been removed.

- - Geometry.computeLineDistances() has been removed. Use [page:Line.computeLineDistances] instead.

-

-

[page:BufferGeometry]

BufferGeometry.addIndex has been renamed to [page:BufferGeometry.setIndex].

@@ -176,13 +168,25 @@

[page:BufferGeometry]

BufferGeometry.offsets has been renamed to [page:BufferGeometry.groups].

+ BufferGeometry.applyMatrix() has been renamed to [page:BufferGeometry.applyMatrix4]().

+ + +

[page:CubeGeometry]

CubeGeometry has been renamed to [page:BoxGeometry].

+ +

[page:Geometry]

-

Geometry.computeTangents() has been removed.

+

+ Geometry.computeTangents() has been removed.

+ + Geometry.computeLineDistances() has been removed. Use [page:Line.computeLineDistances] instead.

+ + Geometry.applyMatrix() has been renamed to [page:Geometry.applyMatrix4](). +

[page:GeometryUtils]

@@ -253,7 +257,7 @@

[page:XHRLoader]

[page:JSONLoader]

JSONLoader has been removed from core.

-

Maths

+

Math

[page:Box2]

@@ -283,6 +287,9 @@

[page:Box3]

[page:Face4]

Face4 has been removed. Use [page:Face3] instead.

+

[page:Frustum]

+

Frustum.setFromMatrix() has been renamed to [page:Frustum.setFromProjectionMatrix]().

+

[page:Line3]

Line3.center has been renamed to [page:Line3.getCenter]().

@@ -293,15 +300,15 @@

[page:Math]

[page:Matrix3]

- Matrix3.flattenToArrayOffset is deprecated. Use [page:Matrix3.toArray]() instead.

+ Matrix3.flattenToArrayOffset() is deprecated. Use [page:Matrix3.toArray]() instead.

- Matrix3.multiplyVector3 has been removed. Use vector.applyMatrix3( matrix ) instead.

+ Matrix3.multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.

- Matrix3.multiplyVector3Array has been renamed to [page:Matrix3.applyToVector3Array]( array ).

+ Matrix3.multiplyVector3Array() has been renamed to [page:Matrix3.applyToVector3Array]( array ).

- Matrix3.applyToBuffer has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.

+ Matrix3.applyToBufferAttribute() has been removed. Use [page:BufferAttribute.applyMatrix3]( matrix ) instead.

- Matrix3.applyToVector3Array has been removed. + Matrix3.applyToVector3Array() has been removed.

[page:Matrix4]

@@ -332,7 +339,7 @@

[page:Matrix4]

Matrix4.rotateByAxis() has been removed.

- Matrix4.applyToBuffer() has been removed. Use matrix.applyToBufferAttribute() instead.

+ Matrix4.applyToBufferAttribute() has been removed. Use [page:BufferAttribute.applyMatrix4]( matrix ) instead.

Matrix4.applyToVector3Array() has been removed.

@@ -458,12 +465,15 @@

[page:Object3D]

Object3D.translate() has been removed. Use [page:Object3D.translateOnAxis]( axis, distance ) instead.

- Object3D.useQuaternion has been removed. The library now uses quaternions by default. + Object3D.useQuaternion has been removed. The library now uses quaternions by default.

+ + Object3D.applyMatrix() has been renamed to [page:Object3D.applyMatrix4](). +

[page:LensFlare]

- LensFlare has been moved to [link:https://github.com/mrdoob/three.js/blob/master/examples/js/objects/Lensflare.js /examples/js/objects/Lensflare.js]. + LensFlare has been moved to [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Lensflare.js /examples/jsm/objects/Lensflare.js].

@@ -499,7 +509,7 @@

[page:CanvasRenderer]

[page:Projector]

Projector has been moved to - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/Projector.js /examples/js/renderers/Projector.js].

+ [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/Projector.js /examples/jsm/renderers/Projector.js].

Projector.projectVector() is now [page:Vector.project]().

@@ -601,8 +611,9 @@

[page:ImageUtils]

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/Three.Legacy.js src/Three.Legacy.js] - +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/Three.Legacy.js src/Three.Legacy.js] +

diff --git a/docs/api/en/extras/Earcut.html b/docs/api/en/extras/Earcut.html index 66bb67d2890b9f..52bf8e7651a379 100644 --- a/docs/api/en/extras/Earcut.html +++ b/docs/api/en/extras/Earcut.html @@ -26,6 +26,8 @@

[method:Array triangulate]( data, holeIndices, dim )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/ImageUtils.html b/docs/api/en/extras/ImageUtils.html new file mode 100644 index 00000000000000..1f850372034bee --- /dev/null +++ b/docs/api/en/extras/ImageUtils.html @@ -0,0 +1,32 @@ + + + + + + + + + + +

[name]

+ +

+ A class containing utility functions for images. +

+ +

Methods

+ +

[method:String getDataURL]( [param:HTMLCanvasElement image] | [param:HTMLImageElement image] | [param:ImageBitmap image] )

+

+ image -- The image object.

+ + Returns a data URI containing a representation of the given image. +

+ +

Source

+ +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ + diff --git a/docs/api/en/extras/PMREMGenerator.html b/docs/api/en/extras/PMREMGenerator.html new file mode 100644 index 00000000000000..e5fa7605922cdc --- /dev/null +++ b/docs/api/en/extras/PMREMGenerator.html @@ -0,0 +1,80 @@ + + + + + + + + + + +

[name]

+ +

+ This class generates a Prefiltered, Mipmapped Radiance Environment Map (PMREM) from a cubeMap environment texture. + This allows different levels of blur to be quickly accessed based on material roughness. It is packed into a special + CubeUV format that allows us to perform custom interpolation so that we can support nonlinear formats such as RGBE. + Unlike a traditional mipmap chain, it only goes down to the LOD_MIN level (above), and then creates extra even more + filtered 'mips' at the same LOD_MIN resolution, associated with higher roughness levels. In this way we maintain + resolution to smoothly interpolate diffuse lighting while limiting sampling computation. +

+ +

Constructor

+ +

[name]( [param:WebGLRenderer renderer] )

+

+ This constructor creates a new [name]. +

+ +

Methods

+ +

[method:WebGLRenderTarget fromScene]( [param:Scene scene], [param:Number sigma], [param:Number near], [param:Number far] )

+

+ [page:Scene scene] - The given scene.
+ [page:Number sigma] - (optional) Specifies a blur radius in radians to be applied to the scene before PMREM generation. Default is *0*.
+ [page:Number near] - (optional) The near plane value. Default is *0.1*.
+ [page:Number far] - (optional) The far plane value. Default is *100*.

+ + Generates a PMREM from a supplied Scene, which can be faster than using an image if networking bandwidth is low. + Optional near and far planes ensure the scene is rendered in its entirety (the cubeCamera is placed at the origin). +

+ +

[method:WebGLRenderTarget fromEquirectangular]( [param:Texture equirectangular] )

+

+ [page:Texture equirectangular] - The equirectangular texture.

+ + Generates a PMREM from an equirectangular texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). + The ideal input image size is 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output. +

+ +

[method:WebGLRenderTarget fromCubemap]( [param:CubeTexture cubemap] )

+

+ [page:CubeTexture cubemap] - The cubemap texture.

+ + Generates a PMREM from an cubemap texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). + The ideal input cube size is 256 x 256, as this matches best with the 256 x 256 cubemap output. +

+ +

[method:void compileCubemapShader]()

+

+ Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. +

+ +

[method:void compileEquirectangularShader]()

+

+ Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. +

+ +

[method:void dispose]()

+

+ Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, so you should not need more than one + PMREMGenerator object. If you do, calling dispose() on one of them will cause any others to also become unusable. +

+ +

Source

+ +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ + diff --git a/docs/api/en/extras/ShapeUtils.html b/docs/api/en/extras/ShapeUtils.html index b377b6f1347fd5..b3666001b1bb2b 100644 --- a/docs/api/en/extras/ShapeUtils.html +++ b/docs/api/en/extras/ShapeUtils.html @@ -28,7 +28,7 @@

[method:Number area]( contour )

-

[method:Boolean isClockwise]( pts )

+

[method:Boolean isClockWise]( pts )

pts -- points defining a 2D polygon

@@ -49,6 +49,8 @@

[method:Array triangulateShape]( contour, holes )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/core/Curve.html b/docs/api/en/extras/core/Curve.html index ee3a07713aa2ab..9abd7140ab6e51 100644 --- a/docs/api/en/extras/core/Curve.html +++ b/docs/api/en/extras/core/Curve.html @@ -111,6 +111,8 @@

[method:Curve fromJSON]( [param:Object json] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/core/CurvePath.html b/docs/api/en/extras/core/CurvePath.html index 54c6c8ef6e48c9..c9f935056b0570 100644 --- a/docs/api/en/extras/core/CurvePath.html +++ b/docs/api/en/extras/core/CurvePath.html @@ -51,10 +51,25 @@

[method:null closePath]()

[method:Float getCurveLengths]()

Adds together the lengths of the curves in the [page:.curves] array.

+ +

[method:Array getPoints]( [param:Integer divisions] )

+

+ divisions -- number of pieces to divide the curve into. Default is *12*.

+ + Returns a set of divisions + 1 points using getPoint( t ). +

+ +

[method:Array getSpacedPoints]( [param:Integer divisions] )

+

+ divisions -- number of pieces to divide the curve into. Default is *40*.

+ Returns a set of divisions + 1 equi-spaced points using getPointAt( u ). +

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/core/Font.html b/docs/api/en/extras/core/Font.html index 724e2af643c40c..2d17d18599bfa9 100644 --- a/docs/api/en/extras/core/Font.html +++ b/docs/api/en/extras/core/Font.html @@ -37,13 +37,6 @@

Properties

[property:array data]

The JSON data passed in the constructor.

-

[property:Boolean isFont]

-

- Used to check whether this or derived classes are fonts. Default is *true*.

- - You should not change this, as it used internally by the renderer for optimisation. -

-

Methods

[method:null generateShapes]( [param:String text], [param:Float size] )

@@ -56,6 +49,8 @@

[method:null generateShapes]( [param:String text], [param:Float size] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/core/Interpolations.html b/docs/api/en/extras/core/Interpolations.html index c31ba66b943d87..5423e3bdc3ba26 100644 --- a/docs/api/en/extras/core/Interpolations.html +++ b/docs/api/en/extras/core/Interpolations.html @@ -11,7 +11,7 @@

[name]

- TODO + [name] contains spline and Bézier functions internally used by concrete curve classes.

Methods

@@ -42,6 +42,8 @@

[method:Float CubicBezier]( [param:Float t], [param:Float p0], [param:Float

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/core/Path.html b/docs/api/en/extras/core/Path.html index 643a5a135db8a3..9ce6d6fa23b6f2 100644 --- a/docs/api/en/extras/core/Path.html +++ b/docs/api/en/extras/core/Path.html @@ -16,22 +16,22 @@

[name]

A 2D path representation. The class provides methods for creating paths and contours of 2D shapes similar to the 2D Canvas API.

-

Example

+

Code Example

- var path = new THREE.Path(); + var path = new THREE.Path(); - path.lineTo( 0, 0.8 ); - path.quadraticCurveTo( 0, 1, 0.2, 1 ); - path.lineTo( 1, 1 ); + path.lineTo( 0, 0.8 ); + path.quadraticCurveTo( 0, 1, 0.2, 1 ); + path.lineTo( 1, 1 ); - var points = path.getPoints(); + var points = path.getPoints(); - var geometry = new THREE.BufferGeometry().setFromPoints( points ); - var material = new THREE.LineBasicMaterial( { color: 0xffffff } ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var material = new THREE.LineBasicMaterial( { color: 0xffffff } ); - var line = new THREE.Line( geometry, material ); - scene.add( line ); + var line = new THREE.Line( geometry, material ); + scene.add( line ); @@ -60,7 +60,7 @@

[property:array currentPoint]

Methods

See the base [page:CurvePath] class for common methods.

-

[method:null absarc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise] )

+

[method:this absarc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise] )

x, y -- The absolute center of the arc.
radius -- The radius of the arc.
@@ -71,7 +71,7 @@

[method:null absarc]( [param:Float x], [param:Float y], [param:Float radius] Adds an absolutely positioned [page:EllipseCurve EllipseCurve] to the path.

-

[method:null absellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise], [param:Float rotation] )

+

[method:this absellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise], [param:Float rotation] )

x, y -- The absolute center of the ellipse.
xRadius -- The radius of the ellipse in the x axis.
@@ -84,7 +84,7 @@

[method:null absellipse]( [param:Float x], [param:Float y], [param:Float xRa Adds an absolutely positioned [page:EllipseCurve EllipseCurve] to the path.

-

[method:null arc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise] )

+

[method:this arc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise] )

x, y -- The center of the arc offset from the last call.
radius -- The radius of the arc.
@@ -96,10 +96,10 @@

[method:null arc]( [param:Float x], [param:Float y], [param:Float radius], [

-

[method:null bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

+

[method:this bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

This creates a bezier curve from [page:.currentPoint] with (cp1X, cp1Y) and (cp2X, cp2Y) as control points and updates [page:.currentPoint] to x and y.

-

[method:null ellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise], [param:Float rotation] )

+

[method:this ellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise], [param:Float rotation] )

x, y -- The center of the ellipse offset from the last call.
xRadius -- The radius of the ellipse in the x axis.
@@ -112,18 +112,18 @@

[method:null ellipse]( [param:Float x], [param:Float y], [param:Float xRadiu Adds an [page:EllipseCurve EllipseCurve] to the path, positioned relative to [page:.currentPoint].

-

[method:null lineTo]( [param:Float x], [param:Float y] )

+

[method:this lineTo]( [param:Float x], [param:Float y] )

Connects a [page:LineCurve] from [page:.currentPoint] to x, y onto the path.

-

[method:null moveTo]( [param:Float x], [param:Float y] )

+

[method:this moveTo]( [param:Float x], [param:Float y] )

Move the [page:.currentPoint] to x, y.

-

[method:null quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

+

[method:this quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

Creates a quadratic curve from [page:.currentPoint] with cpX and cpY as control point and updates [page:.currentPoint] to x and y.

-

[method:null setFromPoints]( [param:Array vector2s] )

+

[method:this setFromPoints]( [param:Array vector2s] )

points -- array of [page:Vector2 Vector2s].

@@ -131,7 +131,7 @@

[method:null setFromPoints]( [param:Array vector2s] )

array as [page:LineCurve LineCurves].

-

[method:null splineThru] ( [param:Array points] )

+

[method:this splineThru] ( [param:Array points] )

points - An array of [page:Vector2 Vector2s]

@@ -140,6 +140,8 @@

[method:null splineThru] ( [param:Array points] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/core/Shape.html b/docs/api/en/extras/core/Shape.html index cf09326ee4cb97..2c5e6156b3a9a4 100644 --- a/docs/api/en/extras/core/Shape.html +++ b/docs/api/en/extras/core/Shape.html @@ -17,6 +17,8 @@

[name]

[page:ShapeGeometry], to get points, or to get triangulated faces.

+

Code Example

+ var heartShape = new THREE.Shape(); @@ -30,7 +32,7 @@

[name]

var extrudeSettings = { amount: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 }; - var geometry = new THREE.ExtrudeGeometry( heartShape, extrudeSettings ); + var geometry = new THREE.ExtrudeBufferGeometry( heartShape, extrudeSettings ); var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial() );
@@ -96,6 +98,8 @@

[method:Array getPointsHoles]( [param:Integer divisions] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/core/ShapePath.html b/docs/api/en/extras/core/ShapePath.html index 19c2fd15fb9da5..62e58fd1db8d3f 100644 --- a/docs/api/en/extras/core/ShapePath.html +++ b/docs/api/en/extras/core/ShapePath.html @@ -8,8 +8,6 @@ - [page:Curve] → [page:CurvePath] → -

[name]

@@ -18,9 +16,10 @@

[name]

series of paths.

-

Example

- - [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2] +

Examples

+

+ [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2] +

Constructor

@@ -49,27 +48,27 @@

[property:Color color]

Methods

-

[method:null moveTo]( [param:Float x], [param:Float y] )

+

[method:this moveTo]( [param:Float x], [param:Float y] )

Starts a new [page:Path] and calls [page:Path.moveTo]( x, y ) on that [page:Path]. Also points [page:ShapePath.currentPath currentPath] to that [page:Path].

-

[method:null lineTo]( [param:Float x], [param:Float y] )

+

[method:this lineTo]( [param:Float x], [param:Float y] )

This creates a line from the [page:ShapePath.currentPath currentPath]'s offset to X and Y and updates the offset to X and Y.

-

[method:null quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

+

[method:this quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

This creates a quadratic curve from the [page:ShapePath.currentPath currentPath]'s offset to x and y with cpX and cpY as control point and updates the [page:ShapePath.currentPath currentPath]'s offset to x and y.

-

[method:null bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

+

[method:this bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

This creates a bezier curve from the [page:ShapePath.currentPath currentPath]'s offset to x and y with cp1X, cp1Y and cp1X, cp1Y as control points and updates the [page:ShapePath.currentPath currentPath]'s offset to x and y.

-

[method:null splineThru] ( [param:Array points] )

+

[method:this splineThru] ( [param:Array points] )

points - An array of [page:Vector2]s

Connects a new [page:SplineCurve] onto the [page:ShapePath.currentPath currentPath].

@@ -89,6 +88,8 @@

[method:Array toShapes]( [param:Boolean isCCW], [param:Boolean noHoles] )Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js src/extras/core/ShapePath.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js src/extras/core/ShapePath.js] +

diff --git a/docs/api/en/extras/curves/ArcCurve.html b/docs/api/en/extras/curves/ArcCurve.html index 84227ffa1dbbc1..3d4fe504ffd41f 100644 --- a/docs/api/en/extras/curves/ArcCurve.html +++ b/docs/api/en/extras/curves/ArcCurve.html @@ -12,21 +12,16 @@

[name]

-

Alias for [page:EllipseCurve]

+

Alias for [page:EllipseCurve].

Properties

See the [page:EllipseCurve] class for common properties.

-

[property:Boolean isArcCurve]

-

- Used to check whether this or derived classes are ArcCurves. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/CatmullRomCurve3.html b/docs/api/en/extras/curves/CatmullRomCurve3.html index cc485f46bf4267..788fe0e1e66fd5 100644 --- a/docs/api/en/extras/curves/CatmullRomCurve3.html +++ b/docs/api/en/extras/curves/CatmullRomCurve3.html @@ -15,29 +15,32 @@

[name]

Create a smooth 3d spline curve from a series of points using the [link:https://en.wikipedia.org/wiki/Centripetal_Catmull-Rom_spline Catmull-Rom] algorithm.

-

Example

+

Code Example

- -//Create a closed wavey loop -var curve = new THREE.CatmullRomCurve3( [ - new THREE.Vector3( -10, 0, 10 ), - new THREE.Vector3( -5, 5, 5 ), - new THREE.Vector3( 0, 0, 0 ), - new THREE.Vector3( 5, -5, 5 ), - new THREE.Vector3( 10, 0, 10 ) -] ); + + //Create a closed wavey loop + var curve = new THREE.CatmullRomCurve3( [ + new THREE.Vector3( -10, 0, 10 ), + new THREE.Vector3( -5, 5, 5 ), + new THREE.Vector3( 0, 0, 0 ), + new THREE.Vector3( 5, -5, 5 ), + new THREE.Vector3( 10, 0, 10 ) + ] ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); + -

[example:webgl_geometry_extrude_splines geometry / extrude / splines]

+

Examples

+

+ [example:webgl_geometry_extrude_splines WebGL / geometry / extrude / splines] +

Constructor

@@ -53,13 +56,6 @@

[name]( [param:Array points], [param:Boolean closed], [param:String curveTyp

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isCatmullRomCurve3]

-

- Used to check whether this or derived classes are CatmullRomCurve3s. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Array points]

The array of [page:Vector3] points that define the curve. It needs at least two entries.

@@ -76,6 +72,8 @@

[property:float tension]

Methods

See the base [page:Curve] class for common methods.

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/CubicBezierCurve.html b/docs/api/en/extras/curves/CubicBezierCurve.html index 6462fc5e657e47..4fa7e032610ead 100644 --- a/docs/api/en/extras/curves/CubicBezierCurve.html +++ b/docs/api/en/extras/curves/CubicBezierCurve.html @@ -18,24 +18,24 @@

[name]

defined by a start point, endpoint and two control points.

-

Example

+

Code Example

- -var curve = new THREE.CubicBezierCurve( - new THREE.Vector2( -10, 0 ), - new THREE.Vector2( -5, 15 ), - new THREE.Vector2( 20, 15 ), - new THREE.Vector2( 10, 0 ) -); + + var curve = new THREE.CubicBezierCurve( + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( -5, 15 ), + new THREE.Vector2( 20, 15 ), + new THREE.Vector2( 10, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); +

Constructor

@@ -51,13 +51,6 @@

[name] ( [param:Vector2 v0], [param:Vector2 v1], [param:Vector2 v2], [param:

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isCubicBezierCurve]

-

- Used to check whether this or derived classes are CubicBezierCurves. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Vector2 v0]

The starting point.

@@ -76,6 +69,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/CubicBezierCurve3.html b/docs/api/en/extras/curves/CubicBezierCurve3.html index 77d01a9839828b..cc53e242b56d33 100644 --- a/docs/api/en/extras/curves/CubicBezierCurve3.html +++ b/docs/api/en/extras/curves/CubicBezierCurve3.html @@ -18,25 +18,25 @@

[name]

defined by a start point, endpoint and two control points.

-

Example

+

Code Example

- -var curve = new THREE.CubicBezierCurve3( - new THREE.Vector3( -10, 0, 0 ), - new THREE.Vector3( -5, 15, 0 ), - new THREE.Vector3( 20, 15, 0 ), - new THREE.Vector3( 10, 0, 0 ) -); + + var curve = new THREE.CubicBezierCurve3( + new THREE.Vector3( -10, 0, 0 ), + new THREE.Vector3( -5, 15, 0 ), + new THREE.Vector3( 20, 15, 0 ), + new THREE.Vector3( 10, 0, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); - +

Constructor

@@ -52,13 +52,6 @@

[name]( [param:Vector3 v0], [param:Vector3 v1], [param:Vector3 v2], [param:V

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isCubicBezierCurve3]

-

- Used to check whether this or derived classes are CubicBezierCurve3s. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Vector2 v0]

The starting point.

@@ -77,6 +70,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/EllipseCurve.html b/docs/api/en/extras/curves/EllipseCurve.html index d98ff0e1db353a..261ad2b238d073 100644 --- a/docs/api/en/extras/curves/EllipseCurve.html +++ b/docs/api/en/extras/curves/EllipseCurve.html @@ -17,25 +17,25 @@

[name]

[page:Number xRadius] equal to the [page:Number yRadius] will result in a circle.

-

Example

+

Code Example

- -var curve = new THREE.EllipseCurve( - 0, 0, // ax, aY - 10, 10, // xRadius, yRadius - 0, 2 * Math.PI, // aStartAngle, aEndAngle - false, // aClockwise - 0 // aRotation -); + + var curve = new THREE.EllipseCurve( + 0, 0, // ax, aY + 10, 10, // xRadius, yRadius + 0, 2 * Math.PI, // aStartAngle, aEndAngle + false, // aClockwise + 0 // aRotation + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var ellipse = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var ellipse = new THREE.Line( geometry, material ); +

Constructor

@@ -46,24 +46,15 @@

[name]( [param:Float aX], [param:Float aY], [param:Float xRadius], [param:Fl [page:Float aY] – The Y center of the ellipse. Default is *0*.
[page:Float xRadius] – The radius of the ellipse in the x direction. Default is *1*.
[page:Float yRadius] – The radius of the ellipse in the y direction. Default is *1*.
- [page:Radians aStartAngle] – The start angle of the curve in radians starting from the middle right side. Default is *0*.
- [page:Radians aEndAngle] – The end angle of the curve in radians starting from the middle right side. Default is *2 x Math.PI*.
+ [page:Radians aStartAngle] – The start angle of the curve in radians starting from the positive X axis. Default is *0*.
+ [page:Radians aEndAngle] – The end angle of the curve in radians starting from the positive X axis. Default is *2 x Math.PI*.
[page:Boolean aClockwise] – Whether the ellipse is drawn clockwise. Default is *false*.
[page:Radians aRotation] – The rotation angle of the ellipse in radians, counterclockwise from the positive X axis (optional). Default is *0*.

- - Note: When going clockwise it's best to set the start angle to (Math.PI * 2) and then work towards lower numbers.

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isEllipseCurve]

-

- Used to check whether this or derived classes are EllipseCurves. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Float aX]

The X center of the ellipse.

@@ -94,6 +85,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/LineCurve.html b/docs/api/en/extras/curves/LineCurve.html index cad8ffa2d63018..f16102dd36f8bb 100644 --- a/docs/api/en/extras/curves/LineCurve.html +++ b/docs/api/en/extras/curves/LineCurve.html @@ -27,13 +27,6 @@

[name]( [param:Vector2 v1], [param:Vector2 v2] )

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isLineCurve]

-

- Used to check whether this or derived classes are LineCurves. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Vector2 v1]

The start point.

@@ -46,6 +39,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/LineCurve3.html b/docs/api/en/extras/curves/LineCurve3.html index d9952ea8972b87..b10aa050676c82 100644 --- a/docs/api/en/extras/curves/LineCurve3.html +++ b/docs/api/en/extras/curves/LineCurve3.html @@ -27,13 +27,6 @@

[name]( [param:Vector3 v1], [param:Vector3 v2] )

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isLineCurve3]

-

- Used to check whether this or derived classes are LineCurve3s. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Vector3 v1]

The start point.

@@ -45,6 +38,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/QuadraticBezierCurve.html b/docs/api/en/extras/curves/QuadraticBezierCurve.html index f20c947bd81d7d..411d24ffd71610 100644 --- a/docs/api/en/extras/curves/QuadraticBezierCurve.html +++ b/docs/api/en/extras/curves/QuadraticBezierCurve.html @@ -18,23 +18,23 @@

[name]

defined by a startpoint, endpoint and a single control point.

-

Example

+

Code Example

- -var curve = new THREE.QuadraticBezierCurve( - new THREE.Vector2( -10, 0 ), - new THREE.Vector2( 20, 15 ), - new THREE.Vector2( 10, 0 ) -); + + var curve = new THREE.QuadraticBezierCurve( + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( 20, 15 ), + new THREE.Vector2( 10, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -//Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + //Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); +

Constructor

@@ -50,14 +50,6 @@

[name]( [param:Vector2 v0], [param:Vector2 v1], [param:Vector2 v2] )

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isQuadraticBezierCurve]

-

- Used to check whether this or derived classes are QuadraticBezierCurves. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

- -

[property:Vector2 v0]

The startpoint.

@@ -72,6 +64,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/QuadraticBezierCurve3.html b/docs/api/en/extras/curves/QuadraticBezierCurve3.html index 74070efb5bd309..50bd3af004f221 100644 --- a/docs/api/en/extras/curves/QuadraticBezierCurve3.html +++ b/docs/api/en/extras/curves/QuadraticBezierCurve3.html @@ -18,23 +18,23 @@

[name]

defined by a startpoint, endpoint and a single control point.

-

Example

+

Code Example

- -var curve = new THREE.QuadraticBezierCurve3( - new THREE.Vector3( -10, 0, 0 ), - new THREE.Vector3( 20, 15, 0 ), - new THREE.Vector3( 10, 0, 0 ) -); + + var curve = new THREE.QuadraticBezierCurve3( + new THREE.Vector3( -10, 0, 0 ), + new THREE.Vector3( 20, 15, 0 ), + new THREE.Vector3( 10, 0, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); +

Constructor

@@ -51,13 +51,6 @@

[name]( [param:Vector3 v0], [param:Vector3 v1], [param:Vector3 v2] )

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isQuadraticBezierCurve3]

-

- Used to check whether this or derived classes are QuadraticBezierCurve3s. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Vector3 v0]

The startpoint.

@@ -72,6 +65,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/curves/SplineCurve.html b/docs/api/en/extras/curves/SplineCurve.html index 0ec633793ee1c9..308db8da61c30b 100644 --- a/docs/api/en/extras/curves/SplineCurve.html +++ b/docs/api/en/extras/curves/SplineCurve.html @@ -17,26 +17,26 @@

[name]

[page:Interpolations.CatmullRom] to create the curve.

-

Example

+

Code Example

- -// Create a sine-like wave -var curve = new THREE.SplineCurve( [ - new THREE.Vector2( -10, 0 ), - new THREE.Vector2( -5, 5 ), - new THREE.Vector2( 0, 0 ), - new THREE.Vector2( 5, -5 ), - new THREE.Vector2( 10, 0 ) -] ); + + // Create a sine-like wave + var curve = new THREE.SplineCurve( [ + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( -5, 5 ), + new THREE.Vector2( 0, 0 ), + new THREE.Vector2( 5, -5 ), + new THREE.Vector2( 10, 0 ) + ] ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var splineObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var splineObject = new THREE.Line( geometry, material ); +

Constructor

@@ -48,13 +48,6 @@

[name]( [param:Array points] )

Properties

See the base [page:Curve] class for common properties.

-

[property:Boolean isSplineCurve]

-

- Used to check whether this or derived classes are SplineCurves. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Array points]

The array of [page:Vector2] points that define the curve.

@@ -67,6 +60,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/extras/objects/ImmediateRenderObject.html b/docs/api/en/extras/objects/ImmediateRenderObject.html index cf2558e5083a2b..820bf80f5a3936 100644 --- a/docs/api/en/extras/objects/ImmediateRenderObject.html +++ b/docs/api/en/extras/objects/ImmediateRenderObject.html @@ -37,6 +37,8 @@

[method:null render]([param:Function renderCallback])

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/BoxBufferGeometry.html b/docs/api/en/geometries/BoxBufferGeometry.html index d933e81c051720..568d8472f358a3 100644 --- a/docs/api/en/geometries/BoxBufferGeometry.html +++ b/docs/api/en/geometries/BoxBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); @@ -74,6 +74,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js src/geometries/BoxGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js src/geometries/BoxGeometry.js] +

diff --git a/docs/api/en/geometries/BoxGeometry.html b/docs/api/en/geometries/BoxGeometry.html index 3eb167db1205bf..6772368c705781 100644 --- a/docs/api/en/geometries/BoxGeometry.html +++ b/docs/api/en/geometries/BoxGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); @@ -74,6 +74,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/CircleBufferGeometry.html b/docs/api/en/geometries/CircleBufferGeometry.html index 67f624aab0f29b..d5ba5fdd6eac4b 100644 --- a/docs/api/en/geometries/CircleBufferGeometry.html +++ b/docs/api/en/geometries/CircleBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.CircleBufferGeometry( 5, 32 ); @@ -64,6 +64,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js src/geometries/CircleGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js src/geometries/CircleGeometry.js] +

diff --git a/docs/api/en/geometries/CircleGeometry.html b/docs/api/en/geometries/CircleGeometry.html index 8d7927ae8e17c8..4d6c3558add4e2 100644 --- a/docs/api/en/geometries/CircleGeometry.html +++ b/docs/api/en/geometries/CircleGeometry.html @@ -33,7 +33,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.CircleGeometry( 5, 32 ); @@ -65,6 +65,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/ConeBufferGeometry.html b/docs/api/en/geometries/ConeBufferGeometry.html index 2a35e74bbea26a..b1d0aa210539af 100644 --- a/docs/api/en/geometries/ConeBufferGeometry.html +++ b/docs/api/en/geometries/ConeBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.ConeBufferGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -66,6 +66,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js src/geometries/ConeGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js src/geometries/ConeGeometry.js] +

diff --git a/docs/api/en/geometries/ConeGeometry.html b/docs/api/en/geometries/ConeGeometry.html index 9720d9b2109817..dc2a414a9c840a 100644 --- a/docs/api/en/geometries/ConeGeometry.html +++ b/docs/api/en/geometries/ConeGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.ConeGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -66,6 +66,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/CylinderBufferGeometry.html b/docs/api/en/geometries/CylinderBufferGeometry.html index 4c4f888714f02c..bf95d81ca6dbf4 100644 --- a/docs/api/en/geometries/CylinderBufferGeometry.html +++ b/docs/api/en/geometries/CylinderBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.CylinderBufferGeometry( 5, 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -67,6 +67,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js src/geometries/CylinderGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js src/geometries/CylinderGeometry.js] +

diff --git a/docs/api/en/geometries/CylinderGeometry.html b/docs/api/en/geometries/CylinderGeometry.html index 08e06fa38fe737..74aa5bd6326bf4 100644 --- a/docs/api/en/geometries/CylinderGeometry.html +++ b/docs/api/en/geometries/CylinderGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -67,6 +67,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/DodecahedronBufferGeometry.html b/docs/api/en/geometries/DodecahedronBufferGeometry.html index e285f1953f91e2..f9f3e934426b40 100644 --- a/docs/api/en/geometries/DodecahedronBufferGeometry.html +++ b/docs/api/en/geometries/DodecahedronBufferGeometry.html @@ -53,6 +53,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js src/geometries/DodecahedronGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js src/geometries/DodecahedronGeometry.js] +

diff --git a/docs/api/en/geometries/DodecahedronGeometry.html b/docs/api/en/geometries/DodecahedronGeometry.html index 783cf9f07f4242..7f6f7be1d884f7 100644 --- a/docs/api/en/geometries/DodecahedronGeometry.html +++ b/docs/api/en/geometries/DodecahedronGeometry.html @@ -53,6 +53,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/EdgesGeometry.html b/docs/api/en/geometries/EdgesGeometry.html index c2a53cdf10e3a2..fc16949c05a229 100644 --- a/docs/api/en/geometries/EdgesGeometry.html +++ b/docs/api/en/geometries/EdgesGeometry.html @@ -14,9 +14,7 @@

[name]

This can be used as a helper object to view the edges of a [page:Geometry Geometry] object.

-

Example

- - [example:webgl_helpers helpers] +

Code Example

var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 ); @@ -25,6 +23,11 @@

Example

scene.add( line );
+

Examples

+

+ [example:webgl_helpers helpers] +

+

Constructor

[name]( [param:Geometry geometry], [param:Integer thresholdAngle] )

@@ -46,6 +49,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/ExtrudeBufferGeometry.html b/docs/api/en/geometries/ExtrudeBufferGeometry.html index 5cf5b8f812480d..afca0d6fd02e26 100644 --- a/docs/api/en/geometries/ExtrudeBufferGeometry.html +++ b/docs/api/en/geometries/ExtrudeBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

@@ -107,6 +107,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js src/geometries/ExtrudeGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js src/geometries/ExtrudeGeometry.js] +

diff --git a/docs/api/en/geometries/ExtrudeGeometry.html b/docs/api/en/geometries/ExtrudeGeometry.html index 3b034ad0a61b60..f63062e08c8f9b 100644 --- a/docs/api/en/geometries/ExtrudeGeometry.html +++ b/docs/api/en/geometries/ExtrudeGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

@@ -107,6 +107,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/IcosahedronBufferGeometry.html b/docs/api/en/geometries/IcosahedronBufferGeometry.html index 2b8a081ea18bc6..8b5723cb767ec7 100644 --- a/docs/api/en/geometries/IcosahedronBufferGeometry.html +++ b/docs/api/en/geometries/IcosahedronBufferGeometry.html @@ -52,6 +52,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js src/geometries/IcosahedronGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js src/geometries/IcosahedronGeometry.js] +

diff --git a/docs/api/en/geometries/IcosahedronGeometry.html b/docs/api/en/geometries/IcosahedronGeometry.html index 47c6b33b0cd5a9..3e71e0b8f72a60 100644 --- a/docs/api/en/geometries/IcosahedronGeometry.html +++ b/docs/api/en/geometries/IcosahedronGeometry.html @@ -53,6 +53,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/LatheBufferGeometry.html b/docs/api/en/geometries/LatheBufferGeometry.html index b0bac164437d31..e7fc809e500b47 100644 --- a/docs/api/en/geometries/LatheBufferGeometry.html +++ b/docs/api/en/geometries/LatheBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var points = []; @@ -71,6 +71,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js src/geometries/LatheGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js src/geometries/LatheGeometry.js] +

diff --git a/docs/api/en/geometries/LatheGeometry.html b/docs/api/en/geometries/LatheGeometry.html index 5f7921bdf42a63..4461140f3b2100 100644 --- a/docs/api/en/geometries/LatheGeometry.html +++ b/docs/api/en/geometries/LatheGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var points = []; @@ -71,6 +71,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/OctahedronBufferGeometry.html b/docs/api/en/geometries/OctahedronBufferGeometry.html index fc03ad3d782afd..bbf3b2c5528e44 100644 --- a/docs/api/en/geometries/OctahedronBufferGeometry.html +++ b/docs/api/en/geometries/OctahedronBufferGeometry.html @@ -52,6 +52,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js src/geometries/OctahedronGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js src/geometries/OctahedronGeometry.js] +

diff --git a/docs/api/en/geometries/OctahedronGeometry.html b/docs/api/en/geometries/OctahedronGeometry.html index 139aa373bea9f2..bbd6cde5278ed4 100644 --- a/docs/api/en/geometries/OctahedronGeometry.html +++ b/docs/api/en/geometries/OctahedronGeometry.html @@ -53,6 +53,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/ParametricBufferGeometry.html b/docs/api/en/geometries/ParametricBufferGeometry.html index a7d32b007b93f5..e979b9a9bb63a0 100644 --- a/docs/api/en/geometries/ParametricBufferGeometry.html +++ b/docs/api/en/geometries/ParametricBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.ParametricBufferGeometry( THREE.ParametricGeometries.klein, 25, 25 ); @@ -65,6 +65,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ParametricGeometry.js src/geometries/ParametricGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ParametricGeometry.js src/geometries/ParametricGeometry.js] +

diff --git a/docs/api/en/geometries/ParametricGeometry.html b/docs/api/en/geometries/ParametricGeometry.html index e7e1d45a5d0265..b7b1b32d16ad94 100644 --- a/docs/api/en/geometries/ParametricGeometry.html +++ b/docs/api/en/geometries/ParametricGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.ParametricGeometry( THREE.ParametricGeometries.klein, 25, 25 ); @@ -66,6 +66,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/PlaneBufferGeometry.html b/docs/api/en/geometries/PlaneBufferGeometry.html index 424071d2485a67..26b84eaef2cb6b 100644 --- a/docs/api/en/geometries/PlaneBufferGeometry.html +++ b/docs/api/en/geometries/PlaneBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.PlaneBufferGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ); @@ -63,6 +63,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js src/geometries/PlaneGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js src/geometries/PlaneGeometry.js] +

diff --git a/docs/api/en/geometries/PlaneGeometry.html b/docs/api/en/geometries/PlaneGeometry.html index 787ae77db2eb6a..8135e35524d87c 100644 --- a/docs/api/en/geometries/PlaneGeometry.html +++ b/docs/api/en/geometries/PlaneGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.PlaneGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ); @@ -63,6 +63,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/PolyhedronBufferGeometry.html b/docs/api/en/geometries/PolyhedronBufferGeometry.html index 5a29c31ff1deeb..39bcb566d182c9 100644 --- a/docs/api/en/geometries/PolyhedronBufferGeometry.html +++ b/docs/api/en/geometries/PolyhedronBufferGeometry.html @@ -19,7 +19,7 @@

[name]

and [page:TetrahedronBufferGeometry] to generate their respective geometries.

-

Example

+

Code Example

var verticesOfCube = [ -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1, @@ -62,6 +62,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/PolyhedronGeometry.js src/geometries/PolyhedronGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/PolyhedronGeometry.js src/geometries/PolyhedronGeometry.js] +

diff --git a/docs/api/en/geometries/PolyhedronGeometry.html b/docs/api/en/geometries/PolyhedronGeometry.html index 351471ddd5fbb6..d05ea4b72e2d28 100644 --- a/docs/api/en/geometries/PolyhedronGeometry.html +++ b/docs/api/en/geometries/PolyhedronGeometry.html @@ -17,7 +17,7 @@

[name]

project them onto a sphere, and then divide them up to the desired level of detail.

-

Example

+

Code Example

var verticesOfCube = [ -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1, @@ -60,6 +60,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/RingBufferGeometry.html b/docs/api/en/geometries/RingBufferGeometry.html index 6f2048c6e39d5b..0ff12b940507fd 100644 --- a/docs/api/en/geometries/RingBufferGeometry.html +++ b/docs/api/en/geometries/RingBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.RingBufferGeometry( 1, 5, 32 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } ); @@ -66,6 +66,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js src/geometries/RingGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js src/geometries/RingGeometry.js] +

diff --git a/docs/api/en/geometries/RingGeometry.html b/docs/api/en/geometries/RingGeometry.html index d3e1e6439e4b53..e63aab46fd9609 100644 --- a/docs/api/en/geometries/RingGeometry.html +++ b/docs/api/en/geometries/RingGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.RingGeometry( 1, 5, 32 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } ); @@ -65,6 +65,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/ShapeBufferGeometry.html b/docs/api/en/geometries/ShapeBufferGeometry.html index 860e1c05612453..3dd694d63e7f20 100644 --- a/docs/api/en/geometries/ShapeBufferGeometry.html +++ b/docs/api/en/geometries/ShapeBufferGeometry.html @@ -33,7 +33,7 @@

[name]

-

Example

+

Code Example

@@ -77,6 +77,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js src/geometries/ShapeGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js src/geometries/ShapeGeometry.js] +

diff --git a/docs/api/en/geometries/ShapeGeometry.html b/docs/api/en/geometries/ShapeGeometry.html index 714e8c2baee84d..3abaafd12bdeb9 100644 --- a/docs/api/en/geometries/ShapeGeometry.html +++ b/docs/api/en/geometries/ShapeGeometry.html @@ -33,7 +33,7 @@

[name]

-

Example

+

Code Example

@@ -77,6 +77,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/SphereBufferGeometry.html b/docs/api/en/geometries/SphereBufferGeometry.html index 4d6b25db806fa2..99ff2b9514994c 100644 --- a/docs/api/en/geometries/SphereBufferGeometry.html +++ b/docs/api/en/geometries/SphereBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -71,6 +71,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js src/geometries/SphereGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js src/geometries/SphereGeometry.js] +

diff --git a/docs/api/en/geometries/SphereGeometry.html b/docs/api/en/geometries/SphereGeometry.html index 312df59592e704..08ed82d137d2fc 100644 --- a/docs/api/en/geometries/SphereGeometry.html +++ b/docs/api/en/geometries/SphereGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.SphereGeometry( 5, 32, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -71,6 +71,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/TetrahedronBufferGeometry.html b/docs/api/en/geometries/TetrahedronBufferGeometry.html index 2bab1dcbe53f9a..d0b91263695c21 100644 --- a/docs/api/en/geometries/TetrahedronBufferGeometry.html +++ b/docs/api/en/geometries/TetrahedronBufferGeometry.html @@ -53,6 +53,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js src/geometries/TetrahedronGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js src/geometries/TetrahedronGeometry.js] +

diff --git a/docs/api/en/geometries/TetrahedronGeometry.html b/docs/api/en/geometries/TetrahedronGeometry.html index f247431ecd50d3..74bdee7f808135 100644 --- a/docs/api/en/geometries/TetrahedronGeometry.html +++ b/docs/api/en/geometries/TetrahedronGeometry.html @@ -53,6 +53,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/TextBufferGeometry.html b/docs/api/en/geometries/TextBufferGeometry.html index 33416c64d78402..0adcdb2378a390 100644 --- a/docs/api/en/geometries/TextBufferGeometry.html +++ b/docs/api/en/geometries/TextBufferGeometry.html @@ -36,11 +36,7 @@

[name]

-

Examples

- -

- [example:webgl_geometry_text geometry / text ] -

+

Code Example

var loader = new THREE.FontLoader(); @@ -61,6 +57,12 @@

Examples

} );
+

Examples

+ +

+ [example:webgl_geometry_text geometry / text ] +

+

Constructor

[name]([param:String text], [param:Object parameters])

@@ -168,6 +170,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TextGeometry.js src/geometries/TextGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TextGeometry.js src/geometries/TextGeometry.js] +

diff --git a/docs/api/en/geometries/TextGeometry.html b/docs/api/en/geometries/TextGeometry.html index 7e72d4c548a7a7..cbc59530e44515 100644 --- a/docs/api/en/geometries/TextGeometry.html +++ b/docs/api/en/geometries/TextGeometry.html @@ -15,7 +15,7 @@

[name]

A class for generating text as a single geometry. It is constructed by providing a string of text, and a hash of parameters consisting of a loaded [page:Font] and settings for the geometry's parent [page:ExtrudeGeometry]. - See the [page:Font], [page:FontLoader] and [page:Creating_Text] pages for additional details. + See the [page:Font], [page:FontLoader] and [page:Creating-Text] pages for additional details.

@@ -36,11 +36,7 @@

[name]

-

Examples

- -

- [example:webgl_geometry_text geometry / text ] -

+

Code Example

var loader = new THREE.FontLoader(); @@ -61,6 +57,12 @@

Examples

} );
+

Examples

+ +

+ [example:webgl_geometry_text geometry / text ] +

+

Constructor

[name]([param:String text], [param:Object parameters])

@@ -168,6 +170,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/TorusBufferGeometry.html b/docs/api/en/geometries/TorusBufferGeometry.html index 51b59baeea16ea..42af60e94a4b8a 100644 --- a/docs/api/en/geometries/TorusBufferGeometry.html +++ b/docs/api/en/geometries/TorusBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.TorusBufferGeometry( 10, 3, 16, 100 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -64,6 +64,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js src/geometries/TorusGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js src/geometries/TorusGeometry.js] +

diff --git a/docs/api/en/geometries/TorusGeometry.html b/docs/api/en/geometries/TorusGeometry.html index afbdd48749ef54..5648ddaa8e93e9 100644 --- a/docs/api/en/geometries/TorusGeometry.html +++ b/docs/api/en/geometries/TorusGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.TorusGeometry( 10, 3, 16, 100 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -64,6 +64,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/TorusKnotBufferGeometry.html b/docs/api/en/geometries/TorusKnotBufferGeometry.html index ca6c229bc3546c..5d6e6986862e16 100644 --- a/docs/api/en/geometries/TorusKnotBufferGeometry.html +++ b/docs/api/en/geometries/TorusKnotBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.TorusKnotBufferGeometry( 10, 3, 100, 16 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -67,6 +67,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js src/geometries/TorusKnotGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js src/geometries/TorusKnotGeometry.js] +

diff --git a/docs/api/en/geometries/TorusKnotGeometry.html b/docs/api/en/geometries/TorusKnotGeometry.html index e0a1cb3ef9590d..8b0e9b451f9677 100644 --- a/docs/api/en/geometries/TorusKnotGeometry.html +++ b/docs/api/en/geometries/TorusKnotGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

var geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -68,6 +68,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/TubeBufferGeometry.html b/docs/api/en/geometries/TubeBufferGeometry.html index 28f50b20206f0f..aea2ca3b12a47d 100644 --- a/docs/api/en/geometries/TubeBufferGeometry.html +++ b/docs/api/en/geometries/TubeBufferGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

function CustomSinCurve( scale ) { @@ -104,6 +104,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js src/geometries/TubeGeometry.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js src/geometries/TubeGeometry.js] +

diff --git a/docs/api/en/geometries/TubeGeometry.html b/docs/api/en/geometries/TubeGeometry.html index 3f6213e60285cf..92ce572c1efe59 100644 --- a/docs/api/en/geometries/TubeGeometry.html +++ b/docs/api/en/geometries/TubeGeometry.html @@ -32,7 +32,7 @@

[name]

-

Example

+

Code Example

function CustomSinCurve( scale ) { @@ -104,6 +104,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/geometries/WireframeGeometry.html b/docs/api/en/geometries/WireframeGeometry.html index 789733b0f1ffac..6c440a69c13103 100644 --- a/docs/api/en/geometries/WireframeGeometry.html +++ b/docs/api/en/geometries/WireframeGeometry.html @@ -14,41 +14,27 @@

[name]

This can be used as a helper object to view a [page:Geometry Geometry] object as a wireframe.

- - -

Example

- - [example:webgl_helpers helpers] +

Code Example

-var geometry = new THREE.SphereBufferGeometry( 100, 100, 100 ); + var geometry = new THREE.SphereBufferGeometry( 100, 100, 100 ); -var wireframe = new THREE.WireframeGeometry( geometry ); + var wireframe = new THREE.WireframeGeometry( geometry ); -var line = new THREE.LineSegments( wireframe ); -line.material.depthTest = false; -line.material.opacity = 0.25; -line.material.transparent = true; + var line = new THREE.LineSegments( wireframe ); + line.material.depthTest = false; + line.material.opacity = 0.25; + line.material.transparent = true; -scene.add( line ); + scene.add( line ); +

Examples

+ +

+ [example:webgl_helpers helpers] +

+

Constructor

[name]( [param:Geometry geometry] )

@@ -64,6 +50,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/ArrowHelper.html b/docs/api/en/helpers/ArrowHelper.html index 0d0fa114afda01..434624c5509467 100644 --- a/docs/api/en/helpers/ArrowHelper.html +++ b/docs/api/en/helpers/ArrowHelper.html @@ -14,12 +14,7 @@

[name]

An 3D arrow object for visualizing directions.

- -

Example

- -
[example:webgl_geometries WebGL / geometries]
-
[example:webgl_geometry_normals WebGL / geometry / normals]
-
[example:webgl_shadowmesh WebGL / shadowmesh]
+

Code Example

var dir = new THREE.Vector3( 1, 2, 0 ); @@ -35,11 +30,16 @@

Example

scene.add( arrowHelper );
+

Examples

+

+ [example:webgl_geometries WebGL / geometries]
+ [example:webgl_geometry_normals WebGL / geometry / normals]
+ [example:webgl_shadowmesh WebGL / shadowmesh] +

Constructor

-

[name]([param:Vector3 dir], [param:Vector3 origin], [param:Number length], [param:Number hex], [param:Number headLength], [param:Number headWidth] )

[page:Vector3 dir] -- direction from origin. Must be a unit vector.
@@ -47,27 +47,21 @@

[name]([param:Vector3 dir], [param:Vector3 origin], [param:Number length], [ [page:Number length] -- length of the arrow. Default is *1*.
[page:Number hex] -- hexadecimal value to define color. Default is 0xffff00.
[page:Number headLength] -- The length of the head of the arrow. Default is 0.2 * length.
- [page:Number headWidth] -- The length of the width of the arrow. Default is 0.2 * headLength. + [page:Number headWidth] -- The width of the head of the arrow. Default is 0.2 * headLength.

Properties

See the base [page:Object3D] class for common properties.

-

[property:Line line]

Contains the line part of the arrowHelper.

[property:Mesh cone]

Contains the cone part of the arrowHelper.

- - -

Methods

See the base [page:Object3D] class for common methods.

- -

[method:null setColor]([param:Color color])

color -- The desired color.

@@ -79,7 +73,7 @@

[method:null setLength]([param:Number length], [param:Number headLength], [p

length -- The desired length.
headLength -- The length of the head of the arrow.
- headWidth -- The length of the width of the arrow.

+ headWidth -- The width of the head of the arrow.

Sets the length of the arrowhelper.

@@ -93,6 +87,8 @@

[method:null setDirection]([param:Vector3 dir])

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/AxesHelper.html b/docs/api/en/helpers/AxesHelper.html index 1b5ed6c6da8270..7999d820f5ae12 100644 --- a/docs/api/en/helpers/AxesHelper.html +++ b/docs/api/en/helpers/AxesHelper.html @@ -13,21 +13,23 @@

[name]

An axis object to visualize the 3 axes in a simple way.
- The X axis is red. The Y axis is green. The Z axis is blue.

- - -

Example

- -
[example:webgl_geometries WebGL / geometries]
-
[example:webgl_geometry_convex WebGL / geometry / convex]
-
[example:webgl_geometry_spline_editor WebGL / geometry / spline / editor]
- + The X axis is red. The Y axis is green. The Z axis is blue. +

+

Code Example

var axesHelper = new THREE.AxesHelper( 5 ); scene.add( axesHelper ); - +
+ +

Examples

+ +

+ [example:webgl_geometries WebGL / geometries]
+ [example:webgl_geometry_convex WebGL / geometry / convex]
+ [example:webgl_geometry_spline_editor WebGL / geometry / spline / editor] +

Constructor

@@ -45,6 +47,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/Box3Helper.html b/docs/api/en/helpers/Box3Helper.html index 0190101aa0204d..67cde3c3a31792 100644 --- a/docs/api/en/helpers/Box3Helper.html +++ b/docs/api/en/helpers/Box3Helper.html @@ -17,7 +17,7 @@

[name]

-

Example

+

Code Example

var box = new THREE.Box3(); @@ -59,6 +59,8 @@

[method:void updateMatrixWorld]( [param:Boolean force] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/BoxHelper.html b/docs/api/en/helpers/BoxHelper.html index 782d9ab4062cd1..f3caba4810996a 100644 --- a/docs/api/en/helpers/BoxHelper.html +++ b/docs/api/en/helpers/BoxHelper.html @@ -19,21 +19,22 @@

[name]

so it won't work with [page:Sprite Sprites].

- -

Example

- -
[example:webgl_helpers WebGL / helpers]
-
[example:webgl_loader_nrrd WebGL / loader / nrrd]
-
[example:webgl_buffergeometry_drawcalls advanced / buffergeometry / drawcalls]
- +

Code Example

- var sphere = new THREE.SphereGeometry(); - var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ) ); - var box = new THREE.BoxHelper( object, 0xffff00 ); - scene.add( box ); + var sphere = new THREE.SphereBufferGeometry(); + var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ) ); + var box = new THREE.BoxHelper( object, 0xffff00 ); + scene.add( box ); +

Examples

+ +

+ [example:webgl_helpers WebGL / helpers]
+ [example:webgl_loader_nrrd WebGL / loader / nrrd]
+ [example:webgl_buffergeometry_drawrange WebGL / buffergeometry / drawrange] +

Constructor

@@ -69,6 +70,8 @@

[method:BoxHelper setFromObject]( [param:Object3D object] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/CameraHelper.html b/docs/api/en/helpers/CameraHelper.html index 5ff6378657d140..a445155d071088 100644 --- a/docs/api/en/helpers/CameraHelper.html +++ b/docs/api/en/helpers/CameraHelper.html @@ -17,17 +17,18 @@

[name]

It visualizes the frustum of a camera using a [page:LineSegments].

-

Example

- -
[example:webgl_camera WebGL / camera]
-
[example:webgl_geometry_extrude_splines WebGL / extrude / splines]
- +

Code Example

var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var helper = new THREE.CameraHelper( camera ); scene.add( helper ); +

Examples

+

+ [example:webgl_camera WebGL / camera]
+ [example:webgl_geometry_extrude_splines WebGL / extrude / splines] +

Constructor

@@ -74,6 +75,8 @@

[method:null update]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/DirectionalLightHelper.html b/docs/api/en/helpers/DirectionalLightHelper.html index b46dd06dd92be1..d1a5d9d9d6a23a 100644 --- a/docs/api/en/helpers/DirectionalLightHelper.html +++ b/docs/api/en/helpers/DirectionalLightHelper.html @@ -18,17 +18,14 @@

[name]

This consists of plane and a line representing the light's position and direction.

-

Example

+

Code Example

var light = new THREE.DirectionalLight( 0xFFFFFF ); - var helper = new THREE.DirectionalLightHelper( light, 5 ); - scene.add( helper ); -

Constructor

@@ -80,6 +77,8 @@

[method:null update]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/GridHelper.html b/docs/api/en/helpers/GridHelper.html index cb33bafb61215f..c463284b37d043 100644 --- a/docs/api/en/helpers/GridHelper.html +++ b/docs/api/en/helpers/GridHelper.html @@ -9,13 +9,12 @@ [page:Object3D] → [page:Line] → - +

[name]

The GridHelper is an object to define grids. Grids are two-dimensional arrays of lines.

- -

Example

+

Code Example

var size = 10; var divisions = 10; @@ -23,8 +22,12 @@

Example

var gridHelper = new THREE.GridHelper( size, divisions ); scene.add( gridHelper );
- [example:webgl_helpers Example using various helpers] +

Examples

+ +

+ [example:webgl_helpers WebGL / helpers] +

Constructor

@@ -41,6 +44,8 @@

[name]( [param:number size], [param:Number divisions], [param:Color colorCen

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/HemisphereLightHelper.html b/docs/api/en/helpers/HemisphereLightHelper.html index b0e2460935a7f7..8ff48966610268 100644 --- a/docs/api/en/helpers/HemisphereLightHelper.html +++ b/docs/api/en/helpers/HemisphereLightHelper.html @@ -16,14 +16,12 @@

[name]

Creates a visual aid consisting of a spherical [page:Mesh] for a [page:HemisphereLight HemisphereLight].

-

Example

+

Code Example

-var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); - -var helper = new THREE.HemisphereLightHelper( light, 5 ); - -scene.add( helper ); + var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); + var helper = new THREE.HemisphereLightHelper( light, 5 ); + scene.add( helper ); @@ -73,6 +71,8 @@

[method:null update]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/PlaneHelper.html b/docs/api/en/helpers/PlaneHelper.html index 7b65214c0bf974..7f27010c73c65c 100644 --- a/docs/api/en/helpers/PlaneHelper.html +++ b/docs/api/en/helpers/PlaneHelper.html @@ -17,7 +17,7 @@

[name]

-

Example

+

Code Example

var plane = new THREE.Plane( new THREE.Vector3( 1, 1, 0.2 ), 3 ); @@ -60,6 +60,8 @@

[method:void updateMatrixWorld]( [param:Boolean force] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/PointLightHelper.html b/docs/api/en/helpers/PointLightHelper.html index a21653dd4de89b..3c45767343745a 100644 --- a/docs/api/en/helpers/PointLightHelper.html +++ b/docs/api/en/helpers/PointLightHelper.html @@ -17,10 +17,7 @@

[name]

a [page:PointLight].

- -

Example

- - [example:webgl_helpers WebGL / helpers] +

Code Example

var pointLight = new THREE.PointLight( 0xff0000, 1, 100 ); @@ -32,8 +29,11 @@

Example

scene.add( pointLightHelper );
+

Examples

- +

+ [example:webgl_helpers WebGL / helpers] +

Constructor

@@ -79,6 +79,8 @@

[method:null update]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/PolarGridHelper.html b/docs/api/en/helpers/PolarGridHelper.html index 63259c36bd300c..730165c63638e2 100644 --- a/docs/api/en/helpers/PolarGridHelper.html +++ b/docs/api/en/helpers/PolarGridHelper.html @@ -14,10 +14,10 @@

[name]

The PolarGridHelper is an object to define polar grids. Grids are two-dimensional arrays of lines.

+

Code Example

-

Example

- - var radius = 10; + + var radius = 10; var radials = 16; var circles = 8; var divisions = 64; @@ -25,8 +25,12 @@

Example

var helper = new THREE.PolarGridHelper( radius, radials, circles, divisions ); scene.add( helper );
- [example:webgl_helpers Example using various helpers] +

Examples

+ +

+ [example:webgl_helpers WebGL / helpers] +

Constructor

@@ -45,6 +49,8 @@

[name]( [param:Number radius], [param:Number radials], [param:Number circles

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/SkeletonHelper.html b/docs/api/en/helpers/SkeletonHelper.html index bab2b55680622f..bd3a926df4372a 100644 --- a/docs/api/en/helpers/SkeletonHelper.html +++ b/docs/api/en/helpers/SkeletonHelper.html @@ -17,31 +17,30 @@

[name]

The helper is renderered using a [page:LineBasicMaterial LineBasicMaterial].

- -

Example

- - [example:webgl_animation_skinning_blending animation / skinning / blending]
- [example:webgl_animation_skinning_morph animation / skinning / morph]
- [example:webgl_loader_bvh loader / bvh ] +

Code Example

-var helper = new THREE.SkeletonHelper( mesh ); -helper.material.linewidth = 3; -scene.add( helper ); + var helper = new THREE.SkeletonHelper( skinnedMesh ); + scene.add( helper ); +

Examples

+

+ [example:webgl_animation_skinning_blending WebGL / animation / skinning / blending]
+ [example:webgl_animation_skinning_morph WebGL / animation / skinning / morph]
+ [example:webgl_loader_bvh WebGL / loader / bvh ] +

Constructor

-

[name]( object )

+

[name]( [param:Object3D object] )

- object -- can be any object that has an array of [page:Bone Bone]s as a sub object.
- For example, a [page:Skeleton Skeleton] or a [page:SkinnedMesh SkinnedMesh]. + object -- Usually an instance of [page:SkinnedMesh]. However, any instance of [page:Object3D] can be used if it represents + a hierarchy of [page:Bone Bone]s (via [page:Object3D.children]).

-

Properties

[property:Array bones]

@@ -49,14 +48,15 @@

[property:Array bones]

The list of bones that the helper renders as [page:Line Lines].

-

[property:Object root]

+

[property:Object3D root]

The object passed in the constructor.

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/helpers/SpotLightHelper.html b/docs/api/en/helpers/SpotLightHelper.html index f385c80f3885ed..329dfc34c6f136 100644 --- a/docs/api/en/helpers/SpotLightHelper.html +++ b/docs/api/en/helpers/SpotLightHelper.html @@ -14,13 +14,6 @@

[name]

This displays a cone shaped helper object for a [page:SpotLight].

-

Example

- - View in Examples
-

Other Examples

- -
[example:webgl_lights_spotlights lights / spotlights ]
-

Code Example

var spotLight = new THREE.SpotLight( 0xffffff ); @@ -31,10 +24,13 @@

Code Example

scene.add( spotLightHelper );
+

Examples

+

+ [example:webgl_lights_spotlights WebGL/ lights / spotlights ] +

Constructor

-

[name]( [param:SpotLight light], [param:Hex color] )

[page:SpotLight light] -- The [page:SpotLight] to be visualized.

@@ -63,8 +59,8 @@

[property:object matrixAutoUpdate]

[property:hex color]

- The color parameter passed in the constructor. Default is *undefined*. If this is changed, the helper's color will update - the next time [page:.update update] is called. + The color parameter passed in the constructor. Default is *undefined*. If this is changed, the helper's color will update + the next time [page:.update update] is called.

Methods

@@ -78,6 +74,8 @@

[method:null update]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/AmbientLight.html b/docs/api/en/lights/AmbientLight.html index 4f78e0025e58c1..3699321811fd5e 100644 --- a/docs/api/en/lights/AmbientLight.html +++ b/docs/api/en/lights/AmbientLight.html @@ -18,16 +18,19 @@

[name]

This light cannot be used to cast shadows as it does not have a direction.

+

Code Example

-

Example

+ + var light = new THREE.AmbientLight( 0x404040 ); // soft white light + scene.add( light ); + + +

Examples

- [example:webgl_animation_cloth animation / cloth ]
- [example:webgl_animation_skinning_blending animation / skinning / blending ] + [example:webgl_animation_cloth animation / cloth ]
+ [example:webgl_animation_skinning_blending animation / skinning / blending ]

-var light = new THREE.AmbientLight( 0x404040 ); // soft white light -scene.add( light ); -

Constructor

[name]( [param:Integer color], [param:Float intensity] )

@@ -49,21 +52,14 @@

[property:Boolean castShadow]

-

[property:Boolean isAmbientLight]

-

- Used to check whether this or derived classes are ambient lights. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

- - -

Methods

See the base [page:Light Light] class for common methods.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/DirectionalLight.html b/docs/api/en/lights/DirectionalLight.html index ff0c498196292a..38f975aa4e3f0a 100644 --- a/docs/api/en/lights/DirectionalLight.html +++ b/docs/api/en/lights/DirectionalLight.html @@ -37,11 +37,17 @@

A Note about Position, Target and rotation

See the [page:.target target] property below for details on updating the target.

+

Code Example

-

Example

+ + // White directional light at half intensity shining from the top. + var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 ); + scene.add( directionalLight ); + + +

Examples

[example:misc_controls_fly controls / fly ]
- [example:webvr_cubes cubes ]
[example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
[example:webgl_effects_stereo effects / stereo ]
[example:webgl_geometry_extrude_splines geometry / extrude / splines ]
@@ -49,13 +55,6 @@

Example

[example:webgl_materials_cubemap_balls_reflection materials / cubemap / balls / reflection ]

- - // White directional light at half intensity shining from the top. - var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 ); - scene.add( directionalLight ); - - -

Constructor

[name]( [param:Integer color], [param:Float intensity] )

@@ -68,7 +67,7 @@

[name]( [param:Integer color], [param:Float intensity] )

Properties

- See the base [page:Light Light] class for common properties. +

See the base [page:Light Light] class for common properties.

[property:Boolean castShadow]

@@ -77,14 +76,6 @@

[property:Boolean castShadow]

The default is *false*.

-

[property:Boolean isDirectionalLight]

-

- Used to check whether this or derived classes are directional lights. Default is *true*.

- - You should not change this, as it is used internally for optimisation. -

- -

[property:Vector3 position]

This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. @@ -126,7 +117,7 @@

[property:Object3D target]

Methods

- See the base [page:Light Light] class for common methods. +

See the base [page:Light Light] class for common methods.

[method:DirectionalLight copy]( [param:DirectionalLight source] )

@@ -136,6 +127,8 @@

[method:DirectionalLight copy]( [param:DirectionalLight source] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/HemisphereLight.html b/docs/api/en/lights/HemisphereLight.html index 2cd77b8037ba4f..1cee0bafbfb178 100644 --- a/docs/api/en/lights/HemisphereLight.html +++ b/docs/api/en/lights/HemisphereLight.html @@ -19,21 +19,23 @@

[name]

This light cannot be used to cast shadows.

-

Example

+

Code Example

-
+ + var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); + scene.add( light ); + + +

Examples

+ +

[example:webgl_lights_hemisphere lights / hemisphere ]
- [example:misc_controls_pointerlock controls / pointerlock ]
- [example:webgl_decals decals ]
- [example:webgl_loader_collada_kinematics loader / collada / kinematics ]
- [example:webgl_materials_lightmap materials / lightmap ]
- [example:webgl_shaders_ocean shaders / ocean ] -

- - -var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); -scene.add( light ); - + [example:misc_controls_pointerlock controls / pointerlock ]
+ [example:webgl_decals decals ]
+ [example:webgl_loader_collada_kinematics loader / collada / kinematics ]
+ [example:webgl_materials_lightmap materials / lightmap ]
+ [example:webgl_shaders_ocean shaders / ocean ] +

Constructor

[name]( [param:Integer skyColor], [param:Integer groundColor], [param:Float intensity] )

@@ -68,13 +70,6 @@

[property:Float groundColor]

Default is a new [page:Color] set to white (0xffffff).

-

[property:Boolean isHemisphereLight]

-

- Used to check whether this or derived classes are hemisphere lights. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Vector3 position]

This is set equal to [page:Object3D.DefaultUp] (0, 1, 0), so that the light shines from the top down. @@ -84,7 +79,7 @@

[property:Vector3 position]

Methods

- See the base [page:Light Light] class for common methods. +

See the base [page:Light Light] class for common methods.

[method:HemisphereLight copy]( [param:HemisphereLight source] )

@@ -94,6 +89,8 @@

[method:HemisphereLight copy]( [param:HemisphereLight source] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/Light.html b/docs/api/en/lights/Light.html index 731eb09bcaacf9..951351410b709a 100644 --- a/docs/api/en/lights/Light.html +++ b/docs/api/en/lights/Light.html @@ -47,13 +47,6 @@

[property:Float intensity]

Default - *1.0*.

-

[property:Boolean isLight]

-

- Used to check whether this or derived classes are lights. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

Methods

@@ -75,6 +68,8 @@

[method:Object toJSON]( [param:object meta] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/PointLight.html b/docs/api/en/lights/PointLight.html index 3011e318f3b4db..b6d99a41ed0675 100644 --- a/docs/api/en/lights/PointLight.html +++ b/docs/api/en/lights/PointLight.html @@ -16,28 +16,27 @@

[name]

A light that gets emitted from a single point in all directions. A common use case for this is to replicate the light emitted from a bare lightbulb.

- This light can cast shadows - see [page:LightShadow] page for details. + This light can cast shadows - see [page:PointLightShadow] page for details.

+

Code Example

-

Example

+ +var light = new THREE.PointLight( 0xff0000, 1, 100 ); +light.position.set( 50, 50, 50 ); +scene.add( light ); + + +

Examples

[example:webgl_lights_pointlights lights / pointlights ]
[example:webgl_lights_pointlights2 lights / pointlights2 ]
- [example:webgldeferred_animation animation ]
[example:webgl_effects_anaglyph effects / anaglyph ]
[example:webgl_geometry_text geometry / text ]
[example:webgl_lensflares lensflares ]

- -var light = new THREE.PointLight( 0xff0000, 1, 100 ); -light.position.set( 50, 50, 50 ); -scene.add( light ); - - -

Constructor

[name]( [param:Integer color], [param:Float intensity], [param:Number distance], [param:Float decay] )

@@ -80,13 +79,6 @@

[property:Float distance]

Default is *0.0*.

-

[property:Boolean isPointLight]

-

- Used to check whether this or derived classes are point lights. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Float power]

The light's power.
@@ -100,9 +92,9 @@

[property:Float power]

and changing this will also change the intensity.

-

[property:LightShadow shadow]

+

[property:PointLightShadow shadow]

- A [page:LightShadow] used to calculate shadows for this light.

+ A [page:PointLightShadow] used to calculate shadows for this light.

The lightShadow's [page:LightShadow.camera camera] is set to a [page:PerspectiveCamera] with [page:PerspectiveCamera.fov fov] of 90, @@ -123,6 +115,8 @@

[method:PointLight copy]( [param:PointLight source] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/RectAreaLight.html b/docs/api/en/lights/RectAreaLight.html index bb63576be52b54..ad767e1ae3c11d 100644 --- a/docs/api/en/lights/RectAreaLight.html +++ b/docs/api/en/lights/RectAreaLight.html @@ -20,18 +20,13 @@

[name]

  • There is no shadow support.
  • Only [page:MeshStandardMaterial MeshStandardMaterial] and [page:MeshPhysicalMaterial MeshPhysicalMaterial] are supported.
  • -
  • You have to include [link:https://threejs.org/examples/js/lights/RectAreaLightUniformsLib.js RectAreaLightUniformsLib] into your scene and call *init()*.
  • +
  • You have to include [link:https://threejs.org/examples/jsm/lights/RectAreaLightUniformsLib.js RectAreaLightUniformsLib] into your scene and call *init()*.

+

Code Example

- -

Examples

- -

- [example:webgl_lights_rectarealight WebGL / rectarealight ] - - + var width = 10; var height = 10; var intensity = 1; @@ -43,9 +38,13 @@

Examples

rectLightHelper = new THREE.RectAreaLightHelper( rectLight ); rectLight.add( rectLightHelper ); - -

+
+ +

Examples

+

+ [example:webgl_lights_rectarealight WebGL / rectarealight ] +

Constructor

@@ -65,13 +64,6 @@

Properties

See the base [page:Light Light] class for common properties.

-

[property:Boolean isRectAreaLight]

-

- Used to check whether this or derived classes are RectAreaLights. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

Methods

See the base [page:Light Light] class for common methods. @@ -84,6 +76,8 @@

[method:RectAreaLight copy]( [param:RectAreaLight source] )

RectAreaLight.

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/SpotLight.html b/docs/api/en/lights/SpotLight.html index b276add5943377..515325a7c40cfa 100644 --- a/docs/api/en/lights/SpotLight.html +++ b/docs/api/en/lights/SpotLight.html @@ -19,32 +19,6 @@

[name]

This light can cast shadows - see the [page:SpotLightShadow] page for details.

- - - -

Example

- - -

- [example:webgl_lights_spotlight View in Examples ] -

- -

Other Examples

- -

- [example:webgl_interactive_cubes_gpu interactive / cubes / gpu ]
- [example:webgl_interactive_draggablecubes interactive / draggablecubes ]
- [example:webgl_materials_bumpmap_skin materials / bumpmap / skin ]
- [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
- [example:webgl_loader_md2 loader / md2 ]
- [example:webgl_shading_physical shading / physical ]
- [example:webgl_materials_bumpmap materials / bumpmap]
- [example:webgl_shading_physical shading / physical]
- [example:webgl_shadowmap shadowmap]
- [example:webgl_shadowmap_performance shadowmap / performance]
- [example:webgl_shadowmap_viewer shadowmap / viewer] -

-

Code Example

// white spotlight shining from the side, casting a shadow @@ -64,6 +38,13 @@

Code Example

scene.add( spotLight );
+

Examples

+ +

+ [example:webgl_lights_spotlight lights / spotlight ]
+ [example:webgl_lights_spotlights lights / spotlights ] +

+

Constructor

@@ -83,7 +64,7 @@

[name]( [param:Integer color], [param:Float intensity], [param:Float distanc

Properties

- See the base [page:Light Light] class for common properties. +

See the base [page:Light Light] class for common properties.

[property:Float angle]

@@ -123,13 +104,6 @@

[property:Float distance]

Default is *0.0*.

-

[property:Boolean isSpotLight]

-

- Used to check whether this or derived classes are spot lights. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Float penumbra]

Percent of the spotlight cone that is attenuated due to penumbra. Takes values between @@ -188,7 +162,7 @@

[property:Object3D target]

Methods

- See the base [page:Light Light] class for common methods. +

See the base [page:Light Light] class for common methods.

[method:SpotLight copy]( [param:SpotLight source] )

@@ -196,6 +170,8 @@

[method:SpotLight copy]( [param:SpotLight source] )

SpotLight.

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/lights/shadows/DirectionalLightShadow.html b/docs/api/en/lights/shadows/DirectionalLightShadow.html index aa6e59eb0fce19..e7f1dc95e0fd33 100644 --- a/docs/api/en/lights/shadows/DirectionalLightShadow.html +++ b/docs/api/en/lights/shadows/DirectionalLightShadow.html @@ -20,46 +20,45 @@

[name]

are parallel.

-

Example

-

- -//Create a WebGLRenderer and turn on shadows in the renderer -var renderer = new THREE.WebGLRenderer(); -renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - -//Create a DirectionalLight and turn on shadows for the light -var light = new THREE.DirectionalLight( 0xffffff, 1, 100 ); -light.position.set( 0, 1, 0 ); //default; light shining from top -light.castShadow = true; // default false -scene.add( light ); - -//Set up shadow properties for the light -light.shadow.mapSize.width = 512; // default -light.shadow.mapSize.height = 512; // default -light.shadow.camera.near = 0.5; // default -light.shadow.camera.far = 500; // default - -//Create a sphere that cast shadows (but does not receive them) -var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); -var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); -var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -sphere.castShadow = true; //default is false -sphere.receiveShadow = false; //default -scene.add( sphere ); - -//Create a plane that receives shadows (but does not cast them) -var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); -var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.receiveShadow = true; -scene.add( plane ); - -//Create a helper for the shadow camera (optional) -var helper = new THREE.CameraHelper( light.shadow.camera ); -scene.add( helper ); - -

+

Code Example

+ + + //Create a WebGLRenderer and turn on shadows in the renderer + var renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + //Create a DirectionalLight and turn on shadows for the light + var light = new THREE.DirectionalLight( 0xffffff, 1, 100 ); + light.position.set( 0, 1, 0 ); //default; light shining from top + light.castShadow = true; // default false + scene.add( light ); + + //Set up shadow properties for the light + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500; // default + + //Create a sphere that cast shadows (but does not receive them) + var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); + var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + //Create a plane that receives shadows (but does not cast them) + var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); + var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + //Create a helper for the shadow camera (optional) + var helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); +

Constructor

[name]( )

@@ -92,6 +91,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

diff --git a/docs/api/en/lights/shadows/LightShadow.html b/docs/api/en/lights/shadows/LightShadow.html index 782ccafa955dd0..fa8aaca7c7cd84 100644 --- a/docs/api/en/lights/shadows/LightShadow.html +++ b/docs/api/en/lights/shadows/LightShadow.html @@ -12,60 +12,18 @@

[name]

- This is used internally by [page:PointLight PointLights] for calculating shadows, and also serves as - a base class for the other shadow classes. + Serves as a base class for the other shadow classes.

-

Example

-

- -//Create a WebGLRenderer and turn on shadows in the renderer -var renderer = new THREE.WebGLRenderer(); -renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - -//Create a PointLight and turn on shadows for the light -var light = new THREE.PointLight( 0xffffff, 1, 100 ); -light.position.set( 0, 10, 0 ); -light.castShadow = true; // default false -scene.add( light ); - -//Set up shadow properties for the light -light.shadow.mapSize.width = 512; // default -light.shadow.mapSize.height = 512; // default -light.shadow.camera.near = 0.5; // default -light.shadow.camera.far = 500 // default - -//Create a sphere that cast shadows (but does not receive them) -var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); -var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); -var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -sphere.castShadow = true; //default is false -sphere.receiveShadow = false; //default -scene.add( sphere ); - -//Create a plane that receives shadows (but does not cast them) -var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); -var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.receiveShadow = true; -scene.add( plane ); - -//Create a helper for the shadow camera (optional) -var helper = new THREE.CameraHelper( light.shadow.camera ); -scene.add( helper ); - -

-

Constructor

[name]( [param:Camera camera] )

[page:Camera camera] - the light's view of the world.

- Create a new [name]. This is not intended to be called directly - it is called - internally by [page:PointLight] or used as a base class by other light shadows. + Create a new [name]. This is not intended to be called directly - it is used as a base class by + other light shadows.

Properties

@@ -88,6 +46,11 @@

[property:WebGLRenderTarget map]

in shadow. Computed internally during rendering.

+

[property:WebGLRenderTarget mapPass]

+

+ The distribution map generated using the internal camera; an occlusion is calculated based + on the distribution of depths. Computed internally during rendering. +

[property:Vector2 mapSize]

@@ -99,7 +62,6 @@

[property:Vector2 mapSize]

The default is *( 512, 512 )*.

-

[property:Matrix4 matrix]

Model to shadow camera space, to compute location and depth in shadow map. Stored @@ -111,17 +73,42 @@

[property:Float radius]

Setting this to values greater than 1 will blur the edges of the shadow.
High values will cause unwanted banding effects in the shadows - a greater [page:.mapSize mapSize] - will allow for a higher value to be used here before these effects become visible.

+ will allow for a higher value to be used here before these effects become visible.
+ If [page:WebGLRenderer.shadowMap.type] is set to [page:Renderer PCFSoftShadowMap], radius has + no effect and it is recommended to increase softness by decreasing [page:.mapSize mapSize] instead.

Note that this has no effect if the [page:WebGLRenderer.shadowMap.type] is set to [page:Renderer BasicShadowMap].

Methods

+ +

[method:Vector2 getFrameExtents]()

+

+ Used internally by the renderer to extend the shadow map to contain all viewports +

+ +

[method:null updateMatrices]( [param:Light light] )

+

+ Update the matrices for the camera and shadow, used internally by the renderer.

+ + light -- the light for which the shadow is being rendered. +

+ +

[method:Frustum getFrustum]()

+

+ Gets the shadow cameras frustum. Used internally by the renderer to cull objects. +

+ +

[method:number getViewportCount]()

+

+ Used internally by the renderer to get the number of viewports that need to be rendered for this shadow. +

+

[method:LightShadow copy]( [param:LightShadow source] )

Copies value of all the properties from the [page:LightShadow source] to this - SpotLight. + Light.

[method:LightShadow clone]()

@@ -136,6 +123,8 @@

[method:Object toJSON]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

diff --git a/docs/api/en/lights/shadows/PointLightShadow.html b/docs/api/en/lights/shadows/PointLightShadow.html new file mode 100644 index 00000000000000..9ebdaacce0a22f --- /dev/null +++ b/docs/api/en/lights/shadows/PointLightShadow.html @@ -0,0 +1,90 @@ + + + + + + + + + + + +

[name]

+ +

+ This is used internally by [page:PointLight PointLights] for calculating shadows. +

+ + +

Code Example

+ + //Create a WebGLRenderer and turn on shadows in the renderer + var renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + //Create a PointLight and turn on shadows for the light + var light = new THREE.PointLight( 0xffffff, 1, 100 ); + light.position.set( 0, 10, 0 ); + light.castShadow = true; // default false + scene.add( light ); + + //Set up shadow properties for the light + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500 // default + + //Create a sphere that cast shadows (but does not receive them) + var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); + var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + //Create a plane that receives shadows (but does not cast them) + var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); + var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + //Create a helper for the shadow camera (optional) + var helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); + + +

Constructor

+

[name]( )

+

+ Creates a new [name]. This is not intended to be called directly - it is called + internally by [page:PointLight]. +

+ +

Properties

+

+ See the base [page:LightShadow LightShadow] class for common properties. +

+ +

Methods

+ +

+ See the base [page:LightShadow LightShadow] class for common methods. +

+ +

[method:null updateMatrices]( [param:Light light], [param:number viewportIndex])

+

+ Update the matrices for the camera and shadow, used internally by the renderer.

+ + light -- the light for which the shadow is being rendered.
+ viewportIndex -- calculates the matrix for this viewport +

+ +

Source

+ +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

+ + diff --git a/docs/api/en/lights/shadows/SpotLightShadow.html b/docs/api/en/lights/shadows/SpotLightShadow.html index 4815f157c503b0..a0c39bc70814a1 100644 --- a/docs/api/en/lights/shadows/SpotLightShadow.html +++ b/docs/api/en/lights/shadows/SpotLightShadow.html @@ -16,53 +16,50 @@

[name]

This is used internally by [page:SpotLight SpotLights] for calculating shadows.

-

Example

-

- -//Create a WebGLRenderer and turn on shadows in the renderer -var renderer = new THREE.WebGLRenderer(); -renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - -//Create a SpotLight and turn on shadows for the light -var light = new THREE.SpotLight( 0xffffff ); -light.castShadow = true; // default false -scene.add( light ); - -//Set up shadow properties for the light -light.shadow.mapSize.width = 512; // default -light.shadow.mapSize.height = 512; // default -light.shadow.camera.near = 0.5; // default -light.shadow.camera.far = 500 // default - -//Create a sphere that cast shadows (but does not receive them) -var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); -var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); -var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -sphere.castShadow = true; //default is false -sphere.receiveShadow = false; //default -scene.add( sphere ); - -//Create a plane that receives shadows (but does not cast them) -var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); -var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.receiveShadow = true; -scene.add( plane ); - -//Create a helper for the shadow camera (optional) -var helper = new THREE.CameraHelper( light.shadow.camera ); -scene.add( helper ); - -

- +

Code Example

+ + //Create a WebGLRenderer and turn on shadows in the renderer + var renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + //Create a SpotLight and turn on shadows for the light + var light = new THREE.SpotLight( 0xffffff ); + light.castShadow = true; // default false + scene.add( light ); + + //Set up shadow properties for the light + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500 // default + + //Create a sphere that cast shadows (but does not receive them) + var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); + var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + //Create a plane that receives shadows (but does not cast them) + var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); + var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + //Create a helper for the shadow camera (optional) + var helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); +

Constructor

- The constructor creates a [param:PerspectiveCamera PerspectiveCamera] to manage the shadow's view of the world. +

The constructor creates a [param:PerspectiveCamera PerspectiveCamera] to manage the shadow's view of the world.

Properties

- See the base [page:LightShadow LightShadow] class for common properties. +

See the base [page:LightShadow LightShadow] class for common properties.

[property:Camera camera]

@@ -79,15 +76,8 @@

[property:Camera camera]

-

[property:Boolean isSpotLightShadow]

-

- Used to check whether this or derived classes are spot light shadows. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

Methods

- See the base [page:LightShadow LightShadow] class for common methods. +

See the base [page:LightShadow LightShadow] class for common methods.

[method:SpotLightShadow update]( [param:SpotLight light] )

@@ -96,6 +86,8 @@

[method:SpotLightShadow update]( [param:SpotLight light] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

diff --git a/docs/api/en/loaders/AnimationLoader.html b/docs/api/en/loaders/AnimationLoader.html index 9b0eb60374a697..f95ce00d1a5516 100644 --- a/docs/api/en/loaders/AnimationLoader.html +++ b/docs/api/en/loaders/AnimationLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -15,7 +17,7 @@

[name]

This uses the [page:FileLoader] internally for loading files.

-

Example

+

Code Example

// instantiate a loader @@ -53,13 +55,10 @@

[name]( [param:LoadingManager manager] )

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

+

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -80,16 +79,10 @@

[method:Array parse]( [param:JSON json] )

be parsed with [page:AnimationClip.parse].

-

[method:AnimationLoader setPath]( [param:String path] )

-

- [page:String path] — Base path of the file to load.

- - Sets the base path or URL from which to load files. This can be useful if - you are loading many animations from the same directory. -

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/AudioLoader.html b/docs/api/en/loaders/AudioLoader.html index 39cfe23c9319d8..e05e5d2ab86a71 100644 --- a/docs/api/en/loaders/AudioLoader.html +++ b/docs/api/en/loaders/AudioLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -16,7 +18,7 @@

[name]

This uses the [page:FileLoader] internally for loading files.

-

Example

+

Code Example

// instantiate a listener @@ -62,23 +64,18 @@

Example

Constructor

-

[name]( [param:String context], [param:LoadingManager manager] )

+

[name]( [param:LoadingManager manager] )

- [page:String context] — The [page:String AudioContext] for the loader to use. Default is [page:String window.AudioContext].
[page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].

Creates a new [name].

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

- +

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -92,16 +89,10 @@

[method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and pass the loaded [page:String AudioBuffer] to onLoad.

-

[method:AudioLoader setPath]( [param:String path] )

-

- [page:String path] — Base path of the file to load.

- - Sets the base path or URL from which to load files. This can be useful if - you are loading many audios from the same directory. -

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/BufferGeometryLoader.html b/docs/api/en/loaders/BufferGeometryLoader.html index 6ff54cb87cb046..1cb29c76f19a00 100644 --- a/docs/api/en/loaders/BufferGeometryLoader.html +++ b/docs/api/en/loaders/BufferGeometryLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -15,9 +17,7 @@

[name]

This uses the [page:FileLoader] internally for loading files.

-

Example

- - [example:webgl_geometry_colors_lookuptable WebGL / geometry / colors / lookuptable] +

Code Example

// instantiate a loader @@ -47,6 +47,12 @@

Example

);
+

Examples

+ +

+ [example:webgl_performance WebGL / performance] +

+

Constructor

[name]( [param:LoadingManager manager] )

@@ -57,15 +63,11 @@

[name]( [param:LoadingManager manager] )

Creates a new [name].

-

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

+

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -85,16 +87,10 @@

[method:BufferGeometry parse]( [param:Object json] )

Parse a JSON structure and return a [page:BufferGeometry].

-

[method:BufferGeometryLoader setPath]( [param:String path] )

-

- [page:String path] — Base path of the file to load.

- - Sets the base path or URL from which to load files. This can be useful if - you are loading many geometries from the same directory. -

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/Cache.html b/docs/api/en/loaders/Cache.html index f0f9d81ff19a6d..2a0b3fe4c4940d 100644 --- a/docs/api/en/loaders/Cache.html +++ b/docs/api/en/loaders/Cache.html @@ -14,6 +14,14 @@

[name]

A simple caching system, used internally by [page:FileLoader].

+

Code Example

+ +

To enable caching across all loaders that use [page:FileLoader], set

+ + THREE.Cache.enabled = true. + + +

Examples

@@ -22,14 +30,6 @@

Examples

[example:webgl_loader_ttf WebGL / loader / ttf]

-

Usage

- -

To enable caching across all loaders that use [page:FileLoader], set

- -THREE.Cache.enabled = true. - - -

Properties

[property:Boolean enabled]

@@ -70,6 +70,8 @@

[method:null clear]()

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/CompressedTextureLoader.html b/docs/api/en/loaders/CompressedTextureLoader.html index 514cfe8dbcc8a9..293830ae1963c2 100644 --- a/docs/api/en/loaders/CompressedTextureLoader.html +++ b/docs/api/en/loaders/CompressedTextureLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -18,8 +20,8 @@

[name]

Examples

- See the [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/DDSLoader.js DDSLoader] - and [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PVRLoader.js PVRLoader] + See the [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/DDSLoader.js DDSLoader] + and [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PVRLoader.js PVRLoader] for examples of derived classes.

@@ -33,20 +35,11 @@

[name]( [param:LoadingManager manager] )

Creates a new [name].

-

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

- -

[property:String path]

-

The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.

- - +

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:CompressedTexture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -60,14 +53,10 @@

[method:CompressedTexture load]( [param:String url], [param:Function onLoad] Begin loading from url and pass the loaded texture to onLoad.

-

[method:FileLoader setPath]( [param:String path] )

-

- Set the base path or URL from which to load files. This can be useful if - you are loading many textures from the same directory. -

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/CubeTextureLoader.html b/docs/api/en/loaders/CubeTextureLoader.html index 35ed5bf93def27..0065713dcd8c8b 100644 --- a/docs/api/en/loaders/CubeTextureLoader.html +++ b/docs/api/en/loaders/CubeTextureLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -15,15 +17,7 @@

[name]

This uses the [page:ImageLoader] internally for loading files.

-

Example

- -

- [example:webgl_materials_cubemap materials / cubemap]
- [example:webgl_materials_cubemap_balls_reflection materials / cubemap / balls / reflection]
- [example:webgl_materials_cubemap_balls_refraction materials / cubemap / balls / refraction]
- [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic]
- [example:webgl_materials_cubemap_refraction materials / cubemap / refraction] -

+

Code Example

var scene = new THREE.Scene(); @@ -39,6 +33,16 @@

Example

] );
+

Examples

+ +

+ [example:webgl_materials_cubemap materials / cubemap]
+ [example:webgl_materials_cubemap_balls_reflection materials / cubemap / balls / reflection]
+ [example:webgl_materials_cubemap_balls_refraction materials / cubemap / balls / refraction]
+ [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic]
+ [example:webgl_materials_cubemap_refraction materials / cubemap / refraction] +

+

Constructor

[name]( [param:LoadingManager manager] )

@@ -48,27 +52,11 @@

[name]( [param:LoadingManager manager] )

Creates a new [name].

-

Properties

- -

[property:String crossOrigin]

-

- If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - attribute of the image to the value of *crossOrigin*, - prior to starting the load. Default is *"anonymous"*. -

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

- -

[property:String path]

-

The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.

- - +

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:CubeTexture load]( [param:String urls], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -86,17 +74,10 @@

[method:CubeTexture load]( [param:String urls], [param:Function onLoad], [pa Begin loading from url and pass the loaded [page:CubeTexture texture] to onLoad.

-

[method:null setCrossOrigin]( [param:String value] )

-

Set the [page:.crossOrigin] attribute.

+

Source

-

[method:FileLoader setPath]( [param:String path] )

- Set the base path or URL from which to load files. This can be useful if - you are loading many textures from the same directory. + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

- -

Source

- - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/DataTextureLoader.html b/docs/api/en/loaders/DataTextureLoader.html index a3a68f8f846ac3..7bcaaed1d0cf7a 100644 --- a/docs/api/en/loaders/DataTextureLoader.html +++ b/docs/api/en/loaders/DataTextureLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -19,7 +21,7 @@

[name]

Examples

- See the [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/RGBELoader.js RGBELoader] + See the [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/RGBELoader.js RGBELoader] for an example of a derived class.

@@ -33,16 +35,11 @@

[name]( [param:LoadingManager manager] )

Creates a new [name].

-

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

- +

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:DataTexture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -56,16 +53,10 @@

[method:DataTexture load]( [param:String url], [param:Function onLoad], [par Begin loading from url and pass the loaded texture to onLoad.

-

[method:DataTextureLoader setPath]( [param:String path] )

-

- [page:String path] — Base path of the file to load.

- - Sets the base path or URL from which to load files. This can be useful if - you are loading many data textures from the same directory. -

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/FileLoader.html b/docs/api/en/loaders/FileLoader.html index 6b391139e647f3..ab81a82539ece2 100644 --- a/docs/api/en/loaders/FileLoader.html +++ b/docs/api/en/loaders/FileLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

[name]

@@ -16,7 +17,7 @@

[name]

It can also be used directly to load any file type that does not have a loader.

-

Example

+

Code Example

var loader = new THREE.FileLoader(); @@ -59,13 +60,8 @@

[name] ( [param:LoadingManager manager] )

Default is [page:DefaultLoadingManager].

-

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

+

See the base [page:Loader] class for common properties.

[property:String mimeType]

@@ -73,9 +69,6 @@

[property:String mimeType]

See [page:.setMimeType]. Default is *undefined*.

-

[property:String path]

-

The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.

-

[property:Object requestHeader]

The [link:https://developer.mozilla.org/en-US/docs/Glossary/Request_header request header] used in HTTP request. See [page:.setRequestHeader]. Default is *undefined*.

@@ -88,8 +81,8 @@

[property:String withCredentials]

Default is *undefined*.

-

Methods

+

See the base [page:Loader] class for common methods.

[method:XMLHttpRequest load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -109,12 +102,6 @@

[method:FileLoader setMimeType]( [param:String mimeType] )

of the file being loaded. Note that in many cases this will be determined automatically, so by default it is *undefined*.

-

[method:FileLoader setPath]( [param:String path] )

-

- Set the base path or URL from which to load files. This can be useful if - you are loading many models from the same directory. -

-

[method:FileLoader setRequestHeader]( [param:Object requestHeader] )

[page:object requestHeader] - key: The name of the header whose value is to be set. value: The value to set as the body of the header.

@@ -142,6 +129,8 @@

[method:FileLoader setWithCredentials]( [param:Boolean value] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/FontLoader.html b/docs/api/en/loaders/FontLoader.html index 504d61c91e1bd6..67401a297d0a47 100644 --- a/docs/api/en/loaders/FontLoader.html +++ b/docs/api/en/loaders/FontLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -18,12 +20,7 @@

[name]

You can convert fonts online using [link:https://gero3.github.io/facetype.js/ facetype.js]

-

Examples

- -

- [example:webgl_geometry_text_shapes geometry / text / shapes ]
- [example:webgl_geometry_text geometry / text ] -

+

Code Example

var loader = new THREE.FontLoader(); @@ -49,6 +46,13 @@

Examples

);
+

Examples

+ +

+ [example:webgl_geometry_text_shapes geometry / text / shapes ]
+ [example:webgl_geometry_text geometry / text ] +

+

Constructor

[name]( [param:LoadingManager manager] )

@@ -58,16 +62,10 @@

[name]( [param:LoadingManager manager] )

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

- -

[property:String path]

-

The base path from which fonts will be loaded. See [page:.setPath]. Default is *undefined*.

+

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -86,14 +84,10 @@

[method:Font parse]( [param:Object json] )

Parse a JSON structure and return a [page:Font].

-

[method:FontLoader setPath]( [param:String path] )

-

- Set the base path or URL from which to load fonts. This can be useful if - you are loading many fonts from the same directory. -

-

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/ImageBitmapLoader.html b/docs/api/en/loaders/ImageBitmapLoader.html index 83bda10b65fcb4..6f4fa666df6f4d 100644 --- a/docs/api/en/loaders/ImageBitmapLoader.html +++ b/docs/api/en/loaders/ImageBitmapLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -23,11 +25,7 @@

[name]

instead. Refer to [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.10 WebGL specification] for the detail.

-

Example

- -

- [example:webgl_loader_imagebitmap WebGL / loader / ImageBitmap] -

+

Code Example

// instantiate a loader @@ -57,6 +55,11 @@

Example

);
+

Examples

+ +

+ [example:webgl_loader_imagebitmap WebGL / loader / ImageBitmap] +

Constructor

@@ -68,19 +71,13 @@

[name]( [param:LoadingManager manager] )

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

+

See the base [page:Loader] class for common properties.

[property:String options]

An optional object that sets options for the internally used [link:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap createImageBitmap] factory method. Default is *undefined*.

-

[property:String path]

-

The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.

-

Methods

+

See the base [page:Loader] class for common methods.

[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -94,23 +91,15 @@

[method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and return the [page:ImageBitmap image] object that will contain the data.

-

[method:ImageBitmapLoader setCrossOrigin]()

-

This method exists for compatibility reasons and implements no logic. It ensures that [name] has a similar interface like [page:ImageLoader].

-

[method:ImageBitmapLoader setOptions]( [param:Object options] )

Sets the options object for [link:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap createImageBitmap].

-

[method:ImageBitmapLoader setPath]( [param:String path] )

-

- Sets the base path or URL from which to load files. This can be useful if - you are loading many images from the same directory. -

- -

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/ImageLoader.html b/docs/api/en/loaders/ImageLoader.html index 4704cb298996d5..32a258c89beea8 100644 --- a/docs/api/en/loaders/ImageLoader.html +++ b/docs/api/en/loaders/ImageLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -16,12 +18,7 @@

[name]

[page:CubeTextureLoader], [page:ObjectLoader] and [page:TextureLoader].

-

Example

- -

- [example:webgl_loader_obj WebGL / loader / obj]
- [example:webgl_shaders_ocean WebGL / shaders / ocean] -

+

Code Example

// instantiate a loader @@ -55,6 +52,13 @@

Example

that supports progress events, see [link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-275785639 this thread].

+

Examples

+ +

+ [example:webgl_loader_obj WebGL / loader / obj]
+ [example:webgl_shaders_ocean WebGL / shaders / ocean] +

+

Constructor

[name]( [param:LoadingManager manager] )

@@ -65,22 +69,10 @@

[name]( [param:LoadingManager manager] )

Properties

- -

[property:String crossOrigin]

-

- If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*. -

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

- -

[property:String path]

-

The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.

+

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:HTMLImageElement load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -94,17 +86,10 @@

[method:HTMLImageElement load]( [param:String url], [param:Function onLoad], Begin loading from url and return the [page:Image image] object that will contain the data.

-

[method:null setCrossOrigin]( [param:String value] )

-

Set the [page:.crossOrigin] attribute.

+

Source

-

[method:FileLoader setPath]( [param:String path] )

- Set the base path or URL from which to load files. This can be useful if - you are loading many images from the same directory. + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

- -

Source

- - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/Loader.html b/docs/api/en/loaders/Loader.html index d4007244c88a16..c070231c5bfd93 100644 --- a/docs/api/en/loaders/Loader.html +++ b/docs/api/en/loaders/Loader.html @@ -16,79 +16,71 @@

[name]

Constructor

-

[name]()

+

[name]( [param:LoadingManager manager] )

- Creates a new [name]. This should be called as base class. + [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager]. +

+

+ Creates a new [name].

Properties

-

[property:Function onLoadStart]

-

Will be called when load starts.

-

The default is a function with empty body.

- -

[property:Function onLoadProgress]

-

Will be called while load progresses.

-

The default is a function with empty body.

- -

[property:Function onLoadComplete]

-

Will be called when load completes.

-

The default is a function with empty body.

-

[property:string crossOrigin]

The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. - Default is *"anonymous"*. + Default is *anonymous*.

-

Methods

- -

[method:Material createMaterial]( [param:object m], [param:string texturePath] )

-

- [page:Object m] — The parameters to create the material.
- [page:String texturePath] — The base path of the textures. -

+

[property:LoadingManager manager]

- Creates the Material based on the parameters m. + The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager].

-

[method:Array initMaterials]( [param:Array materials], [param:string texturePath] )

+

[property:String path]

- [page:Array materials] — an array of parameters to create materials.
- [page:String texturePath] — The base path of the textures. + The base path from which the asset will be loaded. + Default is the empty string.

+ +

[property:String resourcePath]

- Creates an array of [page:Material] based on the array of parameters m. The index of the parameters decide the correct index of the materials. + The base path from which additional resources like textures will be loaded. + Default is the empty string.

-

Handlers

+

Methods

+

[method:void load]()

- *[name].Handlers* is a special object normally used by other loaders like [page:GLTFLoader] or [page:MTLLoader]. It provides an - API that allows the definition of special mappings: What loaders should be used in order to load specific files. A typical use case - is to overwrite the default loader for textures.

- - Note: It's only possible to use *[name].Handlers* if the respective loader support the usage. + This method needs to be implement by all concrete loaders. It holds the logic for loading the asset from the backend.

-

[method:null add]( [param:Object regex], [param:Loader loader] )

+

[method:void parse]()

- [page:Object regex] — A regular expression.
- [page:Loader loader] — The loader. + This method needs to be implement by all concrete loaders. It holds the logic for parsing the asset into three.js entities. +

+ +

[method:Loader setCrossOrigin]( [param:String crossOrigin] )

- Registers a loader with the given regular expression. + [page:String crossOrigin] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS.

-

[method:null get]( [param:String file] )

+

[method:Loader setPath]( [param:String path] )

- [page:String file] — The file path. + [page:String path] — Set the base path for the asset. +

+ +

[method:Loader setResourcePath]( [param:String resourcePath] )

- Can be used to retrieve the registered loader for the given file path. + [page:String resourcePath] — Set the base path for dependent resources like textures.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/LoaderUtils.html b/docs/api/en/loaders/LoaderUtils.html index 05df4cf0888d82..4da1f5f5e31f49 100644 --- a/docs/api/en/loaders/LoaderUtils.html +++ b/docs/api/en/loaders/LoaderUtils.html @@ -33,6 +33,8 @@

[method:String extractUrlBase]( [param:string url] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/MaterialLoader.html b/docs/api/en/loaders/MaterialLoader.html index c9030598d273bd..08664632b6a931 100644 --- a/docs/api/en/loaders/MaterialLoader.html +++ b/docs/api/en/loaders/MaterialLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -15,8 +17,7 @@

[name]

This uses the [page:FileLoader] internally for loading files.

-

Example

- +

Code Example

// instantiate a loader @@ -54,17 +55,13 @@

[name]( [param:LoadingManager manager] )

Properties

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

+

See the base [page:Loader] class for common properties.

[property:Object textures]

Object holding any textures used by the material. See [page:.setTextures].

-

Methods

+

See the base [page:Loader] class for common methods.

[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -84,14 +81,6 @@

[method:Material parse]( [param:Object json] )

Parse a JSON structure and create a new [page:Material] of the type [page:String json.type] with parameters defined in the json object.

-

[method:MaterialLoader setPath]( [param:String path] )

-

- [page:String path] — Base path of the file to load.

- - Sets the base path or URL from which to load files. This can be useful if - you are loading many materials from the same directory. -

-

[method:MaterialLoader setTextures]( [param:Object textures] )

[page:Object textures] — object containing any textures used by the material. @@ -99,6 +88,8 @@

[method:MaterialLoader setTextures]( [param:Object textures] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/loaders/ObjectLoader.html b/docs/api/en/loaders/ObjectLoader.html index 75c8acc58e713f..0d4c3e1289b15a 100644 --- a/docs/api/en/loaders/ObjectLoader.html +++ b/docs/api/en/loaders/ObjectLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -16,12 +18,7 @@

[name]

This uses the [page:FileLoader] internally for loading files.

-

Example

- -

- [example:webgl_loader_json_claraio WebGL / loader / json / claraio]
- [example:webgl_materials_lightmap WebGL / materials / lightmap] -

+

Code Example

var loader = new THREE.ObjectLoader(); @@ -55,7 +52,12 @@

Example

scene.add( object );
+

Examples

+

+ [example:webgl_loader_json_claraio WebGL / loader / json / claraio]
+ [example:webgl_materials_lightmap WebGL / materials / lightmap] +

Constructor

@@ -66,27 +68,11 @@

[name]( [param:LoadingManager manager] )

Creates a new [name].

-

Properties

- -

[property:String crossOrigin]

-

- If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*. -

- -

[property:LoadingManager manager]

-

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. -

- -

[property:String resourcePath]

-

- The base path or URL from which additional resources like textuures will be loaded. See [page:.setResourcePath]. - Default is the empty string. -

+

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -206,23 +192,10 @@

[method:Object3D parseObject]( [param:Object json] )

-

[method:ObjectLoader setCrossOrigin]( [param:String value] )

-

- [page:String value] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. -

- -

[method:ObjectLoader setPath]( [param:String value] )

-

- Set the base path for the original file. -

+

Source

-

[method:ObjectLoader setResourcePath]( [param:String value] )

- Set the base path for dependent resources like textures. + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

- -

Source

- - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/TextureLoader.html b/docs/api/en/loaders/TextureLoader.html index 867ef79a351491..1461c5990db4e0 100644 --- a/docs/api/en/loaders/TextureLoader.html +++ b/docs/api/en/loaders/TextureLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

[name]

@@ -15,7 +17,7 @@

[name]

This uses the [page:ImageLoader] internally for loading files.

-

Example

+

Code Example

var texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' ); @@ -24,9 +26,7 @@

Example

var material = new THREE.MeshBasicMaterial( { map: texture } );
- [example:webgl_geometry_cube geometry / cube] - -

Example with Callbacks

+

Code Example with Callbacks

// instantiate a loader @@ -55,37 +55,31 @@

Example with Callbacks

);
- Please note three.js r84 dropped support for TextureLoader progress events. For a TextureLoader that supports progress events, see [link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-293260145 this thread]. - -

Constructor

- -

[name]( [param:LoadingManager manager] )

- [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].

- - Creates a new [name]. + Please note three.js r84 dropped support for TextureLoader progress events. For a TextureLoader that supports progress events, see [link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-293260145 this thread].

+

Examples

-

Properties

- -

[property:String crossOrigin]

- If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*. + [example:webgl_geometry_cube geometry / cube]

+

Constructor

-

[property:LoadingManager manager]

+

[name]( [param:LoadingManager manager] )

- The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager]. + [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].

+ + Creates a new [name].

-

[property:String path]

-

The base path from which files will be loaded. See [page:.setPath]. Default is *undefined*.

+

Properties

+

See the base [page:Loader] class for common properties.

Methods

+

See the base [page:Loader] class for common methods.

[method:Texture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -99,18 +93,10 @@

[method:Texture load]( [param:String url], [param:Function onLoad], [param:F If you do it this way, the texture may pop up in your scene once the respective loading process is finished.

-

[method:null setCrossOrigin]( [param:String value] )

-

Set the [page:.crossOrigin] attribute.

+

Source

-

[method:FileLoader setPath]( [param:String path] )

- Set the base path or URL from which to load files. This can be useful if - you are loading many models from the same directory. + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

- - -

Source

- - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/en/loaders/managers/DefaultLoadingManager.html b/docs/api/en/loaders/managers/DefaultLoadingManager.html index f608c7e1ec04b2..ade7913d6429d4 100644 --- a/docs/api/en/loaders/managers/DefaultLoadingManager.html +++ b/docs/api/en/loaders/managers/DefaultLoadingManager.html @@ -17,7 +17,7 @@

[name]

for say, textures and models.

-

Example

+

Code Example

You can optionally set the [page:LoadingManager.onStart onStart], [page:LoadingManager.onLoad onLoad], @@ -66,6 +66,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

diff --git a/docs/api/en/loaders/managers/LoadingManager.html b/docs/api/en/loaders/managers/LoadingManager.html index 034baa13a21c34..5b2686dcd9509b 100644 --- a/docs/api/en/loaders/managers/LoadingManager.html +++ b/docs/api/en/loaders/managers/LoadingManager.html @@ -19,17 +19,7 @@

[name]

- -

Example

- -

- [example:webgl_loader_babylon WebGL / loader / babylon]
- [example:webgl_loader_fbx WebGL / loader / fbx]
- [example:webgl_loader_obj WebGL / loader / obj]
- [example:webgl_materials_reflectivity WebGL / materials / reflectivity]
- [example:webgl_postprocessing_outline WebGL / postprocesing / outline]
- [example:webgl_terrain_dynamic WebGL / terrain / dynamic] -

+

Code Example

This example shows how to use LoadingManager to track the progress of @@ -107,6 +97,15 @@

Example

});
+

Examples

+ +

+ [example:webgl_loader_fbx WebGL / loader / fbx]
+ [example:webgl_loader_obj WebGL / loader / obj]
+ [example:webgl_materials_physical_reflectivity WebGL / materials / physical / reflectivity]
+ [example:webgl_postprocessing_outline WebGL / postprocesing / outline] +

+

Constructor

[name]( [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

@@ -160,14 +159,31 @@

[property:Function onError]

Methods

-

[method:null setURLModifier]( [param:Function callback] )

+

[method:LoadingManager addHandler]( [param:Object regex], [param:Loader loader] )

- [page:Function callback] — URL modifier callback. Called with [page:String url] argument, and - must return [page:String resolvedURL].

+ [page:Object regex] — A regular expression.
+ [page:Loader loader] — The loader. +

+ Registers a loader with the given regular expression. Can be used to define what loader should be used in + order to load specific files. A typical use case is to overwrite the default loader for textures. +

+ +// add handler for TGA textures +manager.addHandler( /\.tga$/i, new TGALoader() ); + - If provided, the callback will be passed each resource URL before a request is sent. The - callback may return the original URL, or a new URL to override loading behavior. This - behavior can be used to load assets from .ZIP files, drag-and-drop APIs, and Data URIs. +

[method:null getHandler]( [param:String file] )

+

+ [page:String file] — The file path. +

+ Can be used to retrieve the registered loader for the given file path. +

+ +

[method:LoadingManager removeHandler]( [param:Object regex] )

+

+ [page:Object regex] — A regular expression. +

+ Removes the loader for the given regular expression.

[method:String resolveURL]( [param:String url] )

@@ -178,7 +194,18 @@

[method:String resolveURL]( [param:String url] )

URL modifier is set, returns the original URL.

-

+

[method:null setURLModifier]( [param:Function callback] )

+

+ [page:Function callback] — URL modifier callback. Called with [page:String url] argument, and + must return [page:String resolvedURL].

+ + If provided, the callback will be passed each resource URL before a request is sent. The + callback may return the original URL, or a new URL to override loading behavior. This + behavior can be used to load assets from .ZIP files, drag-and-drop APIs, and Data URIs. +

+ +
+

Note: The following methods are designed to be called internally by loaders. You shouldn't call them directly. @@ -198,7 +225,6 @@

[method:null itemEnd]( [param:String url] )

This should be called by any loader using the manager when the loader ended loading an url.

-

[method:null itemError]( [param:String url] )

[page:String url] — the loaded url

@@ -208,6 +234,8 @@

[method:null itemError]( [param:String url] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

diff --git a/docs/api/en/materials/LineBasicMaterial.html b/docs/api/en/materials/LineBasicMaterial.html index f0b85b1d029a02..88d6474f8486d5 100644 --- a/docs/api/en/materials/LineBasicMaterial.html +++ b/docs/api/en/materials/LineBasicMaterial.html @@ -14,6 +14,17 @@

[name]

A material for drawing wireframe-style geometries.

+

Code Example

+ + + var material = new THREE.LineBasicMaterial( { + color: 0xffffff, + linewidth: 1, + linecap: 'round', //ignored by WebGLRenderer + linejoin: 'round' //ignored by WebGLRenderer + } ); + +

Examples

@@ -33,15 +44,6 @@

Examples

[example:webgl_physics_rope WebGL / phyics / rope]

- -var material = new THREE.LineBasicMaterial( { - color: 0xffffff, - linewidth: 1, - linecap: 'round', //ignored by WebGLRenderer - linejoin: 'round' //ignored by WebGLRenderer -} ); - -

Constructor

[name]( [param:Object parameters] )

@@ -60,16 +62,6 @@

Properties

[property:Color color]

[page:Color] of the material, by default set to white (0xffffff).

-

[property:Boolean isLineBasicMaterial]

-

- Used to check whether this or derived classes are line basic materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

- -

[property:Boolean lights]

-

Whether the material is affected by lights. Default is *false*.

-

[property:Float linewidth]

Controls line thickness. Default is *1*.

@@ -102,6 +94,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/LineDashedMaterial.html b/docs/api/en/materials/LineDashedMaterial.html index cfa1fef5d2ce14..c8c79cbf5a825a 100644 --- a/docs/api/en/materials/LineDashedMaterial.html +++ b/docs/api/en/materials/LineDashedMaterial.html @@ -8,46 +8,42 @@ - [page:Material] → + [page:Material] → [page:LineBasicMaterial] →

[name]

A material for drawing wireframe-style geometries with dashed lines.

+

Code Example

+ + + var material = new THREE.LineDashedMaterial( { + color: 0xffffff, + linewidth: 1, + scale: 1, + dashSize: 3, + gapSize: 1, + } ); + +

Examples

[example:webgl_lines_dashed WebGL / lines / dashed]

- -var material = new THREE.LineDashedMaterial( { - color: 0xffffff, - linewidth: 1, - scale: 1, - dashSize: 3, - gapSize: 1, -} ); - -

Constructor

[name]( [param:Object parameters] )

[page:Object parameters] - (optional) an object with one or more properties defining the material's appearance. - Any property of the material (including any property inherited from [page:Material]) can be passed in here.

- - The exception is the property [page:Hexadecimal color], which can be passed i as a hexadecimal - string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally. + Any property of the material (including any property inherited from [page:LineBasicMaterial]) can be passed in here.

Properties

-

See the base [page:Material] class for common properties.

- -

[property:Color color]

-

[page:Color] of the material, by default set to white (0xffffff).

+

See the base [page:LineBasicMaterial] class for common properties.

[property:number dashSize]

The size of the dash. This is both the gap with the stroke. Default is *3*.

@@ -55,35 +51,17 @@

[property:number dashSize]

[property:number gapSize]

The size of the gap. Default is *1*.

-

[property:Boolean isLineDashedMaterial]

-

- Used to check whether this or derived classes are line dashed materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

- -

[property:Boolean lights]

-

Whether the material is affected by lights. Default is *false*.

- -

[property:Float linewidth]

-

- Controls line thickness. Default is *1*.

- - Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile] - with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will - always be 1 regardless of the set value. -

[property:number scale]

The scale of the dashed part of a line. Default is *1*.

Methods

-

See the base [page:Material] class for common methods.

- - +

See the base [page:LineBasicMaterial] class for common methods.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/Material.html b/docs/api/en/materials/Material.html index 628bfd334d9142..be34234301dbed 100644 --- a/docs/api/en/materials/Material.html +++ b/docs/api/en/materials/Material.html @@ -128,7 +128,12 @@

[property:Boolean stencilWrite]

Whether rendering this material has any effect on the stencil buffer. Default is *false*.

-

[property:Boolean stencilFunc]

+

[property:Integer stencilWriteMask]

+

+ The bit mask to use when writing to the stencil buffer. Default is *0xFF*. +

+ +

[property:Integer stencilFunc]

The stencil comparison function to use. Default is [page:Materials AlwaysStencilFunc]. See stencil function [page:Materials constants] for all possible values.

@@ -138,9 +143,9 @@

[property:Integer stencilRef]

The value to use when performing stencil comparisons or stencil operations. Default is *0*.

-

[property:Boolean stencilMask]

+

[property:Integer stencilFuncMask]

- The bit mask to use when comparing against or writing to the stencil buffer. Default is *0xFF*. + The bit mask to use when comparing against the stencil buffer. Default is *0xFF*.

[property:Integer stencilFail]

@@ -148,12 +153,12 @@

[property:Integer stencilFail]

Which stencil operation to perform when the comparison function returns false. Default is [page:Materials KeepStencilOp]. See the stencil operations [page:Materials constants] for all possible values.

-

[property:Boolean stencilZFail]

+

[property:Integer stencilZFail]

Which stencil operation to perform when the comparison function returns true but the depth test fails. Default is [page:Materials KeepStencilOp]. See the stencil operations [page:Materials constants] for all possible values.

-

[property:Boolean stencilZPass]

+

[property:Integer stencilZPass]

Which stencil operation to perform when the comparison function returns true and the depth test passes. Default is [page:Materials KeepStencilOp]. See the stencil operations [page:Materials constants] for all possible values.

@@ -169,23 +174,12 @@

[property:Boolean fog]

[property:Integer id]

Unique number for this material instance.

-

[property:Boolean isMaterial]

-

- Used to check whether this or derived classes are materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

- -

[property:Boolean lights]

-

Whether the material is affected by lights. Default is *true*.

-

[property:String name]

Optional name of the object (doesn't need to be unique). Default is an empty string.

[property:Boolean needsUpdate]

- Specifies that the material needs to be recompiled.
- This property is automatically set to *true* when instancing a new material. + Specifies that the material needs to be recompiled.

[property:Float opacity]

@@ -267,13 +261,18 @@

[property:Integer side]

Other options are [page:Materials THREE.BackSide] and [page:Materials THREE.DoubleSide].

+

[property:Boolean toneMapped]

+

+ Defines whether this material is tone mapped according to the renderer's [page:WebGLRenderer.toneMapping toneMapping] setting. Default is *true*. +

+

[property:Boolean transparent]

Defines whether this material is transparent. This has an effect on rendering as transparent objects need special treatment and are rendered after non-transparent objects.
When set to true, the extent to which the material is transparent is - controlled by setting it's [page:Float opacity] property.
+ controlled by setting its [page:Float opacity] property.
Default is *false*.

@@ -289,18 +288,14 @@

[property:String uuid]

This gets automatically assigned, so this shouldn't be edited.

-

[property:Integer vertexColors]

+

[property:Integer version]

- Defines whether vertex coloring is used. - Default is [page:Materials THREE.NoColors]. - Other options are [page:Materials THREE.VertexColors] and [page:Materials THREE.FaceColors]. + This starts at *0* and counts how many times [property:Boolean needsUpdate] is set to *true*.

-

[property:Boolean vertexTangents]

+

[property:Boolean vertexColors]

- Defines whether precomputed vertex tangents, which must be provided in a vec4 "tangent" attribute, - are used. When disabled, tangents are derived automatically. Using precomputed tangents will give - more accurate normal map details in some cases, such as with mirrored UVs. Default is false. + Defines whether vertex coloring is used. Default is *false*.

[property:Boolean visible]

@@ -335,6 +330,9 @@

[method:null onBeforeCompile]( [param:Shader shader], [param:WebGLRenderer r An optional callback that is executed immediately before the shader program is compiled. This function is called with the shader source code as a parameter. Useful for the modification of built-in materials.

+

+ Unlike properties, the callback is not supported by [page:Material.clone .clone](), [page:Material.copy .copy]() and [page:Material.toJSON .toJSON](). +

[method:null setValues]( [param:object values] )

@@ -350,6 +348,8 @@

[method:Object toJSON]( [param:object meta] )

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/MeshBasicMaterial.html b/docs/api/en/materials/MeshBasicMaterial.html index 6addaaad46ae5f..498f58dd56bb2c 100644 --- a/docs/api/en/materials/MeshBasicMaterial.html +++ b/docs/api/en/materials/MeshBasicMaterial.html @@ -64,8 +64,7 @@

[property:Texture alphaMap]

[property:Texture aoMap]

The red channel of this texture is used as the ambient occlusion map. Default is null. - The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat] - and [page:Texture offset] Texture properties.

+ The aoMap requires a second set of UVs.

[property:Float aoMapIntensity]

Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.

@@ -82,27 +81,15 @@

[property:Integer combine]

blend between the two colors.

-

[property:Boolean isMeshBasicMaterial]

-

- Used to check whether this or derived classes are mesh basic materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:TextureCube envMap]

The environment map. Default is null.

[property:Texture lightMap]

-

The light map. Default is null. The lightMap requires a second set of UVs, - and consequently will ignore the [page:Texture repeat] and [page:Texture offset] - Texture properties.

+

The light map. Default is null. The lightMap requires a second set of UVs.

[property:Float lightMapIntensity]

Intensity of the baked light. Default is 1.

-

[property:Boolean lights]

-

Whether the material is affected by lights. Default is *false*.

-

[property:Texture map]

The color map. Default is null.

@@ -161,6 +148,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/MeshDepthMaterial.html b/docs/api/en/materials/MeshDepthMaterial.html index a70032e6551bd0..a69e9bf69958f2 100644 --- a/docs/api/en/materials/MeshDepthMaterial.html +++ b/docs/api/en/materials/MeshDepthMaterial.html @@ -82,16 +82,6 @@

[property:Float displacementBias]

[property:Boolean fog]

Whether the material is affected by fog. Default is *false*.

-

[property:Boolean isMeshDepthMaterial]

-

- Used to check whether this or derived classes are mesh depth materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

- -

[property:Boolean lights]

-

Whether the material is affected by lights. Default is *false*.

-

[property:Texture map]

The color map. Default is null.

@@ -118,6 +108,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/MeshDistanceMaterial.html b/docs/api/en/materials/MeshDistanceMaterial.html index 5a803747d22dde..cede800a03e40c 100644 --- a/docs/api/en/materials/MeshDistanceMaterial.html +++ b/docs/api/en/materials/MeshDistanceMaterial.html @@ -19,9 +19,11 @@

[name]

The following examples demonstrates this approach in order to ensure transparent parts of objects do no cast shadows.

-

Example

+

Examples

- [example:webgl_shadowmap_pointlight WebGL / shadowmap / pointlight] +

+ [example:webgl_shadowmap_pointlight WebGL / shadowmap / pointlight] +

Examples

- [example:webgl_materials_variations_physical materials / variations / physical]
- [example:webgl_materials_reflectivity materials / reflectivity] +

+ [example:webgl_materials_variations_physical materials / variations / physical]
+ [example:webgl_materials_physical_clearcoat materials / physical / clearcoat]
+ [example:webgl_materials_physical_reflectivity materials / physical / reflectivity]
+ [example:webgl_materials_physical_transparency materials / physical / transparency] +

Constructor

@@ -55,25 +80,42 @@

[name]( [param:Object parameters] )

Properties

See the base [page:Material] and [page:MeshStandardMaterial] classes for common properties.

-

[property:Float clearCoat]

+

[property:Float clearcoat]

- ClearCoat level, from *0.0* to *1.0*. Default is *0.0*. + Represents the thickness of the clear coat layer, from *0.0* to *1.0*. Use clear coat related properties to enable multilayer + materials that have a thin translucent layer over the base layer. Default is *0.0*.

-

[property:Float clearCoatRoughness]

-

How rough the clearCoat appears, from *0.0* to *1.0*. Default is *0.0*.

- -

[property:Boolean isMeshPhysicalMaterial]

+

[property:Texture clearcoatMap]

- Used to check whether this or derived classes are mesh physical materials. Default is *true*.

+ The red channel of this texture is multiplied against [page:.clearcoat], for per-pixel control + over a coating's thickness. Default is *null*. +

+ +

[property:Float clearcoatNormalMap]

+

Can be used to enable independent normals for the clear coat layer. Default is *null*.

+ +

[property:Vector2 clearcoatNormalScale]

+

How much [page:.clearcoatNormalMap] affects the clear coat layer, from *(0,0)* to *(1,1)*. Default is *(1,1)*.

- You should not change this, as it used internally for optimisation. +

[property:Float clearcoatRoughness]

+

Roughness of the clear coat layer, from *0.0* to *1.0*. Default is *0.0*.

+ +

[property:Texture clearcoatRoughnessMap]

+

+ The green channel of this texture is multiplied against [page:.clearcoatRoughness], for per-pixel control + over a coating's roughness. Default is *null*.

[property:Object defines]

An object of the form: - { 'PHYSICAL': '' }; + { + + 'STANDARD': '' + 'PHYSICAL': '', + + }; This is used by the [page:WebGLRenderer] for selecting shaders. @@ -86,12 +128,25 @@

[property:Float reflectivity]

This models the reflectivity of non-metallic materials. It has no effect when [page:MeshStandardMaterial.metalness metalness] is *1.0*

+

[property:Float transparency]

+

+ Degree of transparency, from *0.0* to *1.0*. Default is *0.0*.
+ + Thin, transparent or semitransparent, plastic or glass materials remain largely reflective even if they are mostly transparent. + + The transparency property can be used to model these materials.
+ + When transparency is non-zero, [page:Material.opacity opacity] should be set to *1*. +

+

Methods

See the base [page:Material] and [page:MeshStandardMaterial] classes for common methods.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/MeshStandardMaterial.html b/docs/api/en/materials/MeshStandardMaterial.html index e60c56eb213000..e84d6d4ceac3b2 100644 --- a/docs/api/en/materials/MeshStandardMaterial.html +++ b/docs/api/en/materials/MeshStandardMaterial.html @@ -99,8 +99,7 @@

[property:Texture alphaMap]

[property:Texture aoMap]

The red channel of this texture is used as the ambient occlusion map. Default is null. - The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat] - and [page:Texture offset] Texture properties.

+ The aoMap requires a second set of UVs.

[property:Float aoMapIntensity]

Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.

@@ -173,27 +172,18 @@

[property:TextureCube envMap]

if adjusting texture parameters manually, ensure minFilter is set to one of the MipMap options, and that mip maps have not been otherwise forcibly disabled.

- Note: only [link:https://threejs.org/docs/#api/textures/CubeTexture cube environment maps] are supported - for MeshStandardMaterial. If you want to use an equirectangular map you will need to use the - [link:https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/EquirectangularToCubeGenerator.js EquirectangularToCubeGenerator]. + Note: only [link:https://threejs.org/docs/#api/textures/CubeTexture cube environment maps] are supported + for MeshStandardMaterial. If you want to use an equirectangular map you will need to use + [page:WebGLCubeRenderTarget.fromEquirectangularTexture WebGLCubeRenderTarget.fromEquirectangularTexture](). See this [link:https://threejs.org/examples/webgl_materials_envmaps_exr.html example] for details.

[property:Float envMapIntensity]

Scales the effect of the environment map by multiplying its color.

-

[property:Boolean isMeshStandardMaterial]

-

- Used to check whether this or derived classes are mesh standard materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

-

[property:Texture lightMap]

-

The light map. Default is null. The lightMap requires a second set of UVs, - and consequently will ignore the [page:Texture repeat] and [page:Texture offset] - Texture properties.

+

The light map. Default is null. The lightMap requires a second set of UVs.

[property:Float lightMapIntensity]

Intensity of the baked light. Default is 1.

@@ -204,7 +194,7 @@

[property:Texture map]

[property:Float metalness]

How much the material is like a metal. Non-metallic materials such as wood or stone use 0.0, metallic use 1.0, with nothing - (usually) in between. Default is 0.5. A value between 0.0 and 1.0 could be used for a rusty metal look. If metalnessMap is + (usually) in between. Default is 0.0. A value between 0.0 and 1.0 could be used for a rusty metal look. If metalnessMap is also provided, both values are multiplied.

@@ -224,6 +214,8 @@

[property:Texture normalMap]

The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting. + In case the material has a normal map authored using the left handed convention, the y component of normalScale + should be negated to compensate for the different handedness.

[property:Integer normalMapType]

@@ -248,7 +240,7 @@

[property:Float refractionRatio]

[property:Float roughness]

- How rough the material appears. 0.0 means a smooth mirror reflection, 1.0 means fully diffuse. Default is 0.5. + How rough the material appears. 0.0 means a smooth mirror reflection, 1.0 means fully diffuse. Default is 1.0. If roughnessMap is also provided, both values are multiplied.

@@ -258,6 +250,13 @@

[property:Texture roughnessMap]

[property:Boolean skinning]

Define whether the material uses skinning. Default is false.

+

[property:Boolean vertexTangents]

+

+ Defines whether precomputed vertex tangents, which must be provided in a vec4 "tangent" attribute, + are used. When disabled, tangents are derived automatically. Using precomputed tangents will give + more accurate normal map details in some cases, such as with mirrored UVs. Default is false. +

+

[property:Boolean wireframe]

Render geometry as wireframe. Default is *false* (i.e. render as flat polygons).

@@ -291,6 +290,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/MeshToonMaterial.html b/docs/api/en/materials/MeshToonMaterial.html index 03909274255616..0b3826ea26bb89 100644 --- a/docs/api/en/materials/MeshToonMaterial.html +++ b/docs/api/en/materials/MeshToonMaterial.html @@ -8,11 +8,11 @@ - [page:Material] → [page:MeshPhongMaterial] → + [page:Material] →

[name]

-
An extension of the [page:MeshPhongMaterial] with toon shading.
+
A material implementing toon shading.
@@ -33,49 +33,191 @@

[name]

Examples

- [example:webgl_materials_variations_toon materials / variations / toon]
+

+ [example:webgl_materials_variations_toon materials / variations / toon] +

Constructor

[name]( [param:Object parameters] )

- [page:Object parameters] - (optional) an object with one or more properties defining the material's appearance. - Any property of the material (including any property inherited from [page:Material] and [page:MeshStandardMaterial]) can be passed in here.

+ [page:Object parameters] - (optional) an object with one or more properties defining the material's appearance. + Any property of the material (including any property inherited from [page:Material]) can be passed in here.

- The exception is the property [page:Hexadecimal color], which can be passed in as a hexadecimal - string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally. + The exception is the property [page:Hexadecimal color], which can be passed in as a hexadecimal + string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally.

-

Properties

-

See the base [page:Material] and [page:MeshPhongMaterial] classes for common properties.

+

See the base [page:Material] class for common properties.

+ +

[property:Texture alphaMap]

+

The alpha map is a grayscale texture that controls the opacity across the surface + (black: fully transparent; white: fully opaque). Default is null.

+ + Only the color of the texture is used, ignoring the alpha channel if one exists. + For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the + green channel when sampling this texture due to the extra bit of precision provided + for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and + luminance/alpha textures will also still work as expected. +

+ +

[property:Texture aoMap]

+

The red channel of this texture is used as the ambient occlusion map. Default is null. + The aoMap requires a second set of UVs.

+ +

[property:Float aoMapIntensity]

+

Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.

+ +

[property:Texture bumpMap]

+

+ The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights. + Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will + be ignored. +

+ +

[property:Float bumpScale]

+

How much the bump map affects the material. Typical ranges are 0-1. Default is 1.

+ + +

[property:Color color]

+

[page:Color] of the material, by default set to white (0xffffff).

+ +

[property:Texture displacementMap]

+

+ The displacement map affects the position of the mesh's vertices. Unlike other maps + which only affect the light and shade of the material the displaced vertices can cast shadows, + block other objects, and otherwise act as real geometry. The displacement texture is + an image where the value of each pixel (white being the highest) is mapped against, + and repositions, the vertices of the mesh. +

+ +

[property:Float displacementScale]

+

+ How much the displacement map affects the mesh (where black is no displacement, + and white is maximum displacement). Without a displacement map set, this value is not applied. + Default is 1. +

+ +

[property:Float displacementBias]

+

+ The offset of the displacement map's values on the mesh's vertices. + Without a displacement map set, this value is not applied. Default is 0. +

+ +

[property:Color emissive]

+

+ Emissive (light) color of the material, essentially a solid color unaffected by other lighting. + Default is black. +

+ +

[property:Texture emissiveMap]

+

+ Set emisssive (glow) map. Default is null. The emissive map color is modulated by + the emissive color and the emissive intensity. If you have an emissive map, be sure to + set the emissive color to something other than black. +

+ +

[property:Float emissiveIntensity]

+

Intensity of the emissive light. Modulates the emissive color. Default is 1.

[property:Texture gradientMap]

-

Gradient map for the toon shading. Default is *null*.

+

Gradient map for toon shading. It's required to set [page:Texture.minFilter] and [page:Texture.magFilter] to + [page:Textures THREE.NearestFilter] when using this type of texture. Default is *null*.

+ +

[property:Texture lightMap]

+

The light map. Default is null. The lightMap requires a second set of UVs.

+ +

[property:Float lightMapIntensity]

+

Intensity of the baked light. Default is 1.

-

[property:Boolean isMeshToonMaterial]

+

[property:Texture map]

+

The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].

+ +

[property:boolean morphNormals]

- Used to check whether this or derived classes are mesh toon materials. Default is *true*.

+ Defines whether the material uses morphNormals. Set as true to pass morphNormal + attributes from the [page:Geometry] to the shader. Default is *false*. +

- You should not change this, as it used internally for optimisation. +

[property:Boolean morphTargets]

+

Define whether the material uses morphTargets. Default is false.

+ +

[property:Texture normalMap]

+

+ The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change + the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting. + In case the material has a normal map authored using the left handed convention, the y component of normalScale + should be negated to compensate for the different handedness.

-

[property:Object defines]

-

An object of the form: - - { 'TOON': '' }; - +

[property:Integer normalMapType]

+

+ The type of normal map.

- This is used by the [page:WebGLRenderer] for selecting shaders. + Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap].

+

[property:Vector2 normalScale]

+

+ How much the normal map affects the material. Typical ranges are 0-1. + Default is a [page:Vector2] set to (1,1). +

-

Methods

-

See the base [page:Material] and [page:MeshPhongMaterial] classes for common methods.

+

[property:Float shininess]

+

How shiny the [page:.specular] highlight is; a higher value gives a sharper highlight. Default is *30*.

+ + +

[property:Boolean skinning]

+

Define whether the material uses skinning. Default is false.

+ +

[property:Color specular]

+

+ Specular color of the material. Default is a [page:Color] set to *0x111111* (very dark grey).

+ + This defines how shiny the material is and the color of its shine. +

+ +

[property:Texture specularMap]

+

+ The specular map value affects both how much the specular surface highlight + contributes and how much of the environment map affects the surface. Default is null. +

+ +

[property:Boolean wireframe]

+

Render geometry as wireframe. Default is *false* (i.e. render as flat polygons).

+ +

[property:String wireframeLinecap]

+

+ Define appearance of line ends. Possible values are "butt", "round" and "square". Default is 'round'.

+ + This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + property and it is ignored by the [page:WebGLRenderer WebGL] renderer. +

+ +

[property:String wireframeLinejoin]

+

+ Define appearance of line joints. Possible values are "round", "bevel" and "miter". Default is 'round'.

+ This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin] + property and it is ignored by the [page:WebGLRenderer WebGL] renderer. +

+ +

[property:Float wireframeLinewidth]

+

Controls wireframe thickness. Default is 1.

+ + Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile] + with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will + always be 1 regardless of the set value. +

+ +

Methods

+

See the base [page:Material] class for common methods.

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/PointsMaterial.html b/docs/api/en/materials/PointsMaterial.html index a52eeb9abe3b00..583cd78acc3de1 100644 --- a/docs/api/en/materials/PointsMaterial.html +++ b/docs/api/en/materials/PointsMaterial.html @@ -14,6 +14,30 @@

[name]

The default material used by [page:Points].

+

Code Example

+ + var vertices = []; + + for ( var i = 0; i < 10000; i ++ ) { + + var x = THREE.MathUtils.randFloatSpread( 2000 ); + var y = THREE.MathUtils.randFloatSpread( 2000 ); + var z = THREE.MathUtils.randFloatSpread( 2000 ); + + vertices.push( x, y, z ); + + } + + var geometry = new THREE.BufferGeometry(); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + + var material = new THREE.PointsMaterial( { color: 0x888888 } ); + + var points = new THREE.Points( geometry, material ); + + scene.add( points ); + +

Examples

[example:misc_controls_fly misc / controls / fly]
@@ -31,29 +55,7 @@

Examples

[example:webgl_trails WebGL / trails]

- -//This will add a starfield to the background of a scene -var starsGeometry = new THREE.Geometry(); - -for ( var i = 0; i < 10000; i ++ ) { - - var star = new THREE.Vector3(); - star.x = THREE.Math.randFloatSpread( 2000 ); - star.y = THREE.Math.randFloatSpread( 2000 ); - star.z = THREE.Math.randFloatSpread( 2000 ); - - starsGeometry.vertices.push( star ); - -} - -var starsMaterial = new THREE.PointsMaterial( { color: 0x888888 } ); - -var starField = new THREE.Points( starsGeometry, starsMaterial ); - -scene.add( starField ); - - -

[name]( [param:Object parameters] )

+

[name]( [param:Object parameters] )

[page:Object parameters] - (optional) an object with one or more properties defining the material's appearance. Any property of the material (including any property inherited from [page:Material]) can be passed in here.

@@ -65,16 +67,20 @@

[name]( [param:Object parameters] )

Properties

See the base [page:Material] class for common properties.

-

[property:Color color]

-

[page:Color] of the material, by default set to white (0xffffff).

+

[property:Texture alphaMap]

+

The alpha map is a grayscale texture that controls the opacity across the surface + (black: fully transparent; white: fully opaque). Default is null.

-

[property:Boolean isPointsMaterial]

-

- Used to check whether this or derived classes are points materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. + Only the color of the texture is used, ignoring the alpha channel if one exists. + For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the + green channel when sampling this texture due to the extra bit of precision provided + for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and + luminance/alpha textures will also still work as expected.

+

[property:Color color]

+

[page:Color] of the material, by default set to white (0xffffff).

+

[property:Texture map]

Sets the color of the points using data from a [page:Texture].

@@ -83,7 +89,8 @@

[property:Boolean morphTargets]

Define whether the material uses morphTargets. Default is false.

[property:Number size]

-

Sets the size of the points. Default is 1.0.

+

Sets the size of the points. Default is 1.0.
+ Will be capped if it exceeds the hardware dependent parameter [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getParameter gl.ALIASED_POINT_SIZE_RANGE].

[property:Boolean sizeAttenuation]

Specify whether points' size is attenuated by the camera depth. (Perspective camera only.) Default is true.

@@ -93,6 +100,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/RawShaderMaterial.html b/docs/api/en/materials/RawShaderMaterial.html index 58751f4e52323b..2216d2ba5e93aa 100644 --- a/docs/api/en/materials/RawShaderMaterial.html +++ b/docs/api/en/materials/RawShaderMaterial.html @@ -17,6 +17,19 @@

[name]

built-in uniforms and attributes are not automatically prepended to the GLSL shader code.

+

Code Example

+ + var material = new THREE.RawShaderMaterial( { + + uniforms: { + time: { value: 1.0 } + }, + vertexShader: document.getElementById( 'vertexShader' ).textContent, + fragmentShader: document.getElementById( 'fragmentShader' ).textContent, + + } ); + +

Examples

[example:webgl_buffergeometry_rawshader WebGL / buffergeometry / rawshader]
@@ -28,18 +41,6 @@

Examples

[example:webgl_raymarching_reflect WebGL / raymarching / reflect]

- -var material = new THREE.RawShaderMaterial( { - - uniforms: { - time: { value: 1.0 } - }, - vertexShader: document.getElementById( 'vertexShader' ).textContent, - fragmentShader: document.getElementById( 'fragmentShader' ).textContent, - -} ); - -

Constructor

[name]( [param:Object parameters] )

@@ -50,14 +51,7 @@

[name]( [param:Object parameters] )

Properties

-

See the base [page:Material] and [page:ShaderMaterial] classes for common methods.

- -

[property:Boolean isRawShaderMaterial]

-

- Used to check whether this or derived classes are raw shader materials. Default is *true*.

- - You should not change this, as it used internally for optimisation. -

+

See the base [page:Material] and [page:ShaderMaterial] classes for common properties.

Methods

@@ -66,6 +60,8 @@

Methods

Source

- [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

+ [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

diff --git a/docs/api/en/materials/ShaderMaterial.html b/docs/api/en/materials/ShaderMaterial.html index 2a1837a76985d8..d96669ea8419e9 100644 --- a/docs/api/en/materials/ShaderMaterial.html +++ b/docs/api/en/materials/ShaderMaterial.html @@ -35,7 +35,7 @@

[name]

using [page:BufferAttribute] instances to define custom attributes.
  • - As of THREE r77, [page:WebGLRenderTarget] or [page:WebGLRenderTargetCube] instances + As of THREE r77, [page:WebGLRenderTarget] or [page:WebGLCubeRenderTarget] instances are no longer supposed to be used as uniforms. Their [page:Texture texture] property must be used instead.
  • @@ -45,7 +45,7 @@

    [name]

    [page:RawShaderMaterial] instead of this class.
  • - You can use the directive #pragma unroll_loop in order to unroll a *for* loop in GLSL by the shader preprocessor. + You can use the directive #pragma unroll_loop_start and #pragma unroll_loop_end in order to unroll a *for* loop in GLSL by the shader preprocessor. The directive has to be placed right above the loop. The loop formatting has to correspond to a defined standard.
    • @@ -59,17 +59,37 @@

      [name]

    - #pragma unroll_loop + #pragma unroll_loop_start for ( int i = 0; i < 10; i ++ ) { // ... } + #pragma unroll_loop_end
  • +

    Code Example

    + + + var material = new THREE.ShaderMaterial( { + + uniforms: { + + time: { value: 1.0 }, + resolution: { value: new THREE.Vector2() } + + }, + + vertexShader: document.getElementById( 'vertexShader' ).textContent, + + fragmentShader: document.getElementById( 'fragmentShader' ).textContent + + } ); + +

    Examples

    @@ -101,26 +121,8 @@

    Examples

    [example:webgl_nearestneighbour webgl / nearestneighbour]
    [example:webgl_postprocessing_dof2 webgl / postprocessing / dof2]
    [example:webgl_postprocessing_godrays webgl / postprocessing / godrays] -

    - - var material = new THREE.ShaderMaterial( { - - uniforms: { - - time: { value: 1.0 }, - resolution: { value: new THREE.Vector2() } - - }, - - vertexShader: document.getElementById( 'vertexShader' ).textContent, - - fragmentShader: document.getElementById( 'fragmentShader' ).textContent - - } ); - -

    Vertex shaders and fragment shaders

    @@ -352,16 +354,6 @@

    [property:String index0AttributeName]

    -

    [property:Boolean isShaderMaterial]

    -

    - Used to check whether this or derived classes are shader materials. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    - - - -

    [property:Boolean lights]

    Defines whether this material uses lighting; true to pass uniform data related to lighting to this shader. Default is false. @@ -419,12 +411,14 @@

    [property:Object uniforms]

    so updating the value of the uniform will immediately update the value available to the GLSL code.

    +

    [property:Boolean uniformsNeedUpdate]

    +

    + Can be used to force a uniform update while changing uniforms in [page:Object3D.onBeforeRender](). Default is *false*. +

    -

    [property:Number vertexColors]

    +

    [property:Boolean vertexColors]

    - Define how the vertices are colored, by defining how the *colors* attribute gets populated. - Possible values are [page:Materials THREE.NoColors], [page:Materials THREE.FaceColors] and - [page:Materials THREE.VertexColors]. Default is THREE.NoColors. + Defines whether vertex coloring is used. Default is *false*.

    [property:String vertexShader]

    @@ -463,6 +457,8 @@

    [method:ShaderMaterial clone]() [param:ShaderMaterial this]

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/materials/ShadowMaterial.html b/docs/api/en/materials/ShadowMaterial.html index efe8e2b9b45c15..562a2340b4fa7c 100644 --- a/docs/api/en/materials/ShadowMaterial.html +++ b/docs/api/en/materials/ShadowMaterial.html @@ -8,7 +8,7 @@ - [page:Material] → [page:ShaderMaterial] → + [page:Material] →

    [name]

    @@ -16,52 +16,49 @@

    [name]

    This material can receive shadows, but otherwise is completely transparent.

    -

    Example

    - [example:webgl_geometry_spline_editor geometry / spline / editor] +

    Code Example

    -var planeGeometry = new THREE.PlaneGeometry( 2000, 2000 ); -planeGeometry.rotateX( - Math.PI / 2 ); + var planeGeometry = new THREE.PlaneBufferGeometry( 2000, 2000 ); + planeGeometry.rotateX( - Math.PI / 2 ); -var planeMaterial = new THREE.ShadowMaterial(); -planeMaterial.opacity = 0.2; + var planeMaterial = new THREE.ShadowMaterial(); + planeMaterial.opacity = 0.2; -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.position.y = -200; -plane.receiveShadow = true; -scene.add( plane ); + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.position.y = -200; + plane.receiveShadow = true; + scene.add( plane ); +

    Examples

    + +

    + [example:webgl_geometry_spline_editor geometry / spline / editor] +

    +

    Constructor

    [name]( [param:Object parameters] )

    [page:Object parameters] - (optional) an object with one or more properties defining the material's appearance. - Any property of the material (including any property inherited from [page:Material] and [page:ShaderMaterial]) can be passed in here.

    + Any property of the material (including any property inherited from [page:Material]) can be passed in here.

    Properties

    -

    See the base [page:Material] and [page:ShaderMaterial] classes for common properties.

    - -

    [property:Boolean isShadowMaterial]

    -

    - Used to check whether this or derived classes are shadow materials. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    - -

    [property:Boolean lights]

    -

    Whether the material is affected by lights. Default is *true*.

    +

    See the base [page:Material] classes for common properties.

    [property:Boolean transparent]

    Defines whether this material is transparent. Default is *true*.

    Methods

    -

    See the base [page:Material] and [page:ShaderMaterial] classes for common methods.

    +

    See the base [page:Material] classes for common methods.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/materials/SpriteMaterial.html b/docs/api/en/materials/SpriteMaterial.html index 301570dceeb504..61fe2cdccf7099 100644 --- a/docs/api/en/materials/SpriteMaterial.html +++ b/docs/api/en/materials/SpriteMaterial.html @@ -14,26 +14,28 @@

    [name]

    A material for a use with a [page:Sprite].

    -

    Examples

    -
    - [example:webgl_sprites WebGL / sprites]
    - [example:software_sandbox software / sandbox]
    - [example:svg_sandbox svg / sandbox]
    - [example:webgl_materials_cubemap_dynamic webgl / materials / cubemap / dynamic] -
    +

    Code Example

    -var spriteMap = new THREE.TextureLoader().load( 'textures/sprite.png' ); + var spriteMap = new THREE.TextureLoader().load( 'textures/sprite.png' ); -var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } ); + var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } ); -var sprite = new THREE.Sprite( spriteMaterial ); -sprite.scale.set(200, 200, 1) - -scene.add( sprite ); + var sprite = new THREE.Sprite( spriteMaterial ); + sprite.scale.set(200, 200, 1) + scene.add( sprite ); +

    Examples

    +

    + [example:webgl_sprites WebGL / sprites]
    + [example:software_sandbox software / sandbox]
    + [example:svg_sandbox svg / sandbox]
    + [example:webgl_materials_cubemap_dynamic webgl / materials / cubemap / dynamic] +

    + +

    Constructor

    [name]( [param:Object parameters] )

    @@ -50,15 +52,23 @@

    [name]( [param:Object parameters] )

    Properties

    See the base [page:Material] class for common properties.

    +

    [property:Texture alphaMap]

    +

    The alpha map is a grayscale texture that controls the opacity across the surface + (black: fully transparent; white: fully opaque). Default is null.

    + + Only the color of the texture is used, ignoring the alpha channel if one exists. + For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the + green channel when sampling this texture due to the extra bit of precision provided + for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and + luminance/alpha textures will also still work as expected. +

    +

    [property:Color color]

    [page:Color] of the material, by default set to white (0xffffff). The [page:.map] is mutiplied by the color.

    [property:boolean fog]

    Whether or not this material affected by the scene's fog. Default is false

    -

    [property:Boolean lights]

    -

    Whether the material is affected by lights. Default is *false*.

    -

    [property:Texture map]

    The texture map. Default is null.

    @@ -73,6 +83,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Box2.html b/docs/api/en/math/Box2.html index da4f7bbd03fe43..8c3101b5c62f20 100644 --- a/docs/api/en/math/Box2.html +++ b/docs/api/en/math/Box2.html @@ -11,7 +11,7 @@

    [name]

    - Represents a box in 2D space. + Represents an axis-aligned bounding box (AABB) in 2D space.

    @@ -174,7 +174,8 @@

    [method:Box2 set]( [param:Vector2 min], [param:Vector2 max] )

    [page:Vector2 min] - (required ) [page:Vector2] representing the lower (x, y) boundary of the box.
    [page:Vector2 max] - (required) [page:Vector2] representing the upper (x, y) boundary of the box.

    - Sets the lower and upper (x, y) boundaries of this box. + Sets the lower and upper (x, y) boundaries of this box.
    + Please note that this method only copies the values from the given objects.

    [method:Box2 setFromCenterAndSize]( [param:Vector2 center], [param:Vector2 size] )

    @@ -214,6 +215,8 @@

    [method:Box2 union]( [param:Box2 box] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Box3.html b/docs/api/en/math/Box3.html index 2751385bc1613e..bd35df8ca2b5bc 100644 --- a/docs/api/en/math/Box3.html +++ b/docs/api/en/math/Box3.html @@ -11,32 +11,29 @@

    [name]

    - Represents a box or cube in 3D space. The main purpose of this is to represent - the world-axis-aligned bounding boxes for objects. + Represents an axis-aligned bounding box (AABB) in 3D space.

    - -

    Example

    +

    Code Example

    - // Creating the object whose bounding box we want to compute - var sphereObject = new THREE.Mesh( - new THREE.SphereGeometry(), - new THREE.MeshBasicMaterial( 0xff0000 ) + var box = new THREE.Box3(); + + var mesh = new THREE.Mesh( + new THREE.SphereBufferGeometry(), + new THREE.MeshBasicMaterial() ); - // Creating the actual bounding box with Box3 - sphereObject.geometry.computeBoundingBox(); - var box = sphereObject.geometry.boundingBox.clone(); + + // ensure the bounding box is computed for its geometry + // this should be done only once (assuming static geometries) + mesh.geometry.computeBoundingBox(); // ... - - // In the animation loop, to keep the bounding box updated after move/rotate/scale operations - sphereObject.updateMatrixWorld( true ); - box.copy( sphereObject.geometry.boundingBox ).applyMatrix4( sphereObject.matrixWorld ); - + // in the animation loop, compute the current bounding box with the world matrix + box.copy( mesh.geometry.boundingBox ).applyMatrix4( mesh.matrixWorld ); +
    -

    Constructor

    @@ -53,13 +50,6 @@

    [name]( [param:Vector3 min], [param:Vector3 max] )

    Properties

    -

    [property:Boolean isBox3]

    -

    - Used to check whether this or derived classes are Box3s. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:Vector3 min]

    [page:Vector3] representing the lower (x, y, z) boundary of the box.
    @@ -138,6 +128,7 @@

    [method:Box3 expandByObject]( [param:Object3D object] )

    Expands the boundaries of this box to include [page:Object3D object] and its children, accounting for the object's, and children's, world transforms. + The function may result in a larger box than strictly necessary.

    @@ -247,7 +238,8 @@

    [method:Box3 set]( [param:Vector3 min], [param:Vector3 max] )

    [page:Vector3 min] - [page:Vector3] representing the lower (x, y, z) boundary of the box.
    [page:Vector3 max] - [page:Vector3] representing the lower upper (x, y, z) boundary of the box.

    - Sets the lower and upper (x, y, z) boundaries of this box. + Sets the lower and upper (x, y, z) boundaries of this box.
    + Please note that this method only copies the values from the given objects.

    [method:Box3 setFromArray]( [param:Array array] ) [param:Box3 this]

    @@ -279,6 +271,7 @@

    [method:Box3 setFromObject]( [param:Object3D object] )

    Computes the world-axis-aligned bounding box of an [page:Object3D] (including its children), accounting for the object's, and children's, world transforms. + The function may result in a larger box than strictly necessary.

    @@ -308,6 +301,8 @@

    [method:Box3 union]( [param:Box3 box] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Color.html b/docs/api/en/math/Color.html index 02c57a28151fd4..baebef469a3e51 100644 --- a/docs/api/en/math/Color.html +++ b/docs/api/en/math/Color.html @@ -14,9 +14,11 @@

    [name]

    Class representing a color.

    +

    Code Examples

    -

    Examples

    - A Color can be initialised in any of the following ways: +

    + A Color can be initialised in any of the following ways: +

    //empty constructor - will default white var color = new THREE.Color(); @@ -39,8 +41,6 @@

    Examples

    var color = new THREE.Color( 1, 0, 0 );
    - -

    Constructor

    @@ -75,13 +75,6 @@

    [name]( [param:Color_Hex_or_String r], [param:Float g], [param:Float b] )Properties

    -

    [property:Boolean isColor]

    -

    - Used to check whether this or derived classes are Colors. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:Float r]

    Red channel value between 0 and 1. Default is 1. @@ -126,7 +119,7 @@

    [method:Color convertGammaToLinear]( [param:Float gammaFactor] )

    [page:Float gammaFactor] - (optional). Default is *2.0*.

    Converts this color from gamma space to linear space by taking [page:.r r], [page:.g g] and [page:.b b] to the power of [page:Float gammaFactor].

    - +

    [method:Color convertLinearToGamma]( [param:Float gammaFactor] )

    [page:Float gammaFactor] - (optional). Default is *2.0*.

    @@ -302,6 +295,15 @@

    [method:Color setStyle]( [param:String style] )

    Note that for X11 color names, multiple words such as Dark Orange become the string 'darkorange' (all lowercase).

    +

    [method:Color setColorName]( [param:String style] )

    +

    + [page:String style] — color name ( from [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart X11 color names] ).

    + + Sets this color from a color name. Faster than [page:.setStyle] method if you don't need the other CSS-style formats.

    + + For convenience, the list of names is exposed in Color.NAMES as a hash: Color.NAMES.aliceblue // returns 0xF0F8FF +

    +

    [method:Color sub]( [param:Color color] )

    Subtracts the RGB components of the given color from the RGB components of this color. @@ -318,6 +320,8 @@

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Cylindrical.html b/docs/api/en/math/Cylindrical.html index cc2d76d76c4083..8f8407877d31b4 100644 --- a/docs/api/en/math/Cylindrical.html +++ b/docs/api/en/math/Cylindrical.html @@ -68,6 +68,8 @@

    [method:Cylindrical setFromCartesianCoords]( [param:Float x], [param:Float y

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Euler.html b/docs/api/en/math/Euler.html index 6043a50da47016..16b22c85059190 100644 --- a/docs/api/en/math/Euler.html +++ b/docs/api/en/math/Euler.html @@ -17,7 +17,7 @@

    [name]

    axes in specified amounts per axis, and a specified axis order.

    -

    Example

    +

    Code Example

    var a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); var b = new THREE.Vector3( 1, 0, 1 ); @@ -41,13 +41,6 @@

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:String ord

    Properties

    -

    [property:Boolean isEuler]

    -

    - Used to check whether this or derived classes are Eulers. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:String order]

    The order in which to apply rotations. Default is 'XYZ', which means that the object will first be @@ -162,6 +155,8 @@

    [method:Vector3 toVector3]( [param:Vector3 optionalResult] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Frustum.html b/docs/api/en/math/Frustum.html index 755c80883a12d0..fd2392afb6fcbb 100644 --- a/docs/api/en/math/Frustum.html +++ b/docs/api/en/math/Frustum.html @@ -89,33 +89,23 @@

    [method:Boolean intersectsSprite]( [param:Sprite sprite] )

    Checks whether the [page:Sprite sprite] is intersecting the Frustum.

    -

    [method:Frustum set]( [param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5] )

    +

    [method:this set]( [param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5] )

    - Sets the current frustum from the passed planes. No plane order is implicitely implied. + Sets the frustum from the passed planes. No plane order is implied.
    + Note that this method only copies the values from the given objects.

    -

    [method:Frustum setFromMatrix]( [param:Matrix4 matrix] )

    +

    [method:this setFromProjectionMatrix]( [param:Matrix4 matrix] )

    - [page:Matrix4 matrix] - [page:Matrix4] used to set the [page:.planes planes]

    - - This is used by the [page:WebGLRenderer] to set up the Frustum from a [page:Camera Camera]'s - [page:Camera.projectionMatrix projectionMatrix] and [page:Camera.matrixWorldInverse matrixWorldInverse]. + [page:Matrix4 matrix] - Projection [page:Matrix4] used to set the [page:.planes planes]

    + Sets the frustum planes from the projection matrix.

    - - - - - - - - - - -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Interpolant.html b/docs/api/en/math/Interpolant.html index 37379631407a3d..07e0a134fdf105 100644 --- a/docs/api/en/math/Interpolant.html +++ b/docs/api/en/math/Interpolant.html @@ -79,6 +79,8 @@

    [method:null evaluate]( [param:Number t] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Line3.html b/docs/api/en/math/Line3.html index b83b61f1e39e77..59cde37e8ffc36 100644 --- a/docs/api/en/math/Line3.html +++ b/docs/api/en/math/Line3.html @@ -118,6 +118,8 @@

    [method:Line3 set]( [param:Vector3 start], [param:Vector3 end] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Math.html b/docs/api/en/math/MathUtils.html similarity index 79% rename from docs/api/en/math/Math.html rename to docs/api/en/math/MathUtils.html index c87edd728f5323..d881b4f6497bab 100644 --- a/docs/api/en/math/Math.html +++ b/docs/api/en/math/MathUtils.html @@ -105,8 +105,23 @@

    [method:Float smootherstep]( [param:Float x], [param:Float min], [param:Floa that has zero 1st and 2nd order derivatives at x=0 and x=1.

    +

    [method:null setQuaternionFromProperEuler]( [param:Quaternion q], [param:Float a], [param:Float b], [param:Float c], [param:String order] )

    +

    + [page:Quaternion q] - the quaternion to be set
    + [page:Float a] - the rotation applied to the first axis, in radians
    + [page:Float b] - the rotation applied to the second axis, in radians
    + [page:Float c] - the rotation applied to the third axis, in radians
    + [page:String order] - a string specifying the axes order: 'XYX', 'XZX', 'YXY', 'YZY', 'ZXZ', or 'ZYZ'

    + + Sets quaternion [page:Quaternion q] from the [link:http://en.wikipedia.org/wiki/Euler_angles intrinsic Proper Euler Angles] defined by angles [page:Float a], [page:Float b], and [page:Float c], and order [page:String order].
    + + Rotations are applied to the axes in the order specified by [page:String order]: rotation by angle [page:Float a] is applied first, then by angle [page:Float b], then by angle [page:Float c]. Angles are in radians. +

    +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Matrix3.html b/docs/api/en/math/Matrix3.html index 22dcca3fa4f8c9..2cb56a4a4be5b8 100644 --- a/docs/api/en/math/Matrix3.html +++ b/docs/api/en/math/Matrix3.html @@ -14,7 +14,7 @@

    [name]

    A class representing a 3x3 [link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix].

    -

    Example

    +

    Code Example

    var m = new Matrix3(); @@ -61,25 +61,10 @@

    [property:Array elements]

    list of matrix values.

    -

    [property:Boolean isMatrix3]

    -

    - Used to check whether this or derived classes are Matrix3s. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    Methods

    -

    [method:Array applyToBufferAttribute]( [param:BufferAttribute attribute] )

    -

    - [page:BufferAttribute attribute] - An attribute of floats that represent 3D vectors.

    - - Multiplies (applies) this matrix to every 3D vector in the [page:BufferAttribute attribute]. -

    - -

    [method:Matrix3 clone]()

    Creates a new Matrix3 and with identical elements to this one.

    @@ -95,6 +80,23 @@

    [method:Float determinant]()

    [method:Boolean equals]( [param:Matrix3 m] )

    Return true if this matrix and [page:Matrix3 m] are equal.

    +

    [method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    +

    + Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] of this + matrix into the three axis vectors provided. If this matrix is: + +a, b, c, +d, e, f, +g, h, i + + then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] will be set to: + +xAxis = (a, d, g) +yAxis = (b, e, h) +zAxis = (c, f, i) + +

    +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    [page:Array array] - the array to read the elements from.
    @@ -199,6 +201,8 @@

    [method:this transposeIntoArray]( [param:Array array] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Matrix4.html b/docs/api/en/math/Matrix4.html index f37b05e1f1bbf1..06c17ae2d31a2e 100644 --- a/docs/api/en/math/Matrix4.html +++ b/docs/api/en/math/Matrix4.html @@ -77,6 +77,24 @@

    A Note on Row-Major and Column-Major Ordering

    code, you'll have to take the [link:https://en.wikipedia.org/wiki/Transpose transpose] of any matrices outlined here to make sense of the calculations.

    +

    Extracting position, rotation and scale

    +

    + There are several options available for extracting position, rotation and scale from a Matrix4. +

      +
    • + [page:Vector3.setFromMatrixPosition]: can be used to extract the translation component. +
    • +
    • + [page:Vector3.setFromMatrixScale]: can be used to extract the scale component. +
    • +
    • + [page:Quaternion.setFromRotationMatrix], [page:Euler.setFromRotationMatrix] or [page:.extractRotation extractRotation] can be used to extract the rotation component. +
    • +
    • + [page:.decompose decompose] can be used to extract position, rotation and scale all at once. +
    • +
    +

    Constructor

    @@ -96,26 +114,11 @@

    [property:Array elements]

    list of matrix values.

    -

    [property:Boolean isMatrix4]

    -

    - Used to check whether this or derived classes are Matrix4s. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    Methods

    -

    [method:Array applyToBufferAttribute]( [param:BufferAttribute attribute] )

    -

    - [page:BufferAttribute attribute] - An attribute of floats that represent 3D vectors.

    - - Multiplies (applies) this matrix to every 3D vector in the [page:BufferAttribute attribute]. -

    - -

    [method:Matrix4 clone]()

    Creates a new Matrix4 with identical [page:.elements elements] to this one.

    @@ -219,7 +222,7 @@

    [method:this makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )< Sets this matrix as rotation transform around [page:Vector3 axis] by [page:Float theta] radians.
    This is a somewhat controversial but mathematically sound alternative to rotating via [page:Quaternions]. - See the discussion [link:http://www.gamedev.net/reference/articles/article1199.asp here]. + See the discussion [link:https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199 here].

    [method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    @@ -408,6 +411,8 @@

    [method:this transpose]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Plane.html b/docs/api/en/math/Plane.html index c7a1f63e593d0b..8da4ef0566af91 100644 --- a/docs/api/en/math/Plane.html +++ b/docs/api/en/math/Plane.html @@ -130,7 +130,7 @@

    [method:Plane set]( [param:Vector3 normal], [param:Float constant] )

    [page:Vector3 normal] - a unit length [page:Vector3] defining the normal of the plane.
    [page:Float constant] - the signed distance from the origin to the plane. Default is *0*.

    - Sets the plane's [page:.normal normal] and [page:.constant constant] properties. + Sets this plane's [page:.normal normal] and [page:.constant constant] properties by copying the values from the given normal.

    [method:Plane setComponents]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    @@ -171,6 +171,8 @@

    [method:Plane translate]( [param:Vector3 offset] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Quaternion.html b/docs/api/en/math/Quaternion.html index 00d541bbbec4c0..80b6aefc3207a9 100644 --- a/docs/api/en/math/Quaternion.html +++ b/docs/api/en/math/Quaternion.html @@ -11,15 +11,11 @@

    [name]

    - Implementation of a [link:http://en.wikipedia.org/wiki/Quaternion quaternion]. - This is used for [link:https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation rotating things] - without encountering the dreaded - [link:http://en.wikipedia.org/wiki/Gimbal_lock gimbal lock] issue, amongst other - advantages. + Implementation of a [link:http://en.wikipedia.org/wiki/Quaternion quaternion].
    + Quaternions are used in three.js to represent [link:https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation rotations].

    - -

    Example

    +

    Code Example

    var quaternion = new THREE.Quaternion(); @@ -44,13 +40,6 @@

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    Properties

    -

    [property:Boolean isQuaternion]

    -

    - Used to check whether this or derived classes are Quaternions. Default is *true*.

    - - You should not change this, as it is used internally for optimisation. -

    -

    [property:Float x]

    [property:Float y]

    @@ -264,6 +253,8 @@

    [method:null slerpFlat]( [param:Array dst], [param:Integer dstOffset], [para

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Ray.html b/docs/api/en/math/Ray.html index 49911afff4f5e8..b2e72a342637c2 100644 --- a/docs/api/en/math/Ray.html +++ b/docs/api/en/math/Ray.html @@ -25,7 +25,7 @@

    [name]( [param:Vector3 origin], [param:Vector3 direction] )

    [page:Vector3 origin] - (optional) the origin of the [page:Ray]. Default is a [page:Vector3] at (0, 0, 0).
    [page:Vector3 direction] - [page:Vector3] The direction of the [page:Ray]. This must be normalized - (with [page:Vector3.normalize]) for the methods to operate properly. Default is a [page:Vector3] at (0, 0, 0).

    + (with [page:Vector3.normalize]) for the methods to operate properly. Default is a [page:Vector3] at (0, 0, -1).

    Creates a new [name].

    @@ -38,7 +38,7 @@

    [property:Vector3 origin]

    [property:Vector3 direction]

    The direction of the [page:Ray]. This must be normalized (with [page:Vector3.normalize]) - for the methods to operate properly. Default is a [page:Vector3] at (0, 0, 0). + for the methods to operate properly. Default is a [page:Vector3] at (0, 0, -1).

    @@ -201,14 +201,15 @@

    [method:Ray set]( [param:Vector3 origin], [param:Vector3 direction] )

    This must be normalized (with [page:Vector3.normalize]) for the methods to operate properly.

    - Copy the parameters to the [page:.origin origin] and [page:.direction direction] properties - of this ray. + Sets this ray's [page:.origin origin] and [page:.direction direction] properties by copying the values from the given objects.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Sphere.html b/docs/api/en/math/Sphere.html index c66eecaab80729..7b47d5e256dbe8 100644 --- a/docs/api/en/math/Sphere.html +++ b/docs/api/en/math/Sphere.html @@ -46,8 +46,8 @@

    [method:Vector3 clampPoint]( [param:Vector3 point], [param:Vector3 target] ) [page:Vector3 point] - [page:Vector3] The point to clamp.
    [page:Vector3 target] — the result will be copied into this Vector3.

    - Clamps a point within the sphere. If the point is is outside the sphere, it will clamp it to the - closets point on the edge of the sphere. Points already inside the sphere will not be affected. + Clamps a point within the sphere. If the point is outside the sphere, it will clamp it to the + closest point on the edge of the sphere. Points already inside the sphere will not be affected.

    [method:Sphere clone]()

    @@ -114,7 +114,8 @@

    [method:Sphere set]( [param:Vector3 center], [param:Float radius] )

    [page:Vector3 center] - center of the sphere.
    [page:Float radius] - radius of the sphere.

    - Sets the [page:.center center] and [page:.radius radius] properties of this sphere. + Sets the [page:.center center] and [page:.radius radius] properties of this sphere.
    + Please note that this method only copies the values from the given center.

    [method:Sphere setFromPoints]( [param:Array points], [param:Vector3 optionalCenter] )

    @@ -134,6 +135,8 @@

    [method:Sphere translate]( [param:Vector3 offset] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Spherical.html b/docs/api/en/math/Spherical.html index dfe16f3ac0979f..b565d87ad0a80a 100644 --- a/docs/api/en/math/Spherical.html +++ b/docs/api/en/math/Spherical.html @@ -20,8 +20,8 @@

    [name]( [param:Float radius], [param:Float phi], [param:Float theta] )

    [page:Float radius] - the radius, or the [link:https://en.wikipedia.org/wiki/Euclidean_distance Euclidean distance] (straight-line distance) from the point to the origin. Default is *1.0*.
    - [page:Float phi] - polar angle from the y (up) axis. Default is *0*.
    - [page:Float theta] - equator angle around the y (up) axis. Default is *0*.

    + [page:Float phi] - polar angle in radians from the y (up) axis. Default is *0*.
    + [page:Float theta] - equator angle in radians around the y (up) axis. Default is *0*.

    The poles (phi) are at the positive and negative y axis. The equator (theta) starts at positive z.

    @@ -73,6 +73,8 @@

    [method:Spherical setFromCartesianCoords]( [param:Float x], [param:Float y],

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Triangle.html b/docs/api/en/math/Triangle.html index 5aa5ea12f25b3d..3cd59933ee5a3a 100644 --- a/docs/api/en/math/Triangle.html +++ b/docs/api/en/math/Triangle.html @@ -109,7 +109,7 @@

    [method:Vector3 getNormal]( [param:Vector3 target] )

    [method:Plane getPlane]( [param:Plane target] )

    - [page:Vector3 target] — the result will be copied into this Plane.

    + [page:Plane target] — the result will be copied into this Plane.

    Calculate a [page:Plane plane] based on the triangle. .

    @@ -123,7 +123,8 @@

    [method:Boolean intersectsBox]( [param:Box3 box] )

    [method:Triangle set]( [param:Vector3 a], [param:Vector3 b], [param:Vector3 c] ) [param:Triangle this]

    - Sets the triangle's [page:.a a], [page:.b b] and [page:.c c] properties to the passed [page:vector3 vector3s]. + Sets the triangle's [page:.a a], [page:.b b] and [page:.c c] properties to the passed [page:vector3 vector3s].
    + Please note that this method only copies the values from the given objects.

    [method:Triangle setFromPointsAndIndices]( [param:Array points], [param:Integer i0], [param:Integer i1], [param:Integer i2] ) [param:Triangle this]

    @@ -138,6 +139,8 @@

    [method:Triangle setFromPointsAndIndices]( [param:Array points], [param:Inte

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Vector2.html b/docs/api/en/math/Vector2.html index 945585a4d4fcf5..8a4d09d86d007b 100644 --- a/docs/api/en/math/Vector2.html +++ b/docs/api/en/math/Vector2.html @@ -37,7 +37,7 @@

    [name]

    vectors, complex numbers and so on, however these are the most common uses in three.js.

    -

    Example

    +

    Code Example

    var a = new THREE.Vector2( 0, 1 ); @@ -62,13 +62,6 @@

    [name]( [param:Float x], [param:Float y] )

    Properties

    -

    [property:Boolean isVector2]

    -

    - Used to check whether this or derived classes are Vector2s. Default is *true*.

    - - You should not change this, as it is used internally for optimisation. -

    -

    [property:Float height]

    Alias for [page:.y y].

    @@ -176,7 +169,7 @@

    [method:Float dot]( [param:Vector2 v] )

    Calculates the [link:https://en.wikipedia.org/wiki/Dot_product dot product] of this vector and [page:Vector2 v].

    - +

    [method:Float cross]( [param:Vector2 v] )

    Calculates the [link:https://en.wikipedia.org/wiki/Cross_product cross product] of this @@ -341,6 +334,8 @@

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Vector3.html b/docs/api/en/math/Vector3.html index 3a2cb02f0246df..9b10fa851fef56 100644 --- a/docs/api/en/math/Vector3.html +++ b/docs/api/en/math/Vector3.html @@ -37,15 +37,15 @@

    [name]

    -

    Example

    +

    Code Example

    -var a = new THREE.Vector3( 0, 1, 0 ); + var a = new THREE.Vector3( 0, 1, 0 ); -//no arguments; will be initialised to (0, 0, 0) -var b = new THREE.Vector3( ); + //no arguments; will be initialised to (0, 0, 0) + var b = new THREE.Vector3( ); -var d = a.distanceTo( b ); + var d = a.distanceTo( b ); @@ -63,13 +63,6 @@

    [name]( [param:Float x], [param:Float y], [param:Float z] )

    Properties

    -

    [property:Boolean isVector3]

    -

    - Used to check whether this or derived classes are Vector3s. Default is *true*.

    - - You should not change this, as it is used internally for optimisation. -

    -

    [property:Float x]

    [property:Float y]

    @@ -113,6 +106,9 @@

    [method:this applyMatrix4]( [param:Matrix4 m] )

    Multiplies this vector (with an implicit 1 in the 4th dimension) and m, and divides by perspective.

    +

    [method:this applyNormalMatrix]( [param:Matrix3 m] )

    +

    Multiplies this vector by normal matrix [page:Matrix3 m] and normalizes the result.

    +

    [method:this applyQuaternion]( [param:Quaternion quaternion] )

    Applies a [page:Quaternion] transform to this vector. @@ -309,7 +305,7 @@

    [method:this project]( [param:Camera camera] )

    [page:Camera camera] — camera to use in the projection.

    - [link:https://en.wikipedia.org/wiki/Vector_projection Projects] the vector with the camera. + Projects this vector from world space into the camera's normalized device coordinate (NDC) space.

    [method:this projectOnPlane]( [param:Vector3 planeNormal] )

    @@ -320,8 +316,8 @@

    [method:this projectOnPlane]( [param:Vector3 planeNormal] )

    normal from this vector.

    -

    [method:this projectOnVector]( [param:Vector3] )

    -

    [link:https://en.wikipedia.org/wiki/Vector_projection Projects] this vector onto another vector.

    +

    [method:this projectOnVector]( [param:Vector3 v] )

    +

    [link:https://en.wikipedia.org/wiki/Vector_projection Projects] this vector onto [page:Vector3 v].

    [method:this reflect]( [param:Vector3 normal] )

    @@ -362,8 +358,12 @@

    [method:this setFromCylindricalCoords]( [param:Float radius], [param:Float t

    [method:this setFromMatrixColumn]( [param:Matrix4 matrix], [param:Integer index] )

    - Sets this vector's [page:.x x], [page:.y y] and [page:.z z] equal to the column of - the [page:Matrix4 matrix] specified by the [page:Integer index]. + Sets this vector's [page:.x x], [page:.y y] and [page:.z z] components from [page:Integer index] column of [page:Matrix4 matrix]. +

    + +

    [method:this setFromMatrix3Column]( [param:Matrix3 matrix], [param:Integer index] )

    +

    + Sets this vector's [page:.x x], [page:.y y] and [page:.z z] components from [page:Integer index] column of [page:Matrix3 matrix].

    [method:this setFromMatrixPosition]( [param:Matrix4 m] )

    @@ -434,13 +434,14 @@

    [method:this unproject]( [param:Camera camera] )

    [page:Camera camera] — camera to use in the projection.

    - [link:https://en.wikipedia.org/wiki/Vector_projection Unprojects] the vector with the - camera's projection matrix. + Projects this vector from the camera's normalized device coordinate (NDC) space into world space.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/Vector4.html b/docs/api/en/math/Vector4.html index be7d8f4e44a883..93df50b48e993b 100644 --- a/docs/api/en/math/Vector4.html +++ b/docs/api/en/math/Vector4.html @@ -36,15 +36,15 @@

    [name]

    -

    Example

    +

    Code Example

    -var a = new THREE.Vector4( 0, 1, 0, 0 ); + var a = new THREE.Vector4( 0, 1, 0, 0 ); -//no arguments; will be initialised to (0, 0, 0, 1) -var b = new THREE.Vector4( ); + //no arguments; will be initialised to (0, 0, 0, 1) + var b = new THREE.Vector4( ); -var d = a.dot( b ); + var d = a.dot( b ); @@ -63,13 +63,6 @@

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    Properties

    -

    [property:Boolean isVector4]

    -

    - Used to check whether this or derived classes are Vector4s. Default is *true*.

    - - You should not change this, as it is used internally for optimisation. -

    -

    [property:Float x]

    [property:Float y]

    @@ -332,6 +325,8 @@

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/interpolants/CubicInterpolant.html b/docs/api/en/math/interpolants/CubicInterpolant.html index fed706a2fdff13..0cc29820369f7d 100644 --- a/docs/api/en/math/interpolants/CubicInterpolant.html +++ b/docs/api/en/math/interpolants/CubicInterpolant.html @@ -16,7 +16,7 @@

    [name]

    -

    Example

    +

    Code Example

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/interpolants/DiscreteInterpolant.html b/docs/api/en/math/interpolants/DiscreteInterpolant.html index fed706a2fdff13..0cc29820369f7d 100644 --- a/docs/api/en/math/interpolants/DiscreteInterpolant.html +++ b/docs/api/en/math/interpolants/DiscreteInterpolant.html @@ -16,7 +16,7 @@

    [name]

    -

    Example

    +

    Code Example

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/interpolants/LinearInterpolant.html b/docs/api/en/math/interpolants/LinearInterpolant.html index fed706a2fdff13..0cc29820369f7d 100644 --- a/docs/api/en/math/interpolants/LinearInterpolant.html +++ b/docs/api/en/math/interpolants/LinearInterpolant.html @@ -16,7 +16,7 @@

    [name]

    -

    Example

    +

    Code Example

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/math/interpolants/QuaternionLinearInterpolant.html b/docs/api/en/math/interpolants/QuaternionLinearInterpolant.html index fed706a2fdff13..0cc29820369f7d 100644 --- a/docs/api/en/math/interpolants/QuaternionLinearInterpolant.html +++ b/docs/api/en/math/interpolants/QuaternionLinearInterpolant.html @@ -16,7 +16,7 @@

    [name]

    -

    Example

    +

    Code Example

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/Bone.html b/docs/api/en/objects/Bone.html index a6cdf0fef76b0c..3c0c9548ed70ae 100644 --- a/docs/api/en/objects/Bone.html +++ b/docs/api/en/objects/Bone.html @@ -17,7 +17,7 @@

    [name]

    Bones are almost identical to a blank [page:Object3D].

    -

    Example

    +

    Code Example

    var root = new THREE.Bone(); @@ -37,13 +37,6 @@

    [name]( )

    Properties

    See the base [page:Object3D] class for common properties.

    -

    [property:Boolean isBone]

    -

    - Used to check whether this or derived classes are bones. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:String type]

    Set to 'Bone', this can be used to find all Bones in a scene.

    @@ -54,6 +47,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/Group.html b/docs/api/en/objects/Group.html index 67da2510134366..953072baa5bd56 100644 --- a/docs/api/en/objects/Group.html +++ b/docs/api/en/objects/Group.html @@ -17,8 +17,7 @@

    [name]

    with groups of objects syntactically clearer.

    - -

    Example

    +

    Code Example

    var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); @@ -55,6 +54,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/InstancedMesh.html b/docs/api/en/objects/InstancedMesh.html new file mode 100644 index 00000000000000..76c92c9782a49b --- /dev/null +++ b/docs/api/en/objects/InstancedMesh.html @@ -0,0 +1,91 @@ + + + + + + + + + + + [page:Mesh] → + +

    [name]

    + +

    + A special version of [page:Mesh] with instanced rendering support. Use [name] if you have to render a large number of + objects with the same geometry and material but with different world transformations. The usage of [name] will help you + to reduce the number of draw calls and thus improve the overall rendering performance in your application. +

    +

    + The current implementation requires that materials are not shared between [name] and other 3D objects. +

    + +

    Examples

    + +

    + [example:webgl_instancing_dynamic WebGL / instancing / dynamic]
    + [example:webgl_instancing_modified WebGL / instancing / modified]
    + [example:webgl_instancing_performance WebGL / instancing / performance]
    + [example:webgl_instancing_scatter WebGL / instancing / scatter]
    + [example:webgl_instancing_raycast WebGL / instancing / raycast] +

    + +

    Constructor

    +

    [name]( [param:BufferGeometry geometry], [param:Material material], [param:Integer count] )

    +

    + [page:Geometry geometry] - an instance of [page:BufferGeometry].
    + [page:Material material] - an instance of [page:Material]. Default is a new [page:MeshBasicMaterial].
    + [page:Integer count] - the number of instances.
    +

    + +

    Properties

    +

    See the base [page:Mesh] class for common properties.

    + +

    [property:Integer count]

    +

    + The number of instances. The *count* value passed into the constructor represents the maximum number of + instances of this mesh. You can change the number of instances at runtime to an integer value + in the range [0, count]. +

    +

    + If you need more instances than the original count value, you have to create a new [name]. +

    + +

    [property:BufferAttribute instanceMatrix]

    +

    + Represents the local transformation of all instances. For internal use only. +

    + +

    Methods

    +

    See the base [page:Mesh] class for common methods.

    + +

    [method:null getMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )

    +

    + [page:Integer index]: The index of an instance. Values have to be in the range [0, count]. +

    +

    + [page:Matrix4 matrix]: This 4x4 matrix will be set to the local transformation matrix of the defined instance. +

    +

    + Get the local transformation matrix of the defined instance. +

    + +

    [method:null setMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )

    +

    + [page:Integer index]: The index of an instance. Values have to be in the range [0, count]. +

    +

    + [page:Matrix4 matrix]: A 4x4 matrix representing the local transformation of a single instance. +

    +

    + Sets the given local transformation matrix to the defined instance. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/en/objects/LOD.html b/docs/api/en/objects/LOD.html index 1ce7df96ce46a5..3f8417f632320a 100644 --- a/docs/api/en/objects/LOD.html +++ b/docs/api/en/objects/LOD.html @@ -20,29 +20,31 @@

    [name]

    and one for close up (high detail).

    -

    Example

    - -

    - [example:webgl_lod webgl / lod ] -

    +

    Code Example

    -var lod = new THREE.LOD(); + var lod = new THREE.LOD(); -//Create spheres with 3 levels of detail and create new LOD levels for them -for( var i = 0; i < 3; i++ ) { + //Create spheres with 3 levels of detail and create new LOD levels for them + for( var i = 0; i < 3; i++ ) { - var geometry = new THREE.IcosahedronBufferGeometry( 10, 3 - i ) + var geometry = new THREE.IcosahedronBufferGeometry( 10, 3 - i ) - var mesh = new THREE.Mesh( geometry, material ); + var mesh = new THREE.Mesh( geometry, material ); - lod.addLevel( mesh, i * 75 ); + lod.addLevel( mesh, i * 75 ); -} + } -scene.add( lod ); + scene.add( lod ); +

    Examples

    + +

    + [example:webgl_lod webgl / lod ] +

    +

    Constructor

    [name]( )

    @@ -87,6 +89,13 @@

    [method:LOD clone]()

    +

    [method:integer getCurrentLevel]()

    +

    + Get the currently active LOD level. As index of the levels array. +

    + + +

    [method:Object3D getObjectForDistance]( [param:Float distance] )

    Get a reference to the first [page:Object3D] (mesh) that is greater than [page:Float distance]. @@ -108,11 +117,13 @@

    [method:Object toJSON]( meta )

    [method:null update]( [param:Camera camera] )

    Set the visibility of each [page:levels level]'s [page:Object3D object] based on - distance from the [page:Camera camera]. + distance from the [page:Camera camera].

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/Line.html b/docs/api/en/objects/Line.html index cb3800af8f5b1c..4e30e0b83e21fc 100644 --- a/docs/api/en/objects/Line.html +++ b/docs/api/en/objects/Line.html @@ -22,19 +22,19 @@

    [name]

    +

    Code Example

    -

    Example

    - - var material = new THREE.LineBasicMaterial({ + + var material = new THREE.LineBasicMaterial({ color: 0x0000ff }); - var geometry = new THREE.Geometry(); - geometry.vertices.push( - new THREE.Vector3( -10, 0, 0 ), - new THREE.Vector3( 0, 10, 0 ), - new THREE.Vector3( 10, 0, 0 ) - ); + var points = []; + points.push( new THREE.Vector3( - 10, 0, 0 ) ); + points.push( new THREE.Vector3( 0, 10, 0 ) ); + points.push( new THREE.Vector3( 10, 0, 0 ) ); + + var geometry = new THREE.BufferGeometry().setFromPoints( points ); var line = new THREE.Line( geometry, material ); scene.add( line ); @@ -47,22 +47,12 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    [page:Geometry geometry] — vertices representing the line segment(s). Default is a new [page:BufferGeometry].
    - [page:Material material] — material for the line. Default is a new [page:LineBasicMaterial] with random color.
    + [page:Material material] — material for the line. Default is a new [page:LineBasicMaterial].

    -

    If no material is supplied, a randomized line material will be created and assigned to the object.

    - -

    Properties

    See the base [page:Object3D] class for common properties.

    -

    [property:Boolean isLine]

    -

    - Used to check whether this or derived classes are lines. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:Geometry geometry]

    Vertices representing the line segment(s).

    @@ -93,6 +83,8 @@

    [method:Line clone]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/LineLoop.html b/docs/api/en/objects/LineLoop.html index 0c25e2fd3101b1..646966459c09ef 100644 --- a/docs/api/en/objects/LineLoop.html +++ b/docs/api/en/objects/LineLoop.html @@ -31,25 +31,17 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    [page:Material material] — Material for the line. Default is [page:LineBasicMaterial LineBasicMaterial].

    -

    If no material is supplied, a randomized line material will be created and assigned to the object.

    - -

    Properties

    See the base [page:Line] class for common properties.

    -

    [property:Boolean isLineLoop]

    -

    - Used to check whether this or derived classes are line loops. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    Methods

    See the base [page:Line] class for common methods.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/LineSegments.html b/docs/api/en/objects/LineSegments.html index bc349168ba3a09..81a31b9d7463f7 100644 --- a/docs/api/en/objects/LineSegments.html +++ b/docs/api/en/objects/LineSegments.html @@ -30,25 +30,17 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    [page:Material material] — Material for the line. Default is [page:LineBasicMaterial LineBasicMaterial].

    -

    If no material is supplied, a randomized line material will be created and assigned to the object.

    - -

    Properties

    See the base [page:Line] class for common properties.

    -

    [property:Boolean isLineSegments]

    -

    - Used to check whether this or derived classes are line segments. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    Methods

    See the base [page:Line] class for common methods.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/Mesh.html b/docs/api/en/objects/Mesh.html index 4e4de02eb9084c..24f1fa9fcd81a8 100644 --- a/docs/api/en/objects/Mesh.html +++ b/docs/api/en/objects/Mesh.html @@ -17,8 +17,7 @@

    [name]

    Also serves as a base for other classes such as [page:SkinnedMesh].

    - -

    Example

    +

    Code Example

    var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); @@ -27,7 +26,6 @@

    Example

    scene.add( mesh );
    -

    Constructor

    [name]( [param:Geometry geometry], [param:Material material] )

    @@ -41,21 +39,6 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    Properties

    See the base [page:Object3D] class for common properties.

    -

    [property:Integer drawMode]

    -

    - Determines how the mesh triangles are constructed from the vertices. - See the draw mode [page:DrawModes constants] for all possible values. - Default is [page:DrawModes TrianglesDrawMode]. -

    - - -

    [property:Boolean isMesh]

    -

    - Used to check whether this or derived classes are meshes. Default is *true*.

    - - You should not change this, as it is used internally for optimisation. -

    -

    [property:Geometry geometry]

    An instance of [page:Geometry] or [page:BufferGeometry] (or derived classes), @@ -67,7 +50,7 @@

    [property:Geometry geometry]

    [property:Material material]

    An instance of material derived from the [page:Material] base class or an array of materials, defining the - object's appearance. Default is a [page:MeshBasicMaterial] with a random color. + object's appearance. Default is a [page:MeshBasicMaterial].

    [property:Array morphTargetInfluences]

    @@ -86,9 +69,6 @@

    [property:Object morphTargetDictionary]

    Methods

    See the base [page:Object3D] class for common methods.

    -

    [method:null setDrawMode]( [param:Integer value] )

    -

    Set the value of [page:.drawMode drawMode].

    -

    [method:Mesh clone]()

    Returns a clone of this [name] object and its descendants.

    @@ -108,6 +88,8 @@

    [method:null updateMorphTargets]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/Points.html b/docs/api/en/objects/Points.html index f882cd6450fc40..ac1e17a31203ab 100644 --- a/docs/api/en/objects/Points.html +++ b/docs/api/en/objects/Points.html @@ -25,8 +25,7 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    [page:Geometry geometry] — (optional) an instance of [page:Geometry] or [page:BufferGeometry]. Default is a new [page:BufferGeometry].
    - [page:Material material] — (optional) a [page:Material]. Default is a new [page:PointsMaterial] - with a random color. + [page:Material material] — (optional) a [page:Material]. Default is a new [page:PointsMaterial].

    @@ -41,17 +40,10 @@

    [property:Geometry geometry]

    Its recommended to always use a [page:BufferGeometry] if possible for best performance.

    -

    [property:Boolean isPoints]

    -

    - Used to check whether this or derived classes are points. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:Material material]

    An instance of [page:Material], defining the object's appearance. - Default is a [page:PointsMaterial] with a random color. + Default is a [page:PointsMaterial].

    [property:Array morphTargetInfluences]

    @@ -89,7 +81,9 @@

    [method:null updateMorphTargets]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/Skeleton.html b/docs/api/en/objects/Skeleton.html index b5c94d851b5898..e6e133a8360b4d 100644 --- a/docs/api/en/objects/Skeleton.html +++ b/docs/api/en/objects/Skeleton.html @@ -16,29 +16,30 @@

    [name]

    [page:SkinnedMesh].

    -

    Example

    - -// Create a simple "arm" +

    Code Example

    + + // Create a simple "arm" -var bones = []; + var bones = []; -var shoulder = new THREE.Bone(); -var elbow = new THREE.Bone(); -var hand = new THREE.Bone(); + var shoulder = new THREE.Bone(); + var elbow = new THREE.Bone(); + var hand = new THREE.Bone(); -shoulder.add( elbow ); -elbow.add( hand ); + shoulder.add( elbow ); + elbow.add( hand ); -bones.push( shoulder ); -bones.push( elbow ); -bones.push( hand ); + bones.push( shoulder ); + bones.push( elbow ); + bones.push( hand ); -shoulder.position.y = -5; -elbow.position.y = 0; -hand.position.y = 5; + shoulder.position.y = -5; + elbow.position.y = 0; + hand.position.y = 5; + + var armSkeleton = new THREE.Skeleton( bones ); + -var armSkeleton = new THREE.Skeleton( bones ); -

    See the [page:SkinnedMesh] page for an example of usage with standard [page:BufferGeometry].

    @@ -111,6 +112,8 @@

    [method:Bone getBoneByName]( [param:String name] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/SkinnedMesh.html b/docs/api/en/objects/SkinnedMesh.html index 850c8777f05dba..e314768b1576af 100644 --- a/docs/api/en/objects/SkinnedMesh.html +++ b/docs/api/en/objects/SkinnedMesh.html @@ -35,7 +35,7 @@

    [name]

    -

    Example

    +

    Code Example

    var geometry = new THREE.CylinderBufferGeometry( 5, 5, 5, 5, 15, 5, 30 ); @@ -65,8 +65,8 @@

    Example

    } - geometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); - geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); + geometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); + geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); // create skinned mesh and skeleton @@ -119,13 +119,6 @@

    [property:Matrix4 bindMatrixInverse]

    The base matrix that is used for resetting the bound bone transforms.

    -

    [property:Boolean isSkinnedMesh]

    -

    - Used to check whether this or derived classes are skinned meshes. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:Skeleton skeleton]

    [page:Skeleton] representing the bone hierarchy of the skinned mesh. @@ -167,6 +160,8 @@

    [method:null updateMatrixWorld]( [param:Boolean force] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/objects/Sprite.html b/docs/api/en/objects/Sprite.html index 68adb55c68fe7d..44d775e357ff04 100644 --- a/docs/api/en/objects/Sprite.html +++ b/docs/api/en/objects/Sprite.html @@ -19,16 +19,15 @@

    [name]

    Sprites do not cast shadows, setting castShadow = true will have no effect.

    -

    Example

    +

    Code Example

    -var spriteMap = new THREE.TextureLoader().load( "sprite.png" ); -var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } ); -var sprite = new THREE.Sprite( spriteMaterial ); -scene.add( sprite ); + var spriteMap = new THREE.TextureLoader().load( "sprite.png" ); + var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap } ); + var sprite = new THREE.Sprite( spriteMaterial ); + scene.add( sprite ); -

    Constructor

    [name]( [param:Material material] )

    @@ -42,13 +41,6 @@

    [name]( [param:Material material] )

    Properties

    See the base [page:Object3D] class for common properties.

    -

    [property:Boolean isSprite]

    -

    - Used to check whether this or derived classes are sprites. Default is *true*.

    - - You should not change this, as it used internally for optimisation. -

    -

    [property:SpriteMaterial material]

    @@ -85,6 +77,8 @@

    [method:null raycast]( [param:Raycaster raycaster], [param:Array intersects]

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/WebGLRenderTargetCube.html b/docs/api/en/renderers/WebGLCubeRenderTarget.html similarity index 76% rename from docs/api/en/renderers/WebGLRenderTargetCube.html rename to docs/api/en/renderers/WebGLCubeRenderTarget.html index 7a0b6c444d6721..3c5520751ebfc0 100644 --- a/docs/api/en/renderers/WebGLRenderTargetCube.html +++ b/docs/api/en/renderers/WebGLCubeRenderTarget.html @@ -24,10 +24,9 @@

    Examples

    Constructor

    -

    [name]([param:Number width], [param:Number height], [param:Object options])

    +

    [name]([param:Number size], param:Object options])

    - [page:Float width] - The width of the renderTarget.
    - [page:Float height] - The height of the renderTarget.
    + [page:Float size] - the size, in pixels.
    options - (optional) object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. @@ -57,9 +56,19 @@

    Methods

    See [page:WebGLRenderTarget] for inherited methods

    +

    [method:WebGLCubeRenderTarget fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )

    +

    + [page:WebGLRenderer renderer] — the renderer.
    + [page:Texture texture] — the equirectangular texture. +

    +

    + Use this method if you want to convert an equirectangular panorama to the cubemap format. +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/WebGLMultisampleRenderTarget.html b/docs/api/en/renderers/WebGLMultisampleRenderTarget.html index 2d138ee738386a..b5691980d9d550 100644 --- a/docs/api/en/renderers/WebGLMultisampleRenderTarget.html +++ b/docs/api/en/renderers/WebGLMultisampleRenderTarget.html @@ -44,6 +44,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/WebGLRenderTarget.html b/docs/api/en/renderers/WebGLRenderTarget.html index 503afc1b9af207..4372319dcabc89 100644 --- a/docs/api/en/renderers/WebGLRenderTarget.html +++ b/docs/api/en/renderers/WebGLRenderTarget.html @@ -38,7 +38,7 @@

    [name]([param:Number width], [param:Number height], [param:Object options])< [page:Constant minFilter] - default is [page:Textures LinearFilter].
    [page:Constant format] - default is [page:Textures RGBAFormat].
    [page:Constant type] - default is [page:Textures UnsignedByteType].
    - [page:Number anisotropy] - default is *1*. See [page:Texture.anistropy]
    + [page:Number anisotropy] - default is *1*. See [page:Texture.anisotropy]
    [page:Constant encoding] - default is [page:Textures LinearEncoding].
    [page:Boolean depthBuffer] - default is *true*. Set this to false if you don't need it.
    [page:Boolean stencilBuffer] - default is *true*. Set this to false if you don't need it.

    @@ -124,6 +124,8 @@

    [page:EventDispatcher EventDispatcher] methods are available on this class.<

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/WebGLRenderer.html b/docs/api/en/renderers/WebGLRenderer.html index 283f98583a82ec..e64a2672c453af 100644 --- a/docs/api/en/renderers/WebGLRenderer.html +++ b/docs/api/en/renderers/WebGLRenderer.html @@ -65,7 +65,9 @@

    [name]( [param:Object parameters] )

    Default is *true*.
    [page:Boolean logarithmicDepthBuffer] - whether to use a logarithmic depth buffer. It may - be neccesary to use this if dealing with huge differences in scale in a single scene. + be neccesary to use this if dealing with huge differences in scale in a single scene. Note that this setting + uses gl_FragDepth if available which disables the [link:https://www.khronos.org/opengl/wiki/Early_Fragment_Test Early Fragment Test] + optimization and can cause a decrease in performance. Default is *false*. See the [example:webgl_camera_logarithmicdepthbuffer camera / logarithmicdepthbuffer] example.

    @@ -162,13 +164,9 @@

    [property:Object extensions]

    [property:Float gammaFactor]

    Default is *2*.

    - -

    [property:Boolean gammaInput]

    -

    If set, then it expects that all textures and colors are premultiplied gamma. Default is *false*.

    - - -

    [property:Boolean gammaOutput]

    -

    If set, then it expects that all textures and colors need to be outputted in premultiplied gamma. Default is *false*.

    +

    [property:number outputEncoding]

    +

    Defines the output encoding of the renderer. Default is [page:Textures THREE.LinearEncoding].

    +

    See the [page:Textures texture constants] page for details of other formats.

    [property:Object info]

    An object with a series of statistical information about the graphics board memory and the rendering process. Useful for debugging or just for the sake of curiosity. The object contains the following fields:

    @@ -186,6 +184,7 @@

    [property:Object info]

  • triangles
  • points
  • lines
  • +
  • frame
  • programs @@ -248,7 +247,7 @@

    [property:Boolean shadowMap.needsUpdate]

    [property:Integer shadowMap.type]

    Defines shadow map type (unfiltered, percentage close filtering, percentage close filtering with bilinear filtering in shader)

    -

    Options are THREE.BasicShadowMap, THREE.PCFShadowMap (default) and THREE.PCFSoftShadowMap. See [page:Renderer Renderer constants] for details.

    +

    Options are THREE.BasicShadowMap, THREE.PCFShadowMap (default), THREE.PCFSoftShadowMap and THREE.VSMShadowMap. See [page:Renderer Renderer constants] for details.

    [property:Boolean sortObjects]

    @@ -280,6 +279,16 @@

    [property:Number toneMappingWhitePoint]

    Tone mapping white point. Default is *1*.

    +

    [property:Object xr]

    +

    + Provides access to the WebXR related interface of the renderer. +

    + +

    [property:Boolean xr.enabled]

    +

    + Whether the renderer should enable XR rendering or not. Default is *false*. +

    +

    Methods

    [method:null clear]( [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )

    @@ -391,6 +400,9 @@

    [method:Vector4 getViewport]( [param:Vector4 target] )

    Returns the viewport.

    +

    [method:null initTexture]( [param:Texture texture] )

    +

    Initializes the given texture. Useful for preloading a texture rather than waiting until first render (which can cause noticeable lags due to decode and GPU upload overhead).

    +

    [method:null resetGLState]( )

    Reset the GL state to default. Called internally if the WebGL context is lost.

    @@ -398,7 +410,7 @@

    [method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget]

    buffer - Uint8Array is the only destination type supported in all cases, other types are renderTarget and platform dependent. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.

    Reads the pixel data from the renderTarget into the buffer you pass in. This is a wrapper around [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]().

    See the [example:webgl_interactive_cubes_gpu interactive / cubes / gpu] example.

    -

    For reading out a [page:WebGLRenderTargetCube WebGLRenderTargetCube] use the optional parameter activeCubeFaceIndex to determine which face should be read.

    +

    For reading out a [page:WebGLCubeRenderTarget WebGLCubeRenderTarget] use the optional parameter activeCubeFaceIndex to determine which face should be read.

    [method:null render]( [param:Scene scene], [param:Camera camera] )

    @@ -425,7 +437,7 @@

    [method:null renderBufferImmediate]( [param:Object3D object], [param:shaderp

    [method:null setAnimationLoop]( [param:Function callback] )

    [page:Function callback] — The function will be called every available frame. If `null` is passed it will stop any already ongoing animation.

    -

    A built in function that can be used instead of [link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]. For WebVR projects this function must be used.

    +

    A built in function that can be used instead of [link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]. For WebXR projects this function must be used.

    [method:null setClearAlpha]( [param:Float alpha] )

    Sets the clear alpha. Valid input is a float between *0.0* and *1.0*.

    @@ -433,13 +445,16 @@

    [method:null setClearAlpha]( [param:Float alpha] )

    [method:null setClearColor]( [param:Color color], [param:Float alpha] )

    Sets the clear color and opacity.

    +

    [method:null setFramebuffer]( [param:WebGLFramebuffer value] )

    +

    Sets the given WebGLFramebuffer. This method can only be used if no render target is set via [page:WebGLRenderer.setRenderTarget .setRenderTarget]().

    +

    [method:null setPixelRatio]( [param:number value] )

    Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output canvas.

    [method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget], [param:Integer activeCubeFace], [param:Integer activeMipmapLevel] )

    renderTarget -- The [page:WebGLRenderTarget renderTarget] that needs to be activated. When *null* is given, the canvas is set as the active render target instead.
    - activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLRenderTargetCube] (optional).
    + activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLCubeRenderTarget] (optional).
    activeMipmapLevel -- Specifies the active mipmap level (optional).

    This method sets the active rendertarget.

    @@ -461,6 +476,16 @@

    [method:null setScissorTest]( [param:Boolean boolean] )

    scissor area will be affected by further renderer actions.

    +

    [method:null setOpaqueSort]( [param:Function method] )

    +

    + Sets the custom opaque sort function for the WebGLRenderLists. Pass null to use the default painterSortStable function. +

    + +

    [method:null setTransparentSort]( [param:Function method] )

    +

    + Sets the custom transparent sort function for the WebGLRenderLists. Pass null to use the default reversePainterSortStable function. +

    +

    [method:null setSize]( [param:Integer width], [param:Integer height], [param:Boolean updateStyle] )

    Resizes the output canvas to (width, height) with device pixel ratio taken into account, @@ -481,6 +506,8 @@

    [method:null setViewport]( [param:Integer x], [param:Integer y], [param:Inte

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/shaders/ShaderChunk.html b/docs/api/en/renderers/shaders/ShaderChunk.html index a9c917b94ba3c3..a7d1600163d4df 100644 --- a/docs/api/en/renderers/shaders/ShaderChunk.html +++ b/docs/api/en/renderers/shaders/ShaderChunk.html @@ -24,6 +24,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/shaders/ShaderLib.html b/docs/api/en/renderers/shaders/ShaderLib.html index d363e2e5da52a8..c5a72cc0aa8b13 100644 --- a/docs/api/en/renderers/shaders/ShaderLib.html +++ b/docs/api/en/renderers/shaders/ShaderLib.html @@ -23,6 +23,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/shaders/UniformsLib.html b/docs/api/en/renderers/shaders/UniformsLib.html index f8228941c52b56..83dda51acda015 100644 --- a/docs/api/en/renderers/shaders/UniformsLib.html +++ b/docs/api/en/renderers/shaders/UniformsLib.html @@ -24,6 +24,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/shaders/UniformsUtils.html b/docs/api/en/renderers/shaders/UniformsUtils.html index bf978cbbb89229..7ac9813b333160 100644 --- a/docs/api/en/renderers/shaders/UniformsUtils.html +++ b/docs/api/en/renderers/shaders/UniformsUtils.html @@ -10,18 +10,33 @@

    [name]

    -

    Uniform Utilities. Support merging and cloning of uniform variables

    - -

    Properties

    +

    + Provides utility functions for managing uniforms. +

    +

    Methods

    +

    [method:Object clone]( [param:Object src] )

    +

    + src -- An object representing uniform definitions.

    -

    Methods

    + Clones the given uniform definitions by performing a deep-copy. That means if + the [page:Uniform.value value] of a uniform refers to an object like a [page:Vector3] + or [page:Texture], the cloned uniform will refer to a new object reference. +

    +

    [method:Object merge]( [param:Array uniforms] )

    +

    + uniforms -- An array of objects containing uniform definitions.

    + Merges the given uniform definitions into a single object. Since the method + internally uses [page:.clone](), it performs a deep-copy when producing the + merged uniform definitions.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/webgl/WebGLProgram.html b/docs/api/en/renderers/webgl/WebGLProgram.html index 14abf7cec03bde..f8c66501318880 100644 --- a/docs/api/en/renderers/webgl/WebGLProgram.html +++ b/docs/api/en/renderers/webgl/WebGLProgram.html @@ -142,6 +142,8 @@

    [method:Object getAttributes]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/webgl/WebGLShader.html b/docs/api/en/renderers/webgl/WebGLShader.html index f62f7214431b3f..5382ab96752d1d 100644 --- a/docs/api/en/renderers/webgl/WebGLShader.html +++ b/docs/api/en/renderers/webgl/WebGLShader.html @@ -12,7 +12,7 @@

    [name]

    A lower level function to compile either a vertex or fragment shader.

    -

    Example

    +

    Code Example

    var gl = renderer.getContext(); @@ -44,6 +44,8 @@

    [page:WebGLShader objects]([page:WebGLContext gl], [page:WebGLEnum type], [p

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/renderers/webgl/WebGLState.html b/docs/api/en/renderers/webgl/WebGLState.html index 2d8a34ada4093e..ecd6054d261aaf 100644 --- a/docs/api/en/renderers/webgl/WebGLState.html +++ b/docs/api/en/renderers/webgl/WebGLState.html @@ -55,6 +55,8 @@

    [method:null setBlending]( [param:number blending], [param:number blendEquat

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/scenes/Fog.html b/docs/api/en/scenes/Fog.html index ae713493bd1673..197d612cb34e09 100644 --- a/docs/api/en/scenes/Fog.html +++ b/docs/api/en/scenes/Fog.html @@ -45,6 +45,8 @@

    [method:Fog toJSON]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/scenes/FogExp2.html b/docs/api/en/scenes/FogExp2.html index bd196454bbdb4f..c9f9a05541452d 100644 --- a/docs/api/en/scenes/FogExp2.html +++ b/docs/api/en/scenes/FogExp2.html @@ -41,6 +41,8 @@

    [method:FogExp2 toJSON]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/scenes/Scene.html b/docs/api/en/scenes/Scene.html index d7d54a69c1c173..b2512d0d16d32b 100644 --- a/docs/api/en/scenes/Scene.html +++ b/docs/api/en/scenes/Scene.html @@ -25,14 +25,6 @@

    [name]()

    Properties

    -

    [property:Fog fog]

    - -

    A [page:Fog fog] instance defining the type of fog that affects everything rendered in the scene. Default is null.

    - -

    [property:Material overrideMaterial]

    - -

    If not null, it will force everything in the scene to be rendered with that material. Default is null.

    -

    [property:boolean autoUpdate]

    Default is true. If set, then the renderer checks every frame if the scene and its objects needs matrix updates. @@ -41,24 +33,40 @@

    [property:boolean autoUpdate]

    [property:Object background]

    - If not null, sets the background used when rendering the scene, and is always rendered first. Can be set to a [page:Color] which sets the clear color, a [page:Texture] covering the canvas, or a cubemap as a [page:CubeTexture] or [page:WebGLRenderTargetCube]. Default is null. + If not null, sets the background used when rendering the scene, and is always rendered first. Can be set to a [page:Color] which sets the clear color, a [page:Texture] covering the canvas, or a cubemap as a [page:CubeTexture] or [page:WebGLCubeRenderTarget]. Default is null.

    -

    Methods

    - -

    [method:Object toJSON]

    +

    [property:Texture environment]

    - meta -- object containing metadata such as textures or images for the scene.
    - Convert the scene to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format]. + If not null, this texture is set as the environment map for all physical materials in the scene. + However, it's not possible to overwrite an existing texture assigned to [page:MeshStandardMaterial.envmap]. Default is null.

    +

    [property:Fog fog]

    + +

    A [page:Fog fog] instance defining the type of fog that affects everything rendered in the scene. Default is null.

    + +

    [property:Material overrideMaterial]

    + +

    If not null, it will force everything in the scene to be rendered with that material. Default is null.

    + +

    Methods

    +

    [method:null dispose]()

    Clears scene related data internally cached by [page:WebGLRenderer].

    +

    [method:Object toJSON]

    +

    + meta -- object containing metadata such as textures or images for the scene.
    + Convert the scene to three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format]. +

    +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/CanvasTexture.html b/docs/api/en/textures/CanvasTexture.html index d2329a1c06840c..bc4978efa7f21d 100644 --- a/docs/api/en/textures/CanvasTexture.html +++ b/docs/api/en/textures/CanvasTexture.html @@ -72,6 +72,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/CompressedTexture.html b/docs/api/en/textures/CompressedTexture.html index 9ab8960b7329f7..6e09822ff378e8 100644 --- a/docs/api/en/textures/CompressedTexture.html +++ b/docs/api/en/textures/CompressedTexture.html @@ -83,6 +83,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/CubeTexture.html b/docs/api/en/textures/CubeTexture.html index d3e0400abcec89..922da9a2cbb110 100644 --- a/docs/api/en/textures/CubeTexture.html +++ b/docs/api/en/textures/CubeTexture.html @@ -9,17 +9,17 @@ [page:Texture] → - +

    [name]

    Creates a cube texture made up of six images.

    -

    Example

    +

    Code Example

    var loader = new THREE.CubeTextureLoader(); loader.setPath( 'textures/cube/pisa/' ); - + var textureCube = loader.load( [ 'px.png', 'nx.png', 'py.png', 'ny.png', @@ -33,7 +33,7 @@

    Constructor

    [name]( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy )

    - +

    CubeTexture is almost equivalent in functionality and usage to [page:Texture]. The only differences are that the images are an array of 6 images as opposed to a single image, and the mapping options are @@ -43,15 +43,20 @@

    [name]( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, a

    Properties

    -

    See [page:Texture]

    +

    + See the base [page:Texture Texture] class for common properties. +

    Methods

    - -

    See [page:Texture]

    - +

    + See the base [page:Texture Texture] class for common methods. +

    +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/DataTexture.html b/docs/api/en/textures/DataTexture.html index e20530b3023af2..4cd16520ae10aa 100644 --- a/docs/api/en/textures/DataTexture.html +++ b/docs/api/en/textures/DataTexture.html @@ -32,7 +32,7 @@

    [name]( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, In order to use the types THREE.FloatType and THREE.HalfFloatType, the WebGL implementation must support the respective extensions OES_texture_float and OES_texture_half_float. In order to use THREE.LinearFilter for component-wise, bilinear interpolation of the texels based on these types, the WebGL extensions OES_texture_float_linear or OES_texture_half_float_linear must also be present.

    -

    Example

    +

    Code Example

    // create a buffer with color data @@ -57,11 +57,14 @@

    Example

    // used the buffer to create a [name] var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat ); - texture.needsUpdate = true

    Properties

    +

    + See the base [page:Texture Texture] class for common properties. +

    +

    [property:Image image]

    Overridden with a record type holding data, width and height. @@ -69,9 +72,14 @@

    [property:Image image]

    Methods

    +

    + See the base [page:Texture Texture] class for common methods. +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/DataTexture3D.html b/docs/api/en/textures/DataTexture3D.html index 453a1f14b5fc3a..8c90c946a5c87d 100644 --- a/docs/api/en/textures/DataTexture3D.html +++ b/docs/api/en/textures/DataTexture3D.html @@ -27,18 +27,20 @@

    [name]( [param:TypedArray data], [param:Number width], [param:Number height] [page:Number depth] -- depth of the texture.

    -

    Example

    +

    Examples

    -
    [example:webgl2_materials_texture3d WebGL2 / materials / texture3d]
    -
    [example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]
    +

    + [example:webgl2_materials_texture3d WebGL2 / materials / texture3d]
    + [example:webgl2_materials_texture2darray WebGL2 / materials / texture2darray] +

    -

    Properties

    +

    Properties

    - See the base [page:Texture Texture] class for common properties. -

    + See the base [page:Texture Texture] class for common properties. +

    -

    [property:number wrapR]

    +

    [property:number wrapR]

    This defines how the texture is wrapped in the depth direction.
    The default is [page:Textures THREE.ClampToEdgeWrapping], where the edge is clamped to the outer edge texels. @@ -54,6 +56,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/DepthTexture.html b/docs/api/en/textures/DepthTexture.html index 3ec095dfd2f815..c59636cc547c13 100644 --- a/docs/api/en/textures/DepthTexture.html +++ b/docs/api/en/textures/DepthTexture.html @@ -17,9 +17,11 @@

    [name]

    [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/ WEBGL_depth_texture] extension.

    -

    Example

    +

    Examples

    - [example:webgl_depth_texture depth / texture] +

    + [example:webgl_depth_texture depth / texture] +

    Constructor

    [name]( [param:Number width], [param:Number height], [param:Constant type], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Number anisotropy], [param:Constant format] )

    @@ -108,6 +110,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/Texture.html b/docs/api/en/textures/Texture.html index d42c6518d8317a..3d4361eeec579d 100644 --- a/docs/api/en/textures/Texture.html +++ b/docs/api/en/textures/Texture.html @@ -12,12 +12,7 @@

    [name]

    Create a texture to apply to a surface or as a reflection or refraction map.

    - -

    Constructor

    - -

    [name]( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding )

    - -

    Example

    +

    Code Example

    // load a texture, set wrap mode to repeat @@ -27,6 +22,10 @@

    Example

    texture.repeat.set( 4, 4 );
    +

    Constructor

    + +

    [name]( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding )

    +

    Properties

    [property:Integer id]

    @@ -55,13 +54,6 @@

    [property:Image image]

    as long as video is playing - the [page:VideoTexture VideoTexture] class handles this automatically.

    -

    [property:Boolean isTexture]

    -

    - Used to check whether this or derived classes are Textures. Default is *true*.

    - - You should not change this, as it is used internally for optimisation. -

    -

    [property:array mipmaps]

    Array of user-specified mipmaps (optional). @@ -126,6 +118,17 @@

    [property:number format]

    See the [page:Textures texture constants] page for details of other formats.

    +

    [property:String internalFormat]

    +

    + The default value is obtained using a combination of [page:Texture.format .format] and + [page:Texture.type .type].
    + + The GPU format allows the developer to specify how the data is going to be + stored on the GPU.

    + + See the [page:Textures texture constants] page for details regarding all supported internal formats. +

    +

    [property:number type]

    This must correspond to the [page:Texture.format .format]. The default is [page:Textures THREE.UnsignedByteType], @@ -187,7 +190,7 @@

    [property:boolean generateMipmaps]

    [property:boolean premultiplyAlpha]

    - If set to *true*, the alpha channel, if present, is multiplied into the color channels when the texture is uploaded to the GPU. Defaut is *false*.

    + If set to *true*, the alpha channel, if present, is multiplied into the color channels when the texture is uploaded to the GPU. Default is *false*.

    Note that this property has no effect for [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap]. You need to configure on bitmap creation instead. See [page:ImageBitmapLoader]. @@ -270,6 +273,8 @@

    [method:Vector2 transformUv]( [param:Vector2 uv] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/en/textures/VideoTexture.html b/docs/api/en/textures/VideoTexture.html index 18cbe3df6be13c..caabb3252556bf 100644 --- a/docs/api/en/textures/VideoTexture.html +++ b/docs/api/en/textures/VideoTexture.html @@ -18,27 +18,28 @@

    [name]

    This is almost the same as the base [page:Texture Texture] class, except that it continuosly sets [page:Texture.needsUpdate needsUpdate] to *true* so that the texture is updated as the video plays. Automatic creation of [page:Texture.mipmaps mipmaps] is also disabled.

    -

    Example

    - -

    [example:webgl_materials_video materials / video ]

    +

    Code Example

    -//assuming you have created a HTML video element with id="video" -var video = document.getElementById( 'video' ); + //assuming you have created a HTML video element with id="video" + var video = document.getElementById( 'video' ); -var texture = new THREE.VideoTexture( video ); -texture.minFilter = THREE.LinearFilter; -texture.magFilter = THREE.LinearFilter; -texture.format = THREE.RGBFormat; - + var texture = new THREE.VideoTexture( video ); + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.format = THREE.RGBFormat; +
    +

    Examples

    + +

    [example:webgl_materials_video materials / video ]

    Constructor

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Constant format], [param:Constant type], [param:Number anisotropy] )

    [page:Video video] -- The video element to use as the texture.
    - [page:Constant mapping] -- How the image is applied to the object. An object type of [page:Textures THREE.UVMapping]. + [page:Constant mapping] -- How the image is applied to the object. An object type of [page:Textures THREE.UVMapping]. See [page:Textures mapping constants] for other choices.
    [page:Constant wrapS] -- The default is [page:Textures THREE.ClampToEdgeWrapping]. @@ -51,13 +52,13 @@

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS The default is [page:Textures THREE.LinearFilter]. See [page:Textures magnification filter constants] for other choices.
    [page:Constant minFilter] -- How the texture is sampled when a texel covers less than one pixel. - The default is [page:Textures THREE.LinearMipmapLinearFilter]. See [page:Textures minification filter constants] for other choices.
    + The default is [page:Textures THREE.LinearMipmapLinearFilter]. See [page:Textures minification filter constants] for other choices.
    - [page:Constant format] -- The format used in the texture. - See [page:Textures format constants] for other choices.
    + [page:Constant format] -- The format used in the texture. + See [page:Textures format constants] for other choices.
    - [page:Constant type] -- Default is [page:Textures THREE.UnsignedByteType]. - See [page:Textures type constants] for other choices.
    + [page:Constant type] -- Default is [page:Textures THREE.UnsignedByteType]. + See [page:Textures type constants] for other choices.
    [page:Number anisotropy] -- The number of samples taken along the axis through the pixel that has the highest density of texels. By default, this value is 1. A higher value gives a less blurry result than a basic mipmap, at the cost of more texture samples being used. @@ -68,8 +69,8 @@

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS

    Properties

    - See the base [page:Texture Texture] class for common properties. -

    + See the base [page:Texture Texture] class for common properties. +

    [property:boolean needsUpdate]

    @@ -78,19 +79,21 @@

    [property:boolean needsUpdate]

    Methods

    -

    - See the base [page:Texture Texture] class for common methods. -

    +

    + See the base [page:Texture Texture] class for common methods. +

    -

    [method:null update]()

    +

    [method:null update]()

    This is called automatically and sets [property:boolean needsUpdate] to *true* every time - a new frame is available. + a new frame is available.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/Polyfills.html b/docs/api/zh/Polyfills.html index 88ee1e41b22f74..b16a3e471924b2 100644 --- a/docs/api/zh/Polyfills.html +++ b/docs/api/zh/Polyfills.html @@ -41,6 +41,8 @@

    [page:Object.assign Object.assign]( [page:Object target], [page:Object ...so

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/polyfills.js src/polyfills.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/polyfills.js src/polyfills.js] +

    diff --git a/docs/api/zh/Template.html b/docs/api/zh/Template.html index aa44df9badaaef..d0dbbe16ffe67d 100644 --- a/docs/api/zh/Template.html +++ b/docs/api/zh/Template.html @@ -43,6 +43,8 @@

    [method:null todo]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/AnimationAction.html b/docs/api/zh/animation/AnimationAction.html index c1133f3c1da9b3..a8c3cebf3e9017 100644 --- a/docs/api/zh/animation/AnimationAction.html +++ b/docs/api/zh/animation/AnimationAction.html @@ -54,8 +54,8 @@

    [property:Boolean enabled]

    (将 *enabled* 置为 *false* 不会重置此次动作)

    说明: 将*enabled*置为*true*不会让动画自动重新开始。只有满足以下条件时才会马上重新开始: - 暂停([page:.paused paused])值为*false*, 同时动作没有失效 (执行停止([page:.stop stop])命令或重置([page:.reset reset])命令, - 且权重([page:.weight weight])和时间比例([page:.timeScale timeScale])都不能为0 + 暂停([page:.paused paused])值为*false*, 同时动作没有失效 (执行停止([page:.stop stop])命令或重置([page:.reset reset])命令, + 且权重([page:.weight weight])和时间比例([page:.timeScale timeScale])都不能为0

    @@ -64,7 +64,7 @@

    [property:Number loop]

    循环模式 (可以通过[page:.setLoop setLoop]改变)。默认值是 [page:Animation THREE.LoopRepeat] (重复[page:.repetitions repetitions]次数无穷)

    - 必须是以下值之一:

    + 必须是以下值之一:

    [page:Animation THREE.LoopOnce] - 只执行一次
    [page:Animation THREE.LoopRepeat] - 重复次数为*repetitions*的值, 且每次循环结束时候将回到起始动作开始下一次循环。
    [page:Animation THREE.LoopPingPong] - 重复次数为*repetitions*的值, 且像乒乓球一样在起始点与结束点之间来回循环。 @@ -120,12 +120,12 @@

    [property:Number weight]

    [property:Boolean zeroSlopeAtEnd]

    - 启用平滑插值,无须单独剪辑开始、循环和结束。默认值是*true* + 启用平滑插值,无须单独剪辑开始、循环和结束。默认值是*true*

    [property:Boolean zeroSlopeAtStart]

    - 启用平滑插值,无须单独剪辑开始、循环和结束。默认值是*true* + 启用平滑插值,无须单独剪辑开始、循环和结束。默认值是*true*

    @@ -144,7 +144,7 @@

    [method:AnimationAction crossFadeFrom]( [param:AnimationAction fadeOutAction

    [method:AnimationAction crossFadeTo]( [param:AnimationAction fadeInAction], [param:Number durationInSeconds], [param:Boolean warpBoolean] )

    - 在传入的时间段内, 让此动作淡出([page:.fadeOut fade out]),同时让另一个动作淡入。此方法可链式调用。

    + 在传入的时间段内, 让此动作淡出([page:.fadeOut fade out]),同时让另一个动作淡入。此方法可链式调用。

    如果warpBoolean值是true, 额外的 [page:.warp warping] (时间比例的渐变)将会被应用。

    说明: 与 *fadeIn*/*fadeOut*一样, 淡入淡出动作开始/结束时的权重是1. @@ -152,12 +152,12 @@

    [method:AnimationAction crossFadeTo]( [param:AnimationAction fadeInAction],

    [method:AnimationAction fadeIn]( [param:Number durationInSeconds] )

    - 在传入的时间间隔内,逐渐将此动作的权重([page:.weight weight])由0升到1。此方法可链式调用。 + 在传入的时间间隔内,逐渐将此动作的权重([page:.weight weight])由0升到1。此方法可链式调用。

    [method:AnimationAction fadeOut]( [param:Number durationInSeconds] )

    - 在传入的时间间隔内,逐渐将此动作的权重([page:.weight weight])由1降至0。此方法可链式调用。 + 在传入的时间间隔内,逐渐将此动作的权重([page:.weight weight])由1降至0。此方法可链式调用。

    [method:Number getEffectiveTimeScale]()

    @@ -177,7 +177,7 @@

    [method:AnimationClip getClip]()

    [method:AnimationMixer getMixer]()

    - 返回负责完成此动作的混合器 + 返回负责完成此动作的混合器

    [method:Object3D getRoot]()

    @@ -224,7 +224,7 @@

    [method:AnimationAction reset]()

    [page:.time time]设为0, 中断任何预定的淡入淡出和变形, 以及移除内部循环次数以及延迟启动。

    说明: 停止方法[page:.stop stop]内调用了重置方法(reset), 但是 .*reset*不会调用 .*stop*。 - 这就表示: 如果你想要这两者, 重置并且停止, 不要调用*reset*; 而应该调用*stop*。 + 这就表示: 如果你想要这两者, 重置并且停止, 不要调用*reset*; 而应该调用*stop*。

    [method:AnimationAction setDuration]( [param:Number durationInSeconds] )

    @@ -295,7 +295,7 @@

    [method:AnimationAction syncWith]( [param:AnimationAction otherAction] )

    [method:AnimationAction warp]( [param:Number startTimeScale], [param:Number endTimeScale], [param:Number durationInSeconds] )
  • - 在传入的事件间隔内,通过逐渐将时间比例[page:.timeScale timeScale]由*startTimeScale*修改至*endTimeScale*来改变回放速度。该方法可被链式调用。 + 在传入的事件间隔内,通过逐渐将时间比例[page:.timeScale timeScale]由*startTimeScale*修改至*endTimeScale*来改变回放速度。该方法可被链式调用。

    @@ -312,6 +312,8 @@

    事件

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/AnimationClip.html b/docs/api/zh/animation/AnimationClip.html index 6b6f884dff808a..22ddc1d24f8faa 100644 --- a/docs/api/zh/animation/AnimationClip.html +++ b/docs/api/zh/animation/AnimationClip.html @@ -49,7 +49,7 @@

    [property:String name]

    [property:Array tracks]

    - 一个包含该剪辑中有动画的所有属性的关键帧轨道([page:KeyframeTrack])的数组。 + 一个包含该剪辑中有动画的所有属性的关键帧轨道([page:KeyframeTrack])的数组。

    [property:String uuid]

    @@ -67,14 +67,12 @@

    [method:AnimationClip clone]()

    [method:this optimize]()

    - 通过移除等效的顺序键(在变形目标序列中很常见)来优化每一个轨道 - + 通过移除等效的顺序键(在变形目标序列中很常见)来优化每一个轨道

    [method:this resetDuration]()

    将剪辑的持续时间([page:.duration duration])设为最长的关键帧轨道([page:KeyframeTrack])的持续时间。 - .

    [method:this trim]()

    @@ -84,7 +82,7 @@

    [method:this trim]()

    [method:Boolean validate]()

    - 对剪辑中的每个轨道执行最小验证。如果所有轨道都有效,返回true。 + 对剪辑中的每个轨道执行最小验证。如果所有轨道都有效,返回true。

    @@ -99,7 +97,7 @@

    [method:Array CreateClipsFromMorphTargetSequences]( [param:String name], [pa

    [method:AnimationClip CreateFromMorphTargetSequence]( [param:String name], [param:Array morphTargetSequence], [param:Number fps], [param:Boolean noLoop] )

    - 返回一个由几何体变形目标数组([page:Geometry.morphTargets morph targets array])得到的新动画剪辑,接收名称和帧率参数。

    + 返回一个由几何体变形目标数组([page:Geometry.morphTargets morph targets array])得到的新动画剪辑,接收名称和帧率参数。

    说明: 帧率是必须参数, 但是动画速度可能会在*AnimationAction*中被[page:AnimationAction.setDuration animationAction.setDuration]方法重写。 @@ -117,7 +115,7 @@

    [method:AnimationClip parse]( [param:Object json] )

    [method:AnimationClip parseAnimation]( [param:Object animation], [param:Array bones] )

    - 解析动画层级格式并返回动画剪辑。 + 解析动画层级格式并返回动画剪辑。

    [method:Object toJSON]( [param:AnimationClip clip] )

    @@ -129,6 +127,8 @@

    [method:Object toJSON]( [param:AnimationClip clip] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/AnimationMixer.html b/docs/api/zh/animation/AnimationMixer.html index 5f7c3b29809e28..151cf78b2b3453 100644 --- a/docs/api/zh/animation/AnimationMixer.html +++ b/docs/api/zh/animation/AnimationMixer.html @@ -11,7 +11,7 @@

    [name]

    - 动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。

    + 动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。

    在使用手册的“下一步”章节中,“动画系统”一文对three.js动画系统中的不同元素作出了概述

    @@ -41,6 +41,13 @@

    [property:Number timeScale]

    说明: 将混合器的时间比例设为0, 稍后再设置为1,可以暂停/取消暂停由该混合器控制的所有动作。

    +

    [method:AnimationMixer setTime]([param:Number timeInSeconds])

    +

    + 设置全局混合器到一个给定的时间,并相应地更新动画。

    + + 当你需要在一个动画里跳转到一个精确的时间,该函数将是十分有用的。输入的参数将会被混合器的[page:.timeScale timeScale]进行缩放。 +

    +

    方法

    @@ -96,6 +103,8 @@

    [method:null uncacheAction]([param:AnimationClip clip], [param:Object3D opti

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/AnimationObjectGroup.html b/docs/api/zh/animation/AnimationObjectGroup.html index 752cf26920f697..84ac60db5693e6 100644 --- a/docs/api/zh/animation/AnimationObjectGroup.html +++ b/docs/api/zh/animation/AnimationObjectGroup.html @@ -18,10 +18,10 @@

    [name]

    用法:

    - 将本来要作为根对象传入构造器或者动画混合器([page:AnimationMixer AnimationMixer])的[page:AnimationMixer.clipAction clipAction]方法中的对象加入组中,并将这个组对象作为根对象传递。 + 将本来要作为根对象传入构造器或者动画混合器([page:AnimationMixer AnimationMixer])的[page:AnimationMixer.clipAction clipAction]方法中的对象加入组中,并将这个组对象作为根对象传递。

    - 注意,这个类的实例作为混合器中的一个对象,因此,必须对组内的单个对象做缓存控制。 + 注意,这个类的实例作为混合器中的一个对象,因此,必须对组内的单个对象做缓存控制。

    @@ -35,10 +35,10 @@

    限制

    构造器

    -

    [name]( [param:object obj1], [param:object obj2], [param:object obj3], ... )

    - [page:object obj] - 共享同一动画状态的任意数量的网格
    - +

    + [page:object obj] - 共享同一动画状态的任意数量的网格 +

    属性

    @@ -77,6 +77,8 @@

    [method:null uncache]( [param:object obj1], [param:object obj2], [param:obje

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/AnimationUtils.html b/docs/api/zh/animation/AnimationUtils.html index 488e558ed0f3b2..4506306a63b776 100644 --- a/docs/api/zh/animation/AnimationUtils.html +++ b/docs/api/zh/animation/AnimationUtils.html @@ -11,7 +11,7 @@

    [name]

    - 一个提供各种动画辅助方法的对象,内部使用。 + 一个提供各种动画辅助方法的对象,内部使用。

    @@ -25,17 +25,17 @@

    [method:Array arraySlice]( array, from, to )

    [method:Array convertArray]( array, type, forceClone )

    - 将数组转换为某种特定类型。 + 将数组转换为某种特定类型。

    [method:Array flattenJSON]( jsonKeys, times, values, valuePropertyName )

    - 用于解析AOS关键帧格式。 + 用于解析AOS关键帧格式。

    [method:Array getKeyframeOrder]( times )

    - 返回一个数组,时间和值可以根据此数组排序。 + 返回一个数组,时间和值可以根据此数组排序。

    [method:Number insertKeyframe]( [param:KeyframeTrack track], [param:Number time] )

    @@ -43,7 +43,7 @@

    [method:Number insertKeyframe]( [param:KeyframeTrack track], [param:Number t

    [method:Boolean isTypedArray]( object )

    - 如果该对象是类型化数组,返回*true* + 如果该对象是类型化数组,返回*true*

    @@ -52,14 +52,19 @@

    [method:AnimationClip mergeMorphTargetTracks]( [param:AnimationClip clip], [

    [method:Array sortedArray]( values, stride, order )

    - 将[page:AnimationUtils.getKeyframeOrder getKeyframeOrder]方法返回的数组排序。 - + 将[page:AnimationUtils.getKeyframeOrder getKeyframeOrder]方法返回的数组排序。

    +

    [method:AnimationClip subclip]( [param:AnimationClip clip], [param:String name], [param:Number startFrame], [param:Number endFrame], [param:Number fps] )

    +

    + 创建一个新的片段,仅包含所给定帧之间的原始剪辑片段。 +

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/KeyframeTrack.html b/docs/api/zh/animation/KeyframeTrack.html index 92bfcd6f586389..8dd320e5b27945 100644 --- a/docs/api/zh/animation/KeyframeTrack.html +++ b/docs/api/zh/animation/KeyframeTrack.html @@ -17,26 +17,26 @@

    [name]

    - 在使用手册的“下一步”章节中,“动画系统”一文对three.js动画系统中的不同元素作出了概述 + 在使用手册的“下一步”章节中,“动画系统”一文对three.js动画系统中的不同元素作出了概述

    - 和[link:https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3 JSON model format]的动画层级相反, - 关键帧轨道(KeyframeTrack)不会将单帧作为对象存储在“key”数组(一个存有每一帧的时间和值的地方)中。 + 和[link:https://github.com/mrdoob/three.js/wiki/JSON-Model-format-3 JSON model format]的动画层级相反, + 关键帧轨道(KeyframeTrack)不会将单帧作为对象存储在“key”数组(一个存有每一帧的时间和值的地方)中。

    - 关键帧轨道(KeyframeTrack)中总是存在两个数组:[page:.times times]数组按顺序存储该轨道的所有关键帧的时间值,而[page:.values values]数组包含动画属性的相应更改值。 + 关键帧轨道(KeyframeTrack)中总是存在两个数组:[page:.times times]数组按顺序存储该轨道的所有关键帧的时间值,而[page:.values values]数组包含动画属性的相应更改值。

    - 值数组中的每一个成员,属于某一特定时间点,不仅可以是一个简单的数字,还可以是(比如)一个向量(如果是位置动画)或者是一个四元数(如果是旋转动画)。 - 因此,值数组(也是一个平面阵列)的长度可能是时间数组的三四倍。 + 值数组中的每一个成员,属于某一特定时间点,不仅可以是一个简单的数字,还可以是(比如)一个向量(如果是位置动画)或者是一个四元数(如果是旋转动画)。 + 因此,值数组(也是一个平面阵列)的长度可能是时间数组的三四倍。

    - 与不同类型的动画值对应,存在若干关键帧轨道(KeyframeTrack)的子类,继承了它大多数属性和方法: + 与不同类型的动画值对应,存在若干关键帧轨道(KeyframeTrack)的子类,继承了它大多数属性和方法:

      @@ -49,15 +49,15 @@

      [name]

    - 可以在[link:https://threejs.org/examples/js/animation/AnimationClipCreator.js AnimationClipCreator]文件中找到用不同类型的关键帧轨道创建动画剪辑([page:AnimationClip AnimationClips])的示例。 + 可以在[link:https://threejs.org/examples/jsm/animation/AnimationClipCreator.js AnimationClipCreator]文件中找到用不同类型的关键帧轨道创建动画剪辑([page:AnimationClip AnimationClips])的示例。

    - 由于显式值仅针对存储在时间数组中的离散时间点指定,因此必须在两个时间点之间进行插值 + 由于显式值仅针对存储在时间数组中的离散时间点指定,因此必须在两个时间点之间进行插值

    - 轨道的名称对于这个轨道与动画节点的特定属性的连接(由[page:PropertyBinding]完成)很重要。 + 轨道的名称对于这个轨道与动画节点的特定属性的连接(由[page:PropertyBinding]完成)很重要。

    @@ -81,11 +81,11 @@

    属性

    [property:String name]

    - 轨道的名称可以指动画对象中的变形目标([page:Geometry.morphTargets morph targets])、骨骼([page:SkinnedMesh bones])或可能的其他值 + 轨道的名称可以指动画对象中的变形目标([page:Geometry.morphTargets morph targets])、骨骼([page:SkinnedMesh bones])或可能的其他值 查看[page:PropertyBinding.parseTrackName]可获知哪些形式的字符串可以解析出绑定的属性:

    - 可以使用节点名称或uuid(尽管它需要位于传递到混合器的场景图节点的子树中)引用到某节点。或者, 如果轨道名称的首字符是点, + 可以使用节点名称或uuid(尽管它需要位于传递到混合器的场景图节点的子树中)引用到某节点。或者, 如果轨道名称的首字符是点, 该轨道会应用到传入到混合器的根节点上。

    @@ -94,7 +94,7 @@

    [property:String name]

    - 还可以使用对象名称来指定骨骼或多材质,例如:.bones[R_hand].scale;再比如,材料数组中的第四个材料的漫反射颜色的红通道可以通过 .materials[3].diffuse[r]访问到。 + 还可以使用对象名称来指定骨骼或多材质,例如:.bones[R_hand].scale;再比如,材料数组中的第四个材料的漫反射颜色的红通道可以通过 .materials[3].diffuse[r]访问到。

    @@ -159,30 +159,30 @@

    [method:Number getValueSize]()

    [method:DiscreteInterpolant InterpolantFactoryMethodDiscrete]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    - 根据时间([page:KeyframeTrack.times times])和值([page:KeyframeTrack.times values])创建一个新的离散插值([page:DiscreteInterpolant DiscreteInterpolant])。 - 可传入一个Float32Array类型的变量来接收结果, 否则会自动创建一个长度适宜的新数组。 + 根据时间([page:KeyframeTrack.times times])和值([page:KeyframeTrack.times values])创建一个新的离散插值([page:DiscreteInterpolant DiscreteInterpolant])。 + 可传入一个Float32Array类型的变量来接收结果, 否则会自动创建一个长度适宜的新数组。

    [method:null InterpolantFactoryMethodLinear]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    - 根据时间([page:KeyframeTrack.times times])和值([page:KeyframeTrack.times values])创建一个新的线性插值([page:LinearInterpolant LinearInterpolant])。 - 可传入一个Float32Array类型的变量来接收结果, 否则会自动创建一个长度适宜的新数组。 + 根据时间([page:KeyframeTrack.times times])和值([page:KeyframeTrack.times values])创建一个新的线性插值([page:LinearInterpolant LinearInterpolant])。 + 可传入一个Float32Array类型的变量来接收结果, 否则会自动创建一个长度适宜的新数组。

    [method:null InterpolantFactoryMethodSmooth]( [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array result] )

    - 根据时间([page:KeyframeTrack.times times])和值([page:KeyframeTrack.times values])创建一个新的立方插值([page:CubicInterpolant CubicInterpolant])。 - 可传入一个Float32Array类型的变量来接收结果, 否则会自动创建一个长度适宜的新数组。 + 根据时间([page:KeyframeTrack.times times])和值([page:KeyframeTrack.times values])创建一个新的立方插值([page:CubicInterpolant CubicInterpolant])。 + 可传入一个Float32Array类型的变量来接收结果, 否则会自动创建一个长度适宜的新数组。

    [method:this optimize]()

    - 删除等效的顺序键,这些键在变形目标序列中很常见。 + 删除等效的顺序键,这些键在变形目标序列中很常见。

    [method:this scale]()

    - 缩放所有关键帧的时间。

    + 缩放所有关键帧的时间。

    说明: 这个方法很有用,例如, 可用于转化为某一特定帧率(正如[page:AnimationClip.CreateFromMorphTargetSequence animationClip.CreateFromMorphTargetSequence]内部所做的一样)。

    @@ -194,7 +194,7 @@

    [method:this setInterpolation]( [param:Constant interpolationType] )

    [method:this shift]( [param:Number timeOffsetInSeconds] )

    - 及时删除之前或之后的所有关键帧。 + 及时删除之前或之后的所有关键帧。

    @@ -205,7 +205,7 @@

    [method:this trim]( [param:Number startTimeInSeconds], [param:Number endTime

    [method:Boolean validate]()

    - 在轨道上执行最小验证,有效则返回true + 在轨道上执行最小验证,有效则返回true

    @@ -217,18 +217,20 @@

    静态方法

    [method:KeyframeTrack parse]( [param:JSON json] )

    - 解析JSON对象并返回一个正确类型的新关键帧轨道。 + 解析JSON对象并返回一个正确类型的新关键帧轨道。

    [method:JSON toJSON]( [param:KeyframeTrack track] )

    - 将该轨道转化为JSON + 将该轨道转化为JSON

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/PropertyBinding.html b/docs/api/zh/animation/PropertyBinding.html index fc5b6218577481..61d019a4a165c2 100644 --- a/docs/api/zh/animation/PropertyBinding.html +++ b/docs/api/zh/animation/PropertyBinding.html @@ -11,7 +11,7 @@

    [name]

    - 对场景图中某一真实属性的引用,内部使用。 + 对场景图中某一真实属性的引用,内部使用。

    @@ -97,7 +97,7 @@

    [method:Constructor Composite]( targetGroup, path, optionalParsedPath )

    [method:Constructor create]( root, path, parsedPath )

    - 创建一个新的复合属性绑定(Composite PropertyBinding) (如果根对象是[page:AnimationObjectGroup])或普通属性绑定 + 创建一个新的复合属性绑定(Composite PropertyBinding) (如果根对象是[page:AnimationObjectGroup])或普通属性绑定

    [method:Constructor parseTrackName]( trackName )

    @@ -116,7 +116,7 @@

    [method:Constructor parseTrackName]( trackName )

    [method:Constructor findNode]( root, nodeName )

    - 从节点树或骨骼([page:Skeleton Skeleton])中找出某节点 + 从节点树或骨骼([page:Skeleton Skeleton])中找出某节点

    @@ -125,6 +125,8 @@

    [method:Constructor findNode]( root, nodeName )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/PropertyMixer.html b/docs/api/zh/animation/PropertyMixer.html index 6759a6620e97a2..f4d9d5df866209 100644 --- a/docs/api/zh/animation/PropertyMixer.html +++ b/docs/api/zh/animation/PropertyMixer.html @@ -11,7 +11,7 @@

    [name]

    - 允许加权累加的缓冲场景图属性,内部使用 + 允许加权累加的缓冲场景图属性,内部使用

    @@ -54,12 +54,12 @@

    [property:Number valueSize]

    [property:Number referenceCount]

    - 默认值是0 + 默认值是0

    [property:Number useCount]

    - 默认值是0 + 默认值是0

    @@ -85,13 +85,15 @@

    [method:null saveOriginalState]( )

    [method:null restoreOriginalState]( )

    - 将预先通过'saveOriginalState'方法取得的状态应用于绑定。 + 将预先通过'saveOriginalState'方法取得的状态应用于绑定。

    方法

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/tracks/BooleanKeyframeTrack.html b/docs/api/zh/animation/tracks/BooleanKeyframeTrack.html index a7fd810abd553d..bfc34d4e7cc23e 100644 --- a/docs/api/zh/animation/tracks/BooleanKeyframeTrack.html +++ b/docs/api/zh/animation/tracks/BooleanKeyframeTrack.html @@ -73,6 +73,8 @@

    [method:null InterpolantFactoryMethodSmooth ]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/tracks/ColorKeyframeTrack.html b/docs/api/zh/animation/tracks/ColorKeyframeTrack.html index 12153fae364051..e31893fc31332f 100644 --- a/docs/api/zh/animation/tracks/ColorKeyframeTrack.html +++ b/docs/api/zh/animation/tracks/ColorKeyframeTrack.html @@ -56,6 +56,8 @@

    Methods

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/tracks/NumberKeyframeTrack.html b/docs/api/zh/animation/tracks/NumberKeyframeTrack.html index eb185a5d764af3..21c07bc86f020f 100644 --- a/docs/api/zh/animation/tracks/NumberKeyframeTrack.html +++ b/docs/api/zh/animation/tracks/NumberKeyframeTrack.html @@ -57,6 +57,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/tracks/QuaternionKeyframeTrack.html b/docs/api/zh/animation/tracks/QuaternionKeyframeTrack.html index 2aa22ca82a419e..565a9cfd0c914e 100644 --- a/docs/api/zh/animation/tracks/QuaternionKeyframeTrack.html +++ b/docs/api/zh/animation/tracks/QuaternionKeyframeTrack.html @@ -69,6 +69,8 @@

    [method:null InterpolantFactoryMethodLinear]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/tracks/StringKeyframeTrack.html b/docs/api/zh/animation/tracks/StringKeyframeTrack.html index ece3f185b0c9c1..19aca3bf961cc6 100644 --- a/docs/api/zh/animation/tracks/StringKeyframeTrack.html +++ b/docs/api/zh/animation/tracks/StringKeyframeTrack.html @@ -76,6 +76,8 @@

    [method:null InterpolantFactoryMethodSmooth]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/animation/tracks/VectorKeyframeTrack.html b/docs/api/zh/animation/tracks/VectorKeyframeTrack.html index 8b667feecd9c2c..e73b820d6756dd 100644 --- a/docs/api/zh/animation/tracks/VectorKeyframeTrack.html +++ b/docs/api/zh/animation/tracks/VectorKeyframeTrack.html @@ -56,6 +56,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/audio/Audio.html b/docs/api/zh/audio/Audio.html index 39fde92b9bf883..9acf877342f2c5 100644 --- a/docs/api/zh/audio/Audio.html +++ b/docs/api/zh/audio/Audio.html @@ -18,13 +18,7 @@

    [name]

    使用 [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API].

    - -

    例子

    - -

    - [example:webaudio_sandbox webaudio / sandbox ]
    - [example:webaudio_visualizer webaudio / visualizer ] -

    +

    代码示例

    // create an AudioListener and add it to the camera @@ -44,6 +38,12 @@

    例子

    });
    +

    例子

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    构造函数

    @@ -84,12 +84,12 @@

    [property:Boolean isPlaying]

    [property:AudioListener listener]

    A reference to the listener object of this audio.

    -

    [property:Number startTime]

    -

    开始播放的时间. 和[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start]()的*when*参数一样. 默认为 *0*.

    -

    [property:Number offset]

    音频开始播放的偏移时间. 和[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start]()的*offset*参数一样. 默认为 *0*.

    +

    [property:Number duration]

    +

    覆盖音频的持续时间。与[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start]()中的*duration*属性相同。默认为*undefined*,以用于播放整个buffer。

    +

    [property:String source]

    使用 [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource AudioContext.createBufferSource]()创建的[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode AudioBufferSourceNode].

    @@ -143,7 +143,7 @@

    [method:Float getVolume]( value )

    返回音量.

    -

    [method:Audio play]()

    +

    [method:Audio play]( delay )

    如果[page:Audio.hasPlaybackControl hasPlaybackControl]是true, 开始播放.

    @@ -155,7 +155,7 @@

    [method:Audio pause]()

    [method:null onEnded]()

    - 播放完成后自动调用. 如果[page:Audio.isPlaying isPlaying]设置为false. + 播放完成后自动调用.

    [method:Audio setBuffer]( audioBuffer )

    @@ -177,15 +177,30 @@

    [method:Audio setFilters]( [param:Array value] )

    [method:Audio setLoop]( [param:Boolean value] )

    - 设置[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop] 的值 + 设置[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop source.loop]的值 (是否循环播放).

    +

    [method:Audio setLoopStart]( [param:Float value] )

    +

    + 设置[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart source.loopStart]的值 +

    + +

    [method:Audio setLoopEnd]( [param:Float value] )

    +

    + 设置[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd source.loopEnd]的值 +

    +

    [method:Audio setMediaElementSource]( mediaElement )

    - 应用[link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement]类型对象作为音源.
    - 并且设置[page:Audio.hasPlaybackControl hasPlaybackControl]为false. + 应用传入的[link:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement HTMLMediaElement]类型对象作为音源。
    + 并且设置[page:Audio.hasPlaybackControl hasPlaybackControl]为false。 +

    +

    [method:Audio setMediaStreamSource]( mediaStream )

    +

    + 应用传入的[link:https://developer.mozilla.org/en-US/docs/Web/API/MediaStream MediaStream]类型对象作为音源。
    + 并且设置[page:Audio.hasPlaybackControl hasPlaybackControl]为false。

    [method:Audio setNodeSource]( audioNode )

    @@ -207,12 +222,13 @@

    [method:Audio setVolume]( [param:Float value] )

    [method:Audio stop]()

    - 如果[page:Audio.hasPlaybackControl hasPlaybackControl]是true, 停止播放, - 重新设置[page:Audio.startTime startTime]为 *0* 和 设置 [page:Audio.isPlaying isPlaying]为false. + 如果[page:Audio.hasPlaybackControl hasPlaybackControl]是true, 停止播放.

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/audio/AudioAnalyser.html b/docs/api/zh/audio/AudioAnalyser.html index e91f5f9acf1888..4cb36276836fc3 100644 --- a/docs/api/zh/audio/AudioAnalyser.html +++ b/docs/api/zh/audio/AudioAnalyser.html @@ -18,13 +18,7 @@

    [name]

    - -

    示例

    - -

    - [example:webaudio_sandbox webaudio / sandbox ]
    - [example:webaudio_visualizer webaudio / visualizer ] -

    +

    代码示例

    // create an AudioListener and add it to the camera @@ -50,6 +44,12 @@

    示例

    var data = analyser.getAverageFrequency();
    +

    例子

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    构造函数

    @@ -94,6 +94,8 @@

    [method:Number getAverageFrequency]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/audio/AudioContext.html b/docs/api/zh/audio/AudioContext.html index a7557185e94246..3cfae44e350a71 100644 --- a/docs/api/zh/audio/AudioContext.html +++ b/docs/api/zh/audio/AudioContext.html @@ -37,6 +37,8 @@

    [method:AudioContext setContext]( [param:AudioConetxt value] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/audio/AudioListener.html b/docs/api/zh/audio/AudioListener.html index 2f4c6adbea029e..397d55ee51f9f9 100644 --- a/docs/api/zh/audio/AudioListener.html +++ b/docs/api/zh/audio/AudioListener.html @@ -18,14 +18,7 @@

    [name]

    大多数情况下, listener对象是camera的子对象. Camera的3D变换表示了listener的3D变换.

    - -

    示例

    - -

    - [example:webaudio_sandbox webaudio / sandbox ]
    - [example:webaudio_timing webaudio / timing ]
    - [example:webaudio_visualizer webaudio / visualizer ] -

    +

    代码示例

    // create an AudioListener and add it to the camera @@ -45,6 +38,13 @@

    示例

    });
    +

    例子

    + +

    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ]
    + [example:webaudio_visualizer webaudio / visualizer ] +

    构造函数

    @@ -105,6 +105,8 @@

    [method:AudioListener setMasterVolume]( [param:Number value] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/audio/PositionalAudio.html b/docs/api/zh/audio/PositionalAudio.html index 650eb0cc3f2eda..11a8a76f37aa2c 100644 --- a/docs/api/zh/audio/PositionalAudio.html +++ b/docs/api/zh/audio/PositionalAudio.html @@ -18,14 +18,7 @@

    [name]

    使用了[link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API Web Audio API].

    - -

    示例

    - -

    - [example:webaudio_orientation webaudio / orientation ]
    - [example:webaudio_sandbox webaudio / sandbox ]
    - [example:webaudio_timing webaudio / timing ] -

    +

    代码示例

    // create an AudioListener and add it to the camera @@ -44,7 +37,7 @@

    示例

    }); // create an object for the sound to play from - var sphere = new THREE.SphereGeometry( 20, 32, 16 ); + var sphere = new THREE.SphereBufferGeometry( 20, 32, 16 ); var material = new THREE.MeshPhongMaterial( { color: 0xff2200 } ); var mesh = new THREE.Mesh( sphere, material ); scene.add( mesh ); @@ -53,6 +46,13 @@

    示例

    mesh.add( sound );
    +

    例子

    + +

    + [example:webaudio_orientation webaudio / orientation ]
    + [example:webaudio_sandbox webaudio / sandbox ]
    + [example:webaudio_timing webaudio / timing ] +

    构造函数

    @@ -130,6 +130,8 @@

    [method:PositionalAudio setDirectionalCone]( [param:Float coneInnerAngle], [

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/cameras/ArrayCamera.html b/docs/api/zh/cameras/ArrayCamera.html index 86010c43740012..c83985bb01ccd4 100644 --- a/docs/api/zh/cameras/ArrayCamera.html +++ b/docs/api/zh/cameras/ArrayCamera.html @@ -8,7 +8,7 @@ - [page:PerspectiveCamera] → + [page:Object3D] → [page:Camera] → [page:PerspectiveCamera] →

    摄像机阵列([name])

    @@ -18,7 +18,7 @@

    摄像机阵列([name])

    一个 [name] 的实例中总是包含着一组子摄像机,应当为每一个子摄像机定义*viewport*(视口)这个属性,这一属性决定了由该子摄像机所渲染的视口区域的大小。

    -

    示例

    +

    例子

    [example:webgl_camera_array camera / array ]

    @@ -43,6 +43,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/cameras/Camera.html b/docs/api/zh/cameras/Camera.html index 487564902c4e03..1898cfd99fd4df 100644 --- a/docs/api/zh/cameras/Camera.html +++ b/docs/api/zh/cameras/Camera.html @@ -33,15 +33,6 @@

    属性

    共有属性请参见其基类[page:Object3D]

    -

    [property:Boolean isCamera]

    -

    - 用于来检查这个类或者派生的类是否为摄像机,默认为*true*。 -

    - - 你不应当对这个属性进行改变,因为它在内部由渲染器使用,以用于优化。 - -

    -

    [property:Layers layers]

    @@ -90,6 +81,8 @@

    [method:Vector3 getWorldDirection]( [param:Vector3 target] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/cameras/CubeCamera.html b/docs/api/zh/cameras/CubeCamera.html index 9c47356f626763..8f8631ed40bdfb 100644 --- a/docs/api/zh/cameras/CubeCamera.html +++ b/docs/api/zh/cameras/CubeCamera.html @@ -13,13 +13,9 @@

    立方相机([name])

    -

    创建6个摄像机,并将它们所拍摄的场景渲染到[page:WebGLRenderTargetCube]上。

    +

    创建6个摄像机,并将它们所拍摄的场景渲染到[page:WebGLCubeRenderTarget]上。

    -

    示例

    - -

    [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]

    -

    [example:webgl_materials_cubemap_dynamic2 materials / cubemap / dynamic2 ]

    -

    [example:webgl_shading_physical shading / physical ]

    +

    代码示例

    // Create cube camera var cubeCamera = new THREE.CubeCamera( 1, 100000, 128 ); @@ -40,7 +36,13 @@

    示例

    renderer.render( scene, camera );
    +

    例子

    +

    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
    + [example:webgl_materials_cubemap_dynamic2 materials / cubemap / dynamic2 ]
    + [example:webgl_shading_physical shading / physical ] +

    构造器

    @@ -49,12 +51,12 @@

    构造器

    [name]( [param:Number near], [param:Number far], [param:Number cubeResolution] )

    - near -- 远剪切面的距离
    - far -- 近剪切面的距离
    + near -- 近剪切面的距离
    + far -- 远剪切面的距离
    cubeResolution -- 设置立方体边缘的长度

    - 构造一个包含6个[page:PerspectiveCamera PerspectiveCameras](透视摄像机)的立方摄像机,并将其拍摄的场景渲染到一个[page:WebGLRenderTargetCube]上。 + 构造一个包含6个[page:PerspectiveCamera PerspectiveCameras](透视摄像机)的立方摄像机,并将其拍摄的场景渲染到一个[page:WebGLCubeRenderTarget]上。

    @@ -62,7 +64,7 @@

    [name]( [param:Number near], [param:Number far], [param:Number cubeResolutio

    属性

    共有属性请参见其基类[page:Object3D]。

    -

    [property:WebGLRenderTargetCube renderTarget]

    +

    [property:WebGLCubeRenderTarget renderTarget]

    生成的立方体纹理
    (译注:生成的立方体纹理保存在其中的.texture对象中,可作为贴图赋值给其他材质) @@ -91,6 +93,8 @@

    [method:null clear]( [param:WebGLRenderer renderer], [param:Boolean color],

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/cameras/OrthographicCamera.html b/docs/api/zh/cameras/OrthographicCamera.html index 04ee937dce9aef..bff1ea33aa63ba 100644 --- a/docs/api/zh/cameras/OrthographicCamera.html +++ b/docs/api/zh/cameras/OrthographicCamera.html @@ -22,25 +22,26 @@

    正交相机([name])

    这对于渲染2D场景或者UI元素是非常有用的。

    +

    代码示例

    -

    示例

    - -

    [example:canvas_camera_orthographic camera / orthographic ]

    -

    [example:webgl_camera camera ]

    -

    [example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]

    -

    [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]

    -

    [example:webgl_postprocessing_advanced postprocessing / advanced ]

    -

    [example:webgl_postprocessing_dof2 postprocessing / dof2 ]

    -

    [example:webgl_postprocessing_godrays postprocessing / godrays ]

    -

    [example:webgl_rtt rtt ]

    -

    [example:webgl_shaders_tonemapping shaders / tonemapping ]

    -

    [example:webgl_shadowmap shadowmap ]

    -

    [example:webgl_terrain_dynamic terrain / dynamic ]

    - - var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); -scene.add( camera ); + + var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 ); + scene.add( camera ); + +

    例子

    +

    + [example:webgl_camera camera ]
    + [example:webgl_interactive_cubes_ortho interactive / cubes / ortho ]
    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
    + [example:webgl_postprocessing_advanced postprocessing / advanced ]
    + [example:webgl_postprocessing_dof2 postprocessing / dof2 ]
    + [example:webgl_postprocessing_godrays postprocessing / godrays ]
    + [example:webgl_rtt rtt ]
    + [example:webgl_shaders_tonemapping shaders / tonemapping ]
    + [example:webgl_shadowmap shadowmap ] +

    构造器

    @@ -78,12 +79,6 @@

    [property:Float far]

    -

    [property:Boolean isOrthographicCamera]

    -

    - 用于测试这个类或者派生类是否为OrthographicCameras,默认为*true*。

    - 你不应当对这个属性进行改变,因为它在内部由渲染器使用,以用于优化。 -

    -

    [property:Float left]

    摄像机视锥体左侧面。

    @@ -147,6 +142,8 @@

    [method:Object toJSON]([param:object meta])

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/cameras/PerspectiveCamera.html b/docs/api/zh/cameras/PerspectiveCamera.html index 5a45b8f22b5e2f..25bb09d5c7be0f 100644 --- a/docs/api/zh/cameras/PerspectiveCamera.html +++ b/docs/api/zh/cameras/PerspectiveCamera.html @@ -19,20 +19,22 @@

    透视相机([name])

    +

    代码示例

    -

    示例

    + + var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); + scene.add( camera ); + -

    [example:canvas_geometry_birds geometry / birds ]

    -

    [example:canvas_geometry_cube geometry / cube ]

    -

    [example:webgl_animation_skinning_blending animation / skinning / blending ]

    -

    [example:webgl_animation_skinning_morph animation / skinning / blending ]

    -

    [example:webgl_effects_stereo effects / stereo ]

    -

    [example:webgl_interactive_cubes interactive / cubes ]

    -

    [example:webgl_loader_collada_skinning loader / collada / skinning ]

    - - var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); -scene.add( camera ); +

    例子

    +

    + [example:webgl_animation_skinning_blending animation / skinning / blending ]
    + [example:webgl_animation_skinning_morph animation / skinning / blending ]
    + [example:webgl_effects_stereo effects / stereo ]
    + [example:webgl_interactive_cubes interactive / cubes ]
    + [example:webgl_loader_collada_skinning loader / collada / skinning ] +

    构造器

    @@ -79,15 +81,6 @@

    [property:Float focus]

    [property:Float fov]

    摄像机视锥体垂直视野角度,从视图的底部到顶部,以角度来表示。默认值是*50*。

    -

    [property:Boolean isPerspectiveCamera]

    -

    - - 用于测试这个类或者派生类是否为PerspectiveCameras,默认为true。 -

    - - 你不应当对这个属性进行改变,因为它在内部由渲染器使用,以用于优化。 -

    -

    [property:Float near]

    @@ -195,6 +188,8 @@

    [method:Object toJSON]([param:object meta])

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/cameras/StereoCamera.html b/docs/api/zh/cameras/StereoCamera.html index c71dbc9d4dfb13..f08486ff8dd286 100644 --- a/docs/api/zh/cameras/StereoCamera.html +++ b/docs/api/zh/cameras/StereoCamera.html @@ -16,21 +16,14 @@

    立体相机([name])

    - -

    示例

    - -

    [example:webgl_effects_anaglyph effects / anaglyph ]

    -

    [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]

    -

    [example:webgl_effects_stereo effects / stereo ]

    +

    例子

    - 这些类在以上示例中的文件内部使用:

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/AnaglyphEffect.js examples/js/effects/AnaglyphEffect.js]

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/ParallaxBarrierEffect.js examples/js/effects/ParallaxBarrierEffect.js]

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/effects/StereoEffect.js examples/js/effects/StereoEffect.js]

    + [example:webgl_effects_anaglyph effects / anaglyph ]
    + [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
    + [example:webgl_effects_stereo effects / stereo ]

    -

    构造器

    [name]( )

    @@ -58,6 +51,8 @@

    [method:null update]( [param:PerspectiveCamera camera] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/constants/Animation.html b/docs/api/zh/constants/Animation.html index c87cf01763ce9e..58f45a17fc3cbd 100644 --- a/docs/api/zh/constants/Animation.html +++ b/docs/api/zh/constants/Animation.html @@ -11,29 +11,31 @@

    动画常量(Animation Constants)

    循环模式

    - + THREE.LoopOnce THREE.LoopRepeat THREE.LoopPingPong -

    插值模式

    - +

    插值模式

    + THREE.InterpolateDiscrete THREE.InterpolateLinear THREE.InterpolateSmooth - +
    -

    结束模式

    - +

    结束模式

    + THREE.ZeroCurvatureEnding THREE.ZeroSlopeEnding THREE.WrapAroundEnding - +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    diff --git a/docs/api/zh/constants/Core.html b/docs/api/zh/constants/Core.html index 4f097fc50b7190..8718d33c78ced2 100644 --- a/docs/api/zh/constants/Core.html +++ b/docs/api/zh/constants/Core.html @@ -20,16 +20,18 @@

    修订版本号

    当前three.js的修订版本号( [link:https://github.com/mrdoob/three.js/releases revision number])。 -

    鼠标按钮

    - +

    鼠标按钮

    + THREE.MOUSE.LEFT THREE.MOUSE.MIDDLE THREE.MOUSE.RIGHT - +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    diff --git a/docs/api/zh/constants/CustomBlendingEquations.html b/docs/api/zh/constants/CustomBlendingEquations.html index 2fcfb79fe36928..8b9158dfc31bde 100644 --- a/docs/api/zh/constants/CustomBlendingEquations.html +++ b/docs/api/zh/constants/CustomBlendingEquations.html @@ -10,15 +10,12 @@

    自定义混合方程常量(Custom Blending Equation Constants)

    - -

    示例

    -

    [example:webgl_materials_blending_custom materials / blending / custom ]

    - -

    用法

    这个常量可以用于所有的材质类型。首先将材质的混合模式设置为THREE.CustomBlending,然后设置所需要的混合方程、源因子和目标因子。

    +

    代码示例

    + var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); material.blending = THREE.CustomBlending; @@ -27,6 +24,9 @@

    用法

    material.blendDst = THREE.OneMinusSrcAlphaFactor; //default
    +

    例子

    +

    [example:webgl_materials_blending_custom materials / blending / custom ]

    +

    混合方程

    THREE.AddEquation @@ -58,6 +58,8 @@

    目标因子

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    diff --git a/docs/api/zh/constants/DrawModes.html b/docs/api/zh/constants/DrawModes.html deleted file mode 100644 index 3e32e2994b5e6b..00000000000000 --- a/docs/api/zh/constants/DrawModes.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - -

    绘图模式常量(Draw Mode Constants)

    - -

    - 这些是[page:Mesh.drawMode]的有效值,控制着顶点列表一旦被发送到GPU中将如何被解释。 - 请注意,只有当[page:Mesh.geometry]是一个[page:BufferGeometry]的时候,这些值才会生效。当[page:Mesh.geometry]是一个 - [page:Geometry]的时候,改变这个值不会有任何效果。 -

    - - - -

    - - -

    绘图模式

    - - - THREE.TrianglesDrawMode - -

    - 这是默认值,这将使得每三个连续顶点(v0, v1, v2),(v2, v3, v5),……被解释为一个单独的三角形。 -
    - 如果顶点的数量不是3的倍数,那么将会忽略多余的顶点。 -

    - - - THREE.TriangleStripDrawMode - -

    - 这将使得一系列的三角形(由(v0, v1, v2),(v2, v1, v3),(v2, v3, v4),……给定)一个一个地连在一起,每一个连续的三角形将和前一个三角形共享两个顶点。 -

    - - - THREE.TriangleFanDrawMode - -

    -这将会使得一个序列中的每一个三角形(由(v0, v1, v2),(v0, v2, v3),(v0, v3, v4),……给定)共享它们的第一个顶点(就像风扇一样)。

    - - 注意:截至[link:https://en.wikipedia.org/wiki/DirectX#DirectX_10 DirectX10]这个模式还没有被支持。 - 由于Chorme和Firefox在Windows上是使用[link:https://en.wikipedia.org/wiki/ANGLE_(software) ANGLE]来渲染WebGL的,所以这种模式将会在内部转换为受支持的模式, - 但可能会导致这些浏览器在性能上降低一些。 -

    - - -

    用法

    - - - var geometry = new THREE.Geometry(); - - geometry.vertices.push( - new THREE.Vector3( -10, 10, 0 ), - new THREE.Vector3( -10, -10, 0 ), - new THREE.Vector3( 10, -10, 0 ), - ... - ); - geometry.faces.push( new THREE.Face3( 0, 1, 2 ), ... ); - - var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); - - var mesh = new THREE.Mesh( geometry, material ); - mesh.drawMode = THREE.TrianglesDrawMode; //default - - scene.add( mesh ); - - - - -

    源代码

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] - - diff --git a/docs/api/zh/constants/Materials.html b/docs/api/zh/constants/Materials.html index 480ae666022c40..2bab787b1e7818 100644 --- a/docs/api/zh/constants/Materials.html +++ b/docs/api/zh/constants/Materials.html @@ -27,20 +27,6 @@

    默认值是[page:Constant FrontSide](只渲染正面)。

    - -

    颜色

    - - THREE.NoColors - THREE.FaceColors - THREE.VertexColors - -

    - [page:Constant NoColors] 是默认值,且会将材质的颜色应用到所有面。
    - [page:Constant FaceColors] 根据每个[page:Face3 Face3]的[page:Color Color]值来对面进行着色。
    - [page:Constant VertexColors] 根据每个 [page:Face3 Face3]的vertexColors(顶点颜色)值来对面进行着色。 这是一个包含有三个[page:Color Color]的数组,数组中每一项都对应着面中的每一个顶点。
    - 请查看示例:[example:webgl_geometry_colors geometry / colors]。 -

    -

    混合模式

    THREE.NoBlending @@ -142,6 +128,8 @@

    Stencil Operations

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    diff --git a/docs/api/zh/constants/Renderer.html b/docs/api/zh/constants/Renderer.html index 0d0a6b10700d1b..ebca42a251407d 100644 --- a/docs/api/zh/constants/Renderer.html +++ b/docs/api/zh/constants/Renderer.html @@ -39,13 +39,15 @@

    阴影类型

    THREE.BasicShadowMap THREE.PCFShadowMap THREE.PCFSoftShadowMap + THREE.VSMShadowMap

    这些常量定义了WebGLRenderer中[page:WebGLRenderer.shadowMap.type shadowMap.type]的属性。

    [page:constant BasicShadowMap] 能够给出没有经过过滤的阴影映射 —— 速度最快,但质量最差。
    [page:constant PCFShadowMap] 为默认值,使用Percentage-Closer Filtering (PCF)算法来过滤阴影映射。
    - [page:constant PCFSoftShadowMap] 使用Percentage-Closer Soft Shadows (PCSS) 算法来过滤阴影映射。 + [page:constant PCFSoftShadowMap] filters shadow maps using the Percentage-Closer Filtering (PCF) algorithm with better soft shadows especially when using low-resolution shadow maps.
    + [page:constant VSMShadowMap] 使用Variance Shadow Map (VSM)算法来过滤阴影映射。当使用VSMShadowMap时,所有阴影接收者也将会投射阴影。

    色调映射

    @@ -57,9 +59,9 @@

    色调映射

    THREE.CineonToneMapping

    - 这些常量定义了WebGLRenderer中[page:WebGLRenderer.toneMapping toneMapping]的属性。 + 这些常量定义了WebGLRenderer中[page:WebGLRenderer.toneMapping toneMapping]的属性。 - 这个属性用于在普通计算机显示器或者移动设备屏幕等低动态范围介质上,模拟、逼近高动态范围(HDR)效果。

    + 这个属性用于在普通计算机显示器或者移动设备屏幕等低动态范围介质上,模拟、逼近高动态范围(HDR)效果。

    [page:constant NoToneMapping] 禁用色调映射。
    [page:constant LinearToneMapping] 为默认值,线性色调映射。

    @@ -71,6 +73,8 @@

    色调映射

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    diff --git a/docs/api/zh/constants/Textures.html b/docs/api/zh/constants/Textures.html index e442e6543738d2..4aef2061cb1de5 100644 --- a/docs/api/zh/constants/Textures.html +++ b/docs/api/zh/constants/Textures.html @@ -63,9 +63,7 @@

    包裹模式

    使用[page:constant MirroredRepeatWrapping], 纹理将重复到无穷大,在每次重复时将进行镜像。

    -

    Magnification Filters - 放大滤镜 -

    +

    放大滤镜(Magnification Filters)

    THREE.NearestFilter THREE.LinearFilter @@ -80,8 +78,7 @@

    Magnification Filters

    -

    缩小滤镜 - Minification Filters

    +

    缩小滤镜(Minification Filters)

    THREE.NearestFilter THREE.NearestMipmapNearestFilter @@ -97,20 +94,20 @@

    缩小滤镜 除了[page:constant NearestFilter] 和 [page:constant LinearFilter], 下面的四个函数也可以用于缩小:

    - [page:constant NearestMipmapNearestFilter]选择与被纹理化像素的尺寸最匹配的mipmap,并以[page:constant - NearestFilter](最靠近像素中心的纹理元素)为标准来生成纹理值。 + [page:constant NearestMipmapNearestFilter]选择与被纹理化像素的尺寸最匹配的mipmap, + 并以[page:constant NearestFilter](最靠近像素中心的纹理元素)为标准来生成纹理值。

    - [page:constant NearestMipmapLinearFilter]选择与被纹理化像素的尺寸最接近的两个mipmap,并以[page:constant - NearestFilter]为标准来从每个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。 + [page:constant NearestMipmapLinearFilter]选择与被纹理化像素的尺寸最接近的两个mipmap, + 并以[page:constant NearestFilter]为标准来从每个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。

    - [page:constant LinearMipmapNearestFilter]选择与被纹理化像素的尺寸最匹配的mipmap,并以[page:constant - LinearFilter](最靠近像素中心的四个纹理元素的加权平均值)为标准来生成纹理值。 + [page:constant LinearMipmapNearestFilter]选择与被纹理化像素的尺寸最匹配的mipmap, + 并以[page:constant LinearFilter](最靠近像素中心的四个纹理元素的加权平均值)为标准来生成纹理值。

    - [page:constant LinearMipmapLinearFilter]是默认值,它选择与被纹理化像素的尺寸最接近的两个mipmap,并以[page:constant - LinearFilter]为标准来从每个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。

    + [page:constant LinearMipmapLinearFilter]是默认值,它选择与被纹理化像素的尺寸最接近的两个mipmap, + 并以[page:constant LinearFilter]为标准来从每个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。

    请查看示例:[example:webgl_materials_texture_filters materials / texture / filters]。

    @@ -175,8 +172,8 @@

    格式



    请注意,纹理必须具有正确的[page:Texture.type type]设置,正如上一节所描述的那样。 - 请参阅[link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D - WebGLRenderingContext.texImage2D]来获得有关详细信息。 + 请参阅[link:https://developer.mozilla.org/en/docs/Web/API/WebGLRenderingContext/texImage2D WebGLRenderingContext.texImage2D] + 来获得有关详细信息。

    DDS / ST3C 压缩纹理格式

    @@ -187,9 +184,9 @@

    DDS / ST3C 压缩纹理格式

    THREE.RGBA_S3TC_DXT5_Format

    - 要使用[page:CompressedTexture CompressedTexture]中的[page:Texture.format - format]属性,需要获得[link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ - WEBGL_compressed_texture_s3tc]扩展的支持。

    + 要使用[page:CompressedTexture CompressedTexture]中的[page:Texture.format format]属性, + 需要获得[link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ WEBGL_compressed_texture_s3tc] + 扩展的支持。

    通过这个扩展,这里的四种[link:https://en.wikipedia.org/wiki/S3_Texture_Compression S3TC]格式将可以使用:
    @@ -199,8 +196,7 @@

    DDS / ST3C 压缩纹理格式

    [page:constant RGBA_S3TC_DXT5_Format]:RGBA图像格式的DXT5压缩图像,它也提供了4:1的压缩比,但与DX3格式的不同之处在于其Alpha是如何被压缩的。

    -

    PVRTC 压缩纹理格式 - PVRTC Compressed Texture Formats

    +

    PVRTC 压缩纹理格式(PVRTC Compressed Texture Formats)

    THREE.RGB_PVRTC_4BPPV1_Format THREE.RGB_PVRTC_2BPPV1_Format @@ -209,8 +205,8 @@

    PVRTC 压缩纹理格式

    要使用[page:CompressedTexture CompressedTexture]中的[page:Texture.format format]属性,需要获得 - [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/ - WEBGL_compressed_texture_pvrtc]扩展的支持。
    + [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/ WEBGL_compressed_texture_pvrtc] + 扩展的支持。
    PVRTC通常只在具有PowerVR芯片的移动设备上可用,这些设备主要是苹果设备。

    @@ -225,11 +221,50 @@

    PVRTC 压缩纹理格式

    ETC 压缩纹理格式

    THREE.RGB_ETC1_Format + THREE.RGB_ETC2_Format + THREE.RGBA_ETC2_EAC_Format +

    + For use with a [page:CompressedTexture CompressedTexture]'s [page:Texture.format format] property, + these require support for the [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/ WEBGL_compressed_texture_etc1] + (ETC1) or [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/ WEBGL_compressed_texture_etc] + (ETC2) extensions.

    +

    + +

    ASTC Compressed Texture Format

    + + THREE.RGBA_ASTC_4x4_Format + THREE.RGBA_ASTC_5x4_Format + THREE.RGBA_ASTC_5x5_Format + THREE.RGBA_ASTC_6x5_Format + THREE.RGBA_ASTC_6x6_Format + THREE.RGBA_ASTC_8x5_Format + THREE.RGBA_ASTC_8x6_Format + THREE.RGBA_ASTC_8x8_Format + THREE.RGBA_ASTC_10x5_Format + THREE.RGBA_ASTC_10x6_Format + THREE.RGBA_ASTC_10x8_Format + THREE.RGBA_ASTC_10x10_Format + THREE.RGBA_ASTC_12x10_Format + THREE.RGBA_ASTC_12x12_Format + THREE.SRGB8_ALPHA8_ASTC_4x4_Format + THREE.SRGB8_ALPHA8_ASTC_5x4_Format + THREE.SRGB8_ALPHA8_ASTC_5x5_Format + THREE.SRGB8_ALPHA8_ASTC_6x5_Format + THREE.SRGB8_ALPHA8_ASTC_6x6_Format + THREE.SRGB8_ALPHA8_ASTC_8x5_Format + THREE.SRGB8_ALPHA8_ASTC_8x6_Format + THREE.SRGB8_ALPHA8_ASTC_8x8_Format + THREE.SRGB8_ALPHA8_ASTC_10x5_Format + THREE.SRGB8_ALPHA8_ASTC_10x6_Format + THREE.SRGB8_ALPHA8_ASTC_10x8_Format + THREE.SRGB8_ALPHA8_ASTC_10x10_Format + THREE.SRGB8_ALPHA8_ASTC_12x10_Format + THREE.SRGB8_ALPHA8_ASTC_12x12_Format +

    - 要使用[page:CompressedTexture CompressedTexture]中的[page:Texture.format format]属性,需要获得 - [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/ - WEBGL_compressed_texture_etc1]扩展的支持。

    + For use with a [page:CompressedTexture CompressedTexture]'s [page:Texture.format format] property, + these require support for the [link:https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ WEBGL_compressed_texture_astc] extension.

    编码

    @@ -256,7 +291,9 @@

    编码

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/constants.js src/constants.js] +

    - \ No newline at end of file + diff --git a/docs/api/zh/core/BufferAttribute.html b/docs/api/zh/core/BufferAttribute.html index 7447123d24cc78..1819b50287eea4 100644 --- a/docs/api/zh/core/BufferAttribute.html +++ b/docs/api/zh/core/BufferAttribute.html @@ -52,23 +52,6 @@

    [property:Integer count]

    若缓存存储三元组(例如顶点位置、法向量、颜色值),则该值应等于队列中三元组的个数。

    -

    [property:Boolean dynamic]

    -

    - 不论缓存是否是动态的,默认值都将是 *false*
    - - 如果该值为 false,即告知 GPU 缓存中的数据会经常使用但不经常变化。 - 该值与 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData gl.STATIC_DRAW] 标志位相一致。
    - 如果该值为 true,即告知 GPU 缓存中的数据会经常使用且经常变化。 - 该值与 [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData gl.DYNAMIC_DRAW] 标志位相一致。 -

    - -

    [property:Boolean isBufferAttribute]

    -

    - 指示当前类或派生类是 BufferAttributes. 默认值为 *true*.

    - - 开发者不应当改变该值,该值用于内部实现优化。 -

    -

    [property:Integer itemSize]

    保存在 [page:BufferAttribute.array array] 中矢量的长度。

    @@ -101,6 +84,13 @@

    [property:Object updateRange]

    该值只可以被用于更新某些矢量数据(例如,颜色相关数据)。

    +

    [property:Usage usage]

    +

    + Defines the intended usage pattern of the data store for optimization purposes. Corresponds to the *usage* parameter of + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData WebGLRenderingContext.bufferData](). + Default is *THREE.StaticDrawUsage*. +

    +

    [property:Integer version]

    版本号,当 [page:BufferAttribute.needsUpdate needsUpdate] 被设置为 true 时,该值会自增。

    @@ -158,15 +148,8 @@

    [method:BufferAttribute set] ( [param:Array value], [param:Integer offset] ) 特别的, 对将 [page:Array value] 转为 [page:TypedArray] 的要求详见上述链接。

    -

    [method:BufferAttribute setArray] ( [param:TypedArray array] )

    -

    - [page:BufferAttribute.array array] 被赋值的 TypedArray 队列。

    - - 队列被复制后,[page:BufferAttribute.needsUpdate needsUpdate] 应当被设置为 true。 -

    - -

    [method:BufferAttribute setDynamic] ( [param:Boolean value] )

    -

    将 [page:BufferAttribute.dynamic dynamic] 设置为 value.

    +

    [method:BufferAttribute setUsage] ( [param:Usage value] )

    +

    Set [page:BufferAttribute.usage usage] to value.

    [method:BufferAttribute setX]( [param:Integer index], [param:Float x] )

    设置给定索引的矢量的第一维数据(设置 X 值)。

    @@ -193,6 +176,8 @@

    [method:BufferAttribute setXYZW]( [param:Integer index], [param:Float x], [p

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/BufferGeometry.html b/docs/api/zh/core/BufferGeometry.html index 9c7e0743125f36..84997bf73e41f5 100644 --- a/docs/api/zh/core/BufferGeometry.html +++ b/docs/api/zh/core/BufferGeometry.html @@ -21,7 +21,7 @@

    [name]

    几何体的更多使用示例,详见 [page:Geometry]。

    -

    示例

    +

    代码示例

    var geometry = new THREE.BufferGeometry(); // 创建一个简单的矩形. 在这里我们左上和右下顶点被复制了两次。 @@ -37,10 +37,12 @@

    示例

    ] ); // itemSize = 3 因为每个顶点都是一个三元组。 - geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); var mesh = new THREE.Mesh( geometry, material );
    + +

    例子

    [example:webgl_buffergeometry Mesh with non-indexed faces]
    [example:webgl_buffergeometry_indexed Mesh with indexed faces]
    @@ -64,7 +66,7 @@

    属性

    [property:Object attributes]

    通过 hashmap 存储该几何体相关的属性,hashmap 的 id 是当前 attribute 的名称,值是相应的 [page:BufferAttribute buffer]。 - 你可以通过 [page:.addAttribute] 和 [page:.getAttribute] 添加和访问与当前几何体有关的 attribute。 + 你可以通过 [page:.setAttribute] 和 [page:.getAttribute] 添加和访问与当前几何体有关的 attribute。

    [property:Box3 boundingBox]

    @@ -125,13 +127,6 @@

    [property:BufferAttribute index]

    默认值是 *null*。

    -

    [property:Boolean isBufferGeometry]

    -

    - 用于检查当前类或派生类的类型是 BufferGeometries。默认值是 *true*。

    - - 该值用于内部优化,你不应该手动修改该值。 -

    -

    [property:Object morphAttributes]

    存储 [page:BufferAttribute] 的 Hashmap,存储了几何体 [page:Geometry.morphTargets morphTargets] 的细节信息。 @@ -156,9 +151,9 @@

    方法

    [page:EventDispatcher EventDispatcher] 在该类上可用的所有方法。

    -

    [method:BufferGeometry addAttribute]( [param:String name], [param:BufferAttribute attribute] )

    +

    [method:BufferGeometry setAttribute]( [param:String name], [param:BufferAttribute attribute] )

    - 为当前几何体增加一个 attribute。 的属性,在类的内部,有一个存储 [page:.attributes] 的 hashmap, + 为当前几何体设置一个 attribute 属性。在类的内部,有一个存储 [page:.attributes] 的 hashmap, 通过该 hashmap,遍历 attributes 的速度会更快。而使用该方法,可以向 hashmap 内部增加 attribute。 所以,你需要使用该方法来添加 attributes。

    @@ -169,7 +164,7 @@

    [method:null addGroup]( [param:Integer start], [param:Integer count], [param

    -

    [method:null applyMatrix]( [param:Matrix4 matrix] )

    +

    [method:null applyMatrix4]( [param:Matrix4 matrix] )

    用给定矩阵转换几何体的顶点坐标。

    [method:BufferGeometry center] ()

    @@ -236,7 +231,7 @@

    [method:null normalizeNormals]()

    几何体中的每个法向量长度将会为 1。这样操作会更正光线在表面的效果。

    -

    [method:BufferAttribute removeAttribute]( [param:String name] )

    +

    [method:BufferAttribute deleteAttribute]( [param:String name] )

    删除具有指定名称的 [page:BufferAttribute attribute]。

    [method:BufferGeometry rotateX] ( [param:Float radians] )

    @@ -287,6 +282,8 @@

    [method:BufferGeometry updateFromObject] ( [param:Object3D object] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/Clock.html b/docs/api/zh/core/Clock.html index 0b67b59688c834..230d3bb117c6a6 100644 --- a/docs/api/zh/core/Clock.html +++ b/docs/api/zh/core/Clock.html @@ -80,6 +80,8 @@

    [method:Float getDelta]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/DirectGeometry.html b/docs/api/zh/core/DirectGeometry.html index cbb8399de5f10d..45317a017c49df 100644 --- a/docs/api/zh/core/DirectGeometry.html +++ b/docs/api/zh/core/DirectGeometry.html @@ -98,6 +98,8 @@

    [property:null fromGeometry]( [param:Geometry geometry] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/EventDispatcher.html b/docs/api/zh/core/EventDispatcher.html index dba86c9ed751c3..15ebc3dd6b45ed 100644 --- a/docs/api/zh/core/EventDispatcher.html +++ b/docs/api/zh/core/EventDispatcher.html @@ -15,36 +15,36 @@

    [name]

    [link:https://github.com/mrdoob/eventdispatcher.js Eventdispatcher on GitHub]

    -

    示例

    +

    代码示例

    -// 为自定义对象添加事件 + // 为自定义对象添加事件 -var Car = function () { + var Car = function () { - this.start = function () { + this.start = function () { - this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); + this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); - }; + }; -}; + }; -// 将 EventDispatcher.prototype 与自定义对象 prototype 进行混合 + // 将 EventDispatcher.prototype 与自定义对象 prototype 进行混合 -Object.assign( Car.prototype, EventDispatcher.prototype ); + Object.assign( Car.prototype, EventDispatcher.prototype ); -// 使用自定义对象的事件 + // 使用自定义对象的事件 -var car = new Car(); + var car = new Car(); -car.addEventListener( 'start', function ( event ) { + car.addEventListener( 'start', function ( event ) { - alert( event.message ); + alert( event.message ); -} ); + } ); -car.start(); + car.start();

    构造函数

    @@ -95,6 +95,8 @@

    [method:null dispatchEvent]( [param:object event] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/Face3.html b/docs/api/zh/core/Face3.html index 5c8c610c88bcca..7b7c1f9d19b2b4 100644 --- a/docs/api/zh/core/Face3.html +++ b/docs/api/zh/core/Face3.html @@ -11,43 +11,44 @@

    [name]

    - 在 [page:Geometry] 中被使用到的三角面片。这些三角面片会为所有标准几何体自动创建。 - 然而,如果你正在构建一个自定义几何体,你需要手动创建这些三角面片。 + 在 [page:Geometry] 中被使用到的三角形面。这些三角形面会为所有标准几何体自动创建。 + 然而,如果你正在构建一个自定义几何体,你需要手动创建这些三角形面。

    - -

    示例

    - -

    [example:svg_sandbox svg / sandbox ]

    -

    [example:misc_exporter_obj exporter / obj ]

    -

    [example:webgl_shaders_vector WebGL / shaders / vector ]

    - +

    代码示例

    -var material = new THREE.MeshStandardMaterial( { color : 0x00cc00 } ); + var material = new THREE.MeshStandardMaterial( { color : 0x00cc00 } ); -//创建仅有一个三角面片的几何体 -var geometry = new THREE.Geometry(); -geometry.vertices.push( new THREE.Vector3( -50, -50, 0 ) ); -geometry.vertices.push( new THREE.Vector3( 50, -50, 0 ) ); -geometry.vertices.push( new THREE.Vector3( 50, 50, 0 ) ); + // 创建仅有一个三角形面的几何体 + var geometry = new THREE.Geometry(); + geometry.vertices.push( new THREE.Vector3( -50, -50, 0 ) ); + geometry.vertices.push( new THREE.Vector3( 50, -50, 0 ) ); + geometry.vertices.push( new THREE.Vector3( 50, 50, 0 ) ); -//利用顶点 0, 1, 2 创建一个面 -var normal = new THREE.Vector3( 0, 1, 0 ); //optional -var color = new THREE.Color( 0xffaa00 ); //optional -var materialIndex = 0; //optional -var face = new THREE.Face3( 0, 1, 2, normal, color, materialIndex ); + // 利用顶点 0, 1, 2 创建一个面 + var normal = new THREE.Vector3( 0, 0, 1 ); //optional + var color = new THREE.Color( 0xffaa00 ); //optional + var materialIndex = 0; //optional + var face = new THREE.Face3( 0, 1, 2, normal, color, materialIndex ); -//将创建的面添加到几何体的面的队列 -geometry.faces.push( face ); + // 将创建的面添加到几何体的面的队列 + geometry.faces.push( face ); -//如果没有特别指明,面和顶点的法向量可以通过如下代码自动计算 -geometry.computeFaceNormals(); -geometry.computeVertexNormals(); + // 如果没有特别指明,面和顶点的法向量可以通过如下代码自动计算 + geometry.computeFaceNormals(); + geometry.computeVertexNormals(); -scene.add( new THREE.Mesh( geometry, material ) ); + scene.add( new THREE.Mesh( geometry, material ) ); +

    例子

    + +

    + [example:svg_sandbox svg / sandbox ]
    + [example:misc_exporter_obj exporter / obj ]
    + [example:webgl_shaders_vector WebGL / shaders / vector ] +

    构造函数

    @@ -94,7 +95,7 @@

    [property:Vector3 normal]

    [property:Color color]

    面的颜色值 - 在被用于指定材质的 [page:Material.vertexColors vertexColors] 属性时,该值必须被设置为 - [page:Materials THREE.FaceColors]。 + *true*。

    [property:Array vertexNormals]

    @@ -105,7 +106,7 @@

    [property:Array vertexNormals]

    [property:Array vertexColors]

    包含 3 个顶点颜色值的队列 - 在被用于指定材质的 [page:Material.vertexColors vertexColors] 属性时,该值必须被设置为 - [page:Materials THREE.VertexColors]。 + *true*。

    [property:Integer materialIndex]

    @@ -124,6 +125,8 @@

    [method:Face3 copy]( [param:Face3 face3] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/Geometry.html b/docs/api/zh/core/Geometry.html index 80e31e11e5a9f5..e904bc5d93f6e1 100644 --- a/docs/api/zh/core/Geometry.html +++ b/docs/api/zh/core/Geometry.html @@ -12,7 +12,7 @@

    [name]

    - Geometry 是对 [page:BufferGeometry] 的用户有好替代。Geometry 利用 [page:Vector3] + Geometry 是一个便于用户使用的 [page:BufferGeometry] 的替代品。Geometry 利用 [page:Vector3] 或 [page:Color] 存储了几何体的相关 attributes(如顶点位置,面信息,颜色等)比起 BufferGeometry 更容易读写,但是运行效率不如有类型的队列。

    @@ -21,20 +21,10 @@

    [name]

    -

    示例

    +

    代码示例

    -
    [example:webgl_geometry_minecraft WebGL / geometry / minecraft ]
    -
    [example:webgl_geometry_minecraft_ao WebGL / geometry / minecraft / ao ]
    -
    [example:webgl_geometry_nurbs WebGL / geometry / nurbs ]
    -
    [example:webgl_geometry_spline_editor WebGL / geometry / spline / editor ]
    -
    [example:webgl_interactive_cubes_gpu WebGL / interactive / cubes / gpu ]
    -
    [example:webgl_interactive_lines WebGL / interactive / lines ]
    -
    [example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points ]
    -
    [example:webgl_interactive_voxelpainter WebGL / interactive / voxelpainter ]
    -
    [example:webgl_morphnormals WebGL / morphNormals ]
    - - - var geometry = new THREE.Geometry(); + + var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3( -10, 10, 0 ), @@ -47,6 +37,19 @@

    示例

    geometry.computeBoundingSphere();
    +

    例子

    + +

    + [example:webgl_geometry_minecraft WebGL / geometry / minecraft ]
    + [example:webgl_geometry_minecraft_ao WebGL / geometry / minecraft / ao ]
    + [example:webgl_geometry_nurbs WebGL / geometry / nurbs ]
    + [example:webgl_geometry_spline_editor WebGL / geometry / spline / editor ]
    + [example:webgl_interactive_cubes_gpu WebGL / interactive / cubes / gpu ]
    + [example:webgl_interactive_lines WebGL / interactive / lines ]
    + [example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points ]
    + [example:webgl_interactive_voxelpainter WebGL / interactive / voxelpainter ] +

    +

    构造函数

    @@ -96,13 +99,6 @@

    [property:Array faceVertexUvs]

    [property:Integer id]

    当前 geometry 实例的唯一标识符的数。

    -

    [property:Boolean isGeometry]

    -

    - 用于判断当前类或派生类属于 Geometries。默认值是 *true*。

    - - 你不应该改变该值,该值用于内部优化。 -

    -

    [property:array lineDistances]

    用于保存线型几何体中每个顶点间距离的。在正确渲染 [page:LineDashedMaterial] 时,需要用到该数据。 @@ -205,7 +201,7 @@

    方法

    [page:EventDispatcher EventDispatcher] 该类中可用的函数。

    -

    [method:null applyMatrix]( [param:Matrix4 matrix] )

    +

    [method:null applyMatrix4]( [param:Matrix4 matrix] )

    将矩阵信息直接应用于几何体顶点坐标。

    [method:Geometry center] ()

    @@ -331,6 +327,8 @@

    [method:Geometry translate] ( [param:Float x], [param:Float y], [param:Float

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/InstancedBufferAttribute.html b/docs/api/zh/core/InstancedBufferAttribute.html index f6110db4e9c236..75f3e0ccc0c0d0 100644 --- a/docs/api/zh/core/InstancedBufferAttribute.html +++ b/docs/api/zh/core/InstancedBufferAttribute.html @@ -22,23 +22,20 @@

    [name]( [param:TypedArray array], [param:Integer itemSize], [param:Number me

    属性

    - 继承属性详见 [page:BufferAttribute]。 +

    继承属性详见 [page:BufferAttribute]。

    [property:Number meshPerAttribute]

    默认值为 *1*。

    -

    [property:Boolean isInstancedBufferAttribute]

    -

    - 默认值为 *true*. -

    -

    方法

    继承方法详见 [page:BufferAttribute]。

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/InstancedBufferGeometry.html b/docs/api/zh/core/InstancedBufferGeometry.html index 0b8fc97c99e145..5e7ceff1a143a1 100644 --- a/docs/api/zh/core/InstancedBufferGeometry.html +++ b/docs/api/zh/core/InstancedBufferGeometry.html @@ -22,29 +22,20 @@

    [name]( )

    属性

    - 继承属性详见 [page:BufferGeometry]。 +

    继承属性详见 [page:BufferGeometry]。

    [property:Number maxInstancedCount]

    默认值是 *undefined*。

    -

    [property:Boolean isInstancedBufferGeometry]

    -

    - 默认值是 *true*。 -

    -

    方法

    -

    继承方法详见 [page:BufferAttribute]。

    - -

    [property:Number addGroup]( start, count, materialIndex )

    -

    - -

    - +

    继承方法详见 [page:BufferGeometry]。

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/InstancedInterleavedBuffer.html b/docs/api/zh/core/InstancedInterleavedBuffer.html index 478660e58e4c31..b4628e34b31f77 100644 --- a/docs/api/zh/core/InstancedInterleavedBuffer.html +++ b/docs/api/zh/core/InstancedInterleavedBuffer.html @@ -31,11 +31,6 @@

    [property:Number meshPerAttribute]

    默认值是 *1*。

    -

    [property:Boolean isInstancedInterleavedBuffer]

    -

    - 默认值是 *true*。 -

    -

    方法

    继承方法详见 [page:InterleavedBuffer]。 @@ -43,6 +38,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/InterleavedBuffer.html b/docs/api/zh/core/InterleavedBuffer.html index 32d023ce094d62..3d96083a1404fb 100644 --- a/docs/api/zh/core/InterleavedBuffer.html +++ b/docs/api/zh/core/InterleavedBuffer.html @@ -16,7 +16,7 @@

    [name]

    如下链接有对交叉存储更详细的介绍: [link:https://blog.tojicode.com/2011/05/interleaved-array-basics.html Interleaved array basics]

    -

    示例

    +

    例子

    [example:webgl_buffergeometry_points_interleaved webgl / buffergeometry / points / interleaved]

    @@ -44,11 +44,6 @@

    [property:Integer count]

    类型化队列中,所有元素的数目。

    -

    [property:Boolean dynamic]

    -

    - 默认值为 *false*。 -

    -

    [property:Object updateRange]

    对象存储着需要更新的数据的偏移量和数量。 @@ -79,17 +74,13 @@

    [property:Integer needsUpdate]

    默认值为 *false*。该值被设置为 true 时,会导致 [page:InterleavedBuffer.version version] 增加。

    -

    方法

    - -

    [method:InterleavedBuffer setArray] ( [param:TypedArray array] )

    +

    [property:Usage usage]

    - array - 必须是一个类型化的队列。 + Defines the intended usage pattern of the data store for optimization purposes. Corresponds to the *usage* parameter of + [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData WebGLRenderingContext.bufferData]().

    -

    [method:InterleavedBuffer setDynamic] ( [param:Boolean value] )

    -

    - 根据输入参数设置 [page:InterleavedBuffer.dynamic dynamic] 的值。 -

    +

    方法

    [method:InterleavedBuffer copy]( [param:InterleavedBuffer source] )

    @@ -112,8 +103,13 @@

    [method:InterleavedBuffer clone]()

    克隆当前 [name]。

    +

    [method:BufferAttribute setUsage] ( [param:Usage value] )

    +

    Set [page:BufferAttribute.usage usage] to value.

    +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/InterleavedBufferAttribute.html b/docs/api/zh/core/InterleavedBufferAttribute.html index 6ea3b0e1aa7b1b..221f059e2c9655 100644 --- a/docs/api/zh/core/InterleavedBufferAttribute.html +++ b/docs/api/zh/core/InterleavedBufferAttribute.html @@ -54,11 +54,6 @@

    [property:Boolean normalized]

    默认值为 *false*。

    -

    [property:Boolean isInterleavedBufferAttribute]

    -

    - 默认值为 *true*。 -

    -

    方法

    [method:Number getX]( [param:Integer index] )

    @@ -96,6 +91,8 @@

    [method:null setXYZW]( [param:Integer index], [param:Float x], [param:Float

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/Layers.html b/docs/api/zh/core/Layers.html index bf8fa6531b28e8..5a95835bc4f1df 100644 --- a/docs/api/zh/core/Layers.html +++ b/docs/api/zh/core/Layers.html @@ -75,8 +75,20 @@

    [method:null toggle]( [param:Integer layer] )

    根据参数切换对象所属图层。

    +

    [method:null enableAll]()

    +

    + Add membership to all layers. +

    + +

    [method:null disableAll]()

    +

    + Remove membership from all layers. +

    +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/Object3D.html b/docs/api/zh/core/Object3D.html index b995e9fe1c67fd..194408c8a945e0 100644 --- a/docs/api/zh/core/Object3D.html +++ b/docs/api/zh/core/Object3D.html @@ -38,9 +38,9 @@

    [property:Object3D children]

    [property:Material customDepthMaterial]

    渲染到深度贴图时此材质要使用的自定义深度材质。 - 当使用[page:DirectionalLight]或[page:SpotLight]进行阴影投射时,如果您正在(a)修改顶点着色器中的顶点位置, - (b)使用位移贴图,(c)alphaTest中使用alpha贴图,或(d)alphaTest中使用透明纹理, - 您必须指定customDepthMaterial以得到合适的阴影。默认值*undefined*。 + 当使用[page:DirectionalLight]或[page:SpotLight]进行阴影投射时,如果您正在(a)修改顶点着色器中的顶点位置, + (b)使用位移贴图,(c)alphaTest中使用alpha贴图,或(d)alphaTest中使用透明纹理, + 您必须指定customDepthMaterial以得到合适的阴影。默认值*undefined*。

    [property:Material customDistanceMaterial]

    @@ -56,17 +56,11 @@

    [property:Boolean frustumCulled]

    [property:Integer id]

    只读 —— 表示该对象实例ID的唯一数字。

    -

    [property:Boolean isObject3D]

    -

    - - 用于测试这个类或者派生类是否为Object3D,默认为*true*。

    - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:Layers layers]

    物体的层级关系。 - 物体只有和一个正在使用的[page:Camera]至少在同一个层时才可见。 + 物体只有和一个正在使用的[page:Camera]至少在同一个层时才可见。This property can also be used to filter out + unwanted objects in ray-intersection tests when using [page:Raycaster].

    [property:Matrix4 matrix]

    @@ -111,8 +105,8 @@

    [property:function onAfterRender]

    [property:function onBeforeRender]

    - 一个可选的回调函数,在Object3D渲染之前直接执行。 - 使用以下参数来调用此函数:renderer,scene,camera,geometry,material,group。 + 一个可选的回调函数,在Object3D渲染之前直接执行。 + 使用以下参数来调用此函数:renderer,scene,camera,geometry,material,group。

    [property:Object3D parent]

    @@ -182,7 +176,7 @@

    [property:Vector3 DefaultUp]

    默认设为( 0, 1, 0 )。

    -

    [property:Vector3 DefaultMatrixAutoUpdate]

    +

    [property:Boolean DefaultMatrixAutoUpdate]

    [page:.matrixAutoUpdate matrixAutoUpdate]的默认设置,用于新创建的Object3D。
    @@ -200,13 +194,13 @@

    [method:null add]( [param:Object3D object], ... )

    请参阅[page:Group]来查看手动编组对象的相关信息。

    -

    [method:null applyMatrix]( [param:Matrix4 matrix] )

    +

    [method:null applyMatrix4]( [param:Matrix4 matrix] )

    对当前物体应用这个变换矩阵,并更新物体的位置、旋转和缩放。

    [method:Object3D applyQuaternion]( [param:Quaternion quaternion] )

    对当前物体应用由四元数所表示的变换。

    - +

    [method:this attach]( [param:Object3D object] )

    将*object*作为子级来添加到该对象中,同时保持该object的世界变换。

    @@ -416,8 +410,15 @@

    [method:null updateMatrix]()

    更新局部变换。

    [method:null updateMatrixWorld]( [param:Boolean force] )

    -

    更新物体及其子级的全局变换。

    +

    更新物体及其后代的全局变换。

    +

    [method:null updateWorldMatrix]( [param:Boolean updateParents], [param:Boolean updateChildren] )

    +

    + updateParents - recursively updates global transform of ancestors.
    + updateChildren - recursively updates global transform of descendants.

    + + Updates the global transform of the object. +

    [method:Vector3 worldToLocal]( [param:Vector3 vector] )

    @@ -427,7 +428,9 @@

    [method:Vector3 worldToLocal]( [param:Vector3 vector] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/Raycaster.html b/docs/api/zh/core/Raycaster.html index f1b5312d978339..e6ab96a4988309 100644 --- a/docs/api/zh/core/Raycaster.html +++ b/docs/api/zh/core/Raycaster.html @@ -15,7 +15,7 @@

    光线投射[name]

    光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。

    -

    示例

    +

    代码示例

    var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); @@ -52,16 +52,19 @@

    示例

    window.requestAnimationFrame(render);
    -
    - 其它示例:
    [example:webgl_interactive_cubes Raycasting to a Mesh]
    + +

    例子

    +

    + [example:webgl_interactive_cubes Raycasting to a Mesh]
    [example:webgl_interactive_cubes_ortho Raycasting to a Mesh in using an OrthographicCamera]
    [example:webgl_interactive_buffergeometry Raycasting to a Mesh with BufferGeometry]
    + [example:webgl_instancing_raycast Raycasting to a InstancedMesh]
    [example:webgl_interactive_lines Raycasting to a Line]
    [example:webgl_interactive_raycasting_points Raycasting to Points]
    [example:webgl_geometry_terrain_raycast Terrain raycasting]
    [example:webgl_interactive_voxelpainter Raycasting to paint voxels]
    [example:webgl_raycast_texture Raycast to a Texture] -

    +

    @@ -90,31 +93,45 @@

    [property:float far]

    这个值不应当为负,并且应当比near属性大。

    -

    [property:float linePrecision]

    +

    [property:float near]

    + raycaster的近距离因数(投射近点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 + 这个值不应当为负,并且应当比far属性小。 +

    - raycaster与[page:Line](线)物体相交时的精度因数。 +

    [property:Camera camera]

    +

    + The camera to use when raycasting against view-dependent objects such as billboarded objects like [page:Sprites]. This field + can be set manually or is set when calling "setFromCamera". + Defaults to null.

    -

    [property:float near]

    +

    [property:Layers layers]

    - raycaster的近距离因数(投射近点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 - 这个值不应当为负,并且应当比near属性小。 + Used by [name] to selectively ignore 3D objects when performing intersection tests. The following code example ensures that + only 3D objects on layer *1* will be honored by the instance of [name]. + + + raycaster.layers.set( 1 ); + object.layers.enable( 1 ); + +

    [property:Object params]

    - 具有以下属性的物体: + 具有以下属性的对象: { Mesh: {}, - Line: {}, + Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} } + Where threshold is the precision of the raycaster when intersecting objects, in world units.

    [property:Ray ray]

    @@ -162,7 +179,8 @@

    [method:Array intersectObject]( [param:Object3D object], [param:Boolean recu [page:Integer faceIndex] —— 相交的面的索引
    [page:Object3D object] —— 相交的物体
    [page:Vector2 uv] —— 相交部分的点的UV坐标。
    - [page:Vector2 uv2] —— Second set of U,V coordinates at point of intersection + [page:Vector2 uv2] —— Second set of U,V coordinates at point of intersection
    + [page:Integer instanceId] – The index number of the instance where the ray intersects the InstancedMesh

    当计算这条射线是否和物体相交的时候,*Raycaster*将传入的对象委托给[page:Object3D.raycast raycast]方法。 @@ -187,6 +205,8 @@

    [method:Array intersectObjects]( [param:Array objects], [param:Boolean recur

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/Uniform.html b/docs/api/zh/core/Uniform.html index f101a97b37e307..4d60489b55228e 100644 --- a/docs/api/zh/core/Uniform.html +++ b/docs/api/zh/core/Uniform.html @@ -13,10 +13,9 @@

    [name]

    Uniforms 是 [link:https://www.opengl.org/documentation/glsl/ GLSL] 着色器中的全局变量。

    -

    示例

    +

    代码示例

    - 在声明一个 [page:ShaderMaterial] 的 Uniform 变量时,该变量被值或对象声明。 - When declaring a uniform of a [page:ShaderMaterial], it is declared by value or by object. + When declaring a uniform of a [page:ShaderMaterial], it is declared by value or by object.

    uniforms: { @@ -25,7 +24,7 @@

    示例

    }
    -

    Uniform 种类

    +

    Uniform 种类

    每个 Uniform 必须包括一个 *value* 属性。value 的类型必须和下表中 GLSL 的基本类型相对应。同样,Uniform 的结构体和队列 @@ -48,6 +47,10 @@

    Uniform 种类

    int [page:Number] + + uint (WebGL 2) + [page:Number] + float [page:Number] @@ -201,13 +204,13 @@

    [method:Uniform clone]()

    返回该 Uniform 的克隆。
    如果 Uniform 的 value 属性是一个带 clone() 方法的 [page:Object],则克隆该对象时,value 的 clone() 方法也会被调用,否则克隆时只会使用赋值语句。 - 队列中的值会在该 Uniform 和 被克隆对象间共享。

    - - 该方法的使用示例详见 [example:webgldeferred_animation WebGL deferred animation]。 + 队列中的值会在该 Uniform 和 被克隆对象间共享。

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html b/docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html index 4a7a4f10a4c80a..083419f5a59f5b 100644 --- a/docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html +++ b/docs/api/zh/core/bufferAttributeTypes/BufferAttributeTypes.html @@ -34,7 +34,9 @@

    构造函数

    所有上述内容都以相同的方式调用。

    TypedBufferAttribute( [param:Array array], [param:Integer itemSize], [param:Boolean normalized] )

    - array -- 这可以是类型化或非类型化的(普通)数组。它将被转换为指定的类型。

    + array -- 该值可以是类型化或非类型化的(普通)数组。 + 它将被转换为指定的类型。 + If a length is given a new TypedArray will created, initialized with all elements set to zero.

    itemSize -- 应与特定顶点关联的数组值的数量。

    @@ -43,14 +45,20 @@

    TypedBufferAttribute( [param:Array array], [param:Integer itemSize], [param:

    属性

    - 继承属性详见 [page:BufferAttribute]。 +

    + 继承属性详见 [page:BufferAttribute]。 +

    方法

    - 继承方法详见 [page:BufferAttribute]。 +

    + 继承方法详见 [page:BufferAttribute]。 +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js src/core/BufferAttribute.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js src/core/BufferAttribute.js] +

    diff --git a/docs/api/zh/deprecated/DeprecatedList.html b/docs/api/zh/deprecated/DeprecatedList.html index 9e3a0379690d02..a2b820175c2e8e 100644 --- a/docs/api/zh/deprecated/DeprecatedList.html +++ b/docs/api/zh/deprecated/DeprecatedList.html @@ -130,16 +130,6 @@

    [page:SplineCurve3]

    - - -

    几何体(Geometry)

    - -

    - Geometry.computeTangents() 已被删除。

    - - Geometry.computeLineDistances() 已被删除。 请使用[page:Line.computeLineDistances]。

    -

    -

    [page:BufferGeometry]

    BufferGeometry.addIndex 已被重命名为 [page:BufferGeometry.setIndex]。

    @@ -156,13 +146,28 @@

    [page:BufferGeometry]

    BufferGeometry.offsets 已被重命名为 [page:BufferGeometry.groups]。

    + BufferGeometry.applyMatrix() has been renamed to [page:BufferGeometry.applyMatrix4](). +

    + + +

    [page:CubeGeometry]

    CubeGeometry 已被重命名为 [page:BoxGeometry]。

    + + +

    [page:Geometry]

    -

    Geometry.computeTangents() 已被删除。

    +

    + Geometry.computeTangents() 已被删除。

    + + Geometry.computeLineDistances() 已被删除。 请使用[page:Line.computeLineDistances]。

    + + Geometry.applyMatrix() has been renamed to [page:Geometry.applyMatrix4](). +

    +

    [page:GeometryUtils]

    @@ -263,6 +268,9 @@

    [page:Box3]

    [page:Face4]

    Face4 已被删除。 请使用[page:Face3]。

    +

    [page:Frustum]

    +

    Frustum.setFromMatrix() has been renamed to [page:Frustum.setFromProjectionMatrix]().

    +

    [page:Line3]

    Line3.center 已被重命名为 [page:Line3.getCenter]()。

    @@ -438,12 +446,15 @@

    [page:Object3D]

    Object3D.translate() 已被删除。 请使用[page:Object3D.translateOnAxis]( axis, distance )。

    - Object3D.useQuaternion 已被删除。 默认情况下,Three.js库是使用quaternions(四元数)的。 + Object3D.useQuaternion 已被删除。 默认情况下,Three.js库是使用quaternions(四元数)的。

    + + Object3D.applyMatrix() has been renamed to [page:Object3D.applyMatrix4](). +

    [page:LensFlare]

    - LensFlare 已被移动到了 [link:https://github.com/mrdoob/three.js/blob/master/examples/js/objects/Lensflare.js /examples/js/objects/Lensflare.js]. + LensFlare 已被移动到了 [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Lensflare.js /examples/jsm/objects/Lensflare.js].

    @@ -473,13 +484,13 @@

    渲染器(Renderer)

    [page:Projector]

    - CanvasRenderer 已被移动到了 [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CanvasRenderer.js /examples/js/renderers/CanvasRenderer.js]. + CanvasRenderer has been removed.

    [page:Projector]

    Projector 已被移动到了 - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/Projector.js /examples/js/renderers/Projector.js]。

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/Projector.js /examples/jsm/renderers/Projector.js]。

    Projector.projectVector() 现在是 [page:Vector.project]()。

    @@ -581,8 +592,9 @@

    [page:ImageUtils]

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/Three.Legacy.js src/Three.Legacy.js] - +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/Three.Legacy.js src/Three.Legacy.js] +

    diff --git a/docs/api/zh/extras/Earcut.html b/docs/api/zh/extras/Earcut.html index 3e0b5077a7e368..614c88a3a500f8 100644 --- a/docs/api/zh/extras/Earcut.html +++ b/docs/api/zh/extras/Earcut.html @@ -26,6 +26,8 @@

    [method:Array triangulate]( data, holeIndices, dim )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/ImageUtils.html b/docs/api/zh/extras/ImageUtils.html new file mode 100644 index 00000000000000..1f850372034bee --- /dev/null +++ b/docs/api/zh/extras/ImageUtils.html @@ -0,0 +1,32 @@ + + + + + + + + + + +

    [name]

    + +

    + A class containing utility functions for images. +

    + +

    Methods

    + +

    [method:String getDataURL]( [param:HTMLCanvasElement image] | [param:HTMLImageElement image] | [param:ImageBitmap image] )

    +

    + image -- The image object.

    + + Returns a data URI containing a representation of the given image. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/zh/extras/PMREMGenerator.html b/docs/api/zh/extras/PMREMGenerator.html new file mode 100644 index 00000000000000..e5fa7605922cdc --- /dev/null +++ b/docs/api/zh/extras/PMREMGenerator.html @@ -0,0 +1,80 @@ + + + + + + + + + + +

    [name]

    + +

    + This class generates a Prefiltered, Mipmapped Radiance Environment Map (PMREM) from a cubeMap environment texture. + This allows different levels of blur to be quickly accessed based on material roughness. It is packed into a special + CubeUV format that allows us to perform custom interpolation so that we can support nonlinear formats such as RGBE. + Unlike a traditional mipmap chain, it only goes down to the LOD_MIN level (above), and then creates extra even more + filtered 'mips' at the same LOD_MIN resolution, associated with higher roughness levels. In this way we maintain + resolution to smoothly interpolate diffuse lighting while limiting sampling computation. +

    + +

    Constructor

    + +

    [name]( [param:WebGLRenderer renderer] )

    +

    + This constructor creates a new [name]. +

    + +

    Methods

    + +

    [method:WebGLRenderTarget fromScene]( [param:Scene scene], [param:Number sigma], [param:Number near], [param:Number far] )

    +

    + [page:Scene scene] - The given scene.
    + [page:Number sigma] - (optional) Specifies a blur radius in radians to be applied to the scene before PMREM generation. Default is *0*.
    + [page:Number near] - (optional) The near plane value. Default is *0.1*.
    + [page:Number far] - (optional) The far plane value. Default is *100*.

    + + Generates a PMREM from a supplied Scene, which can be faster than using an image if networking bandwidth is low. + Optional near and far planes ensure the scene is rendered in its entirety (the cubeCamera is placed at the origin). +

    + +

    [method:WebGLRenderTarget fromEquirectangular]( [param:Texture equirectangular] )

    +

    + [page:Texture equirectangular] - The equirectangular texture.

    + + Generates a PMREM from an equirectangular texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). + The ideal input image size is 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output. +

    + +

    [method:WebGLRenderTarget fromCubemap]( [param:CubeTexture cubemap] )

    +

    + [page:CubeTexture cubemap] - The cubemap texture.

    + + Generates a PMREM from an cubemap texture, which can be either LDR (RGBFormat) or HDR (RGBEFormat). + The ideal input cube size is 256 x 256, as this matches best with the 256 x 256 cubemap output. +

    + +

    [method:void compileCubemapShader]()

    +

    + Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. +

    + +

    [method:void compileEquirectangularShader]()

    +

    + Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. +

    + +

    [method:void dispose]()

    +

    + Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, so you should not need more than one + PMREMGenerator object. If you do, calling dispose() on one of them will cause any others to also become unusable. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/zh/extras/ShapeUtils.html b/docs/api/zh/extras/ShapeUtils.html index 3ff417b30d1d48..5aedc90b3e8eb6 100644 --- a/docs/api/zh/extras/ShapeUtils.html +++ b/docs/api/zh/extras/ShapeUtils.html @@ -27,7 +27,7 @@

    [method:Number area]( contour )

    -

    [method:Boolean isClockwise]( pts )

    +

    [method:Boolean isClockWise]( pts )

    pts -- 定义2D多边形的点

    @@ -46,6 +46,8 @@

    [method:Array triangulateShape]( contour, holes )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/core/Curve.html b/docs/api/zh/extras/core/Curve.html index ee3a07713aa2ab..9abd7140ab6e51 100644 --- a/docs/api/zh/extras/core/Curve.html +++ b/docs/api/zh/extras/core/Curve.html @@ -111,6 +111,8 @@

    [method:Curve fromJSON]( [param:Object json] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/core/CurvePath.html b/docs/api/zh/extras/core/CurvePath.html index fcd6e455600cac..2d2821856150cf 100644 --- a/docs/api/zh/extras/core/CurvePath.html +++ b/docs/api/zh/extras/core/CurvePath.html @@ -52,9 +52,24 @@

    [method:null closePath]()

    [method:Float getCurveLengths]()

    将[page:.curves]数组中曲线的长度相加。

    +

    [method:Array getPoints]( [param:Integer divisions] )

    +

    + divisions -- 曲线分段数量。默认值为*12*。

    + + 返回一组使用getPoint( t )获得的divisions + 1个点。 +

    + +

    [method:Array getSpacedPoints]( [param:Integer divisions] )

    +

    + divisions -- 曲线分段数量。默认值为*40*。

    + + 返回一组使用getPointAt( u )获得的divisions + 1个均分点。 +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/core/Font.html b/docs/api/zh/extras/core/Font.html index 650517d97d9c8e..36b6aa97806587 100644 --- a/docs/api/zh/extras/core/Font.html +++ b/docs/api/zh/extras/core/Font.html @@ -17,7 +17,7 @@

    字体([name])

    该类在内部由[page:FontLoader]所使用。

    -

    示例

    +

    例子

    [example:webgl_geometry_text_shapes geometry / text / shapes ]
    @@ -38,14 +38,6 @@

    属性

    [property:array data]

    传入到构造函数的JSON数据。

    -

    [property:Boolean isFont]

    -

    - 用于检查该类或者其派生类是否为字体。默认值为*true*。 -

    - - 你不应当对这一属性进行改变,它在内部由渲染器所使用,以用于优化。 -

    -

    方法

    [method:null generateShapes]( [param:String text], [param:Float size] )

    @@ -58,6 +50,8 @@

    [method:null generateShapes]( [param:String text], [param:Float size] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/core/Interpolations.html b/docs/api/zh/extras/core/Interpolations.html index 57a47242693de0..8b0f89ce1b1457 100644 --- a/docs/api/zh/extras/core/Interpolations.html +++ b/docs/api/zh/extras/core/Interpolations.html @@ -11,7 +11,7 @@

    插值([name])

    - TODO + [name] contains spline and Bézier functions internally used by concrete curve classes.

    方法

    @@ -42,6 +42,8 @@

    [method:Float CubicBezier]( [param:Float t], [param:Float p0], [param:Float

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/core/Path.html b/docs/api/zh/extras/core/Path.html index 8a3dcd5fc414e9..4e6cf17705eb0f 100644 --- a/docs/api/zh/extras/core/Path.html +++ b/docs/api/zh/extras/core/Path.html @@ -16,22 +16,22 @@

    路径([name])

    该类定义了二维路径,提供了一些类似2D Canvas API的方法来创建或者构造二维路径。

    -

    示例

    +

    代码示例

    - var path = new THREE.Path(); + var path = new THREE.Path(); - path.lineTo( 0, 0.8 ); - path.quadraticCurveTo( 0, 1, 0.2, 1 ); - path.lineTo( 1, 1 ); + path.lineTo( 0, 0.8 ); + path.quadraticCurveTo( 0, 1, 0.2, 1 ); + path.lineTo( 1, 1 ); - var points = path.getPoints(); + var points = path.getPoints(); - var geometry = new THREE.BufferGeometry().setFromPoints( points ); - var material = new THREE.LineBasicMaterial( { color: 0xffffff } ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var material = new THREE.LineBasicMaterial( { color: 0xffffff } ); - var line = new THREE.Line( geometry, material ); - scene.add( line ); + var line = new THREE.Line( geometry, material ); + scene.add( line ); @@ -59,7 +59,7 @@

    [property:array currentPoint]

    方法

    共有方法请参见其基类[page:CurvePath]。

    -

    [method:null absarc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise] )

    +

    [method:this absarc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise] )

    x, y -- 弧线的绝对中心。
    radius -- 弧线的半径。
    @@ -70,7 +70,7 @@

    [method:null absarc]( [param:Float x], [param:Float y], [param:Float radius] 添加一条绝对定位的[page:EllipseCurve EllipseCurve]到路径中。

    -

    [method:null absellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise], [param:Float rotation] )

    +

    [method:this absellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise], [param:Float rotation] )

    x, y -- 椭圆的绝对中心。
    xRadius -- 椭圆x轴方向的半径。
    @@ -83,7 +83,7 @@

    [method:null absellipse]( [param:Float x], [param:Float y], [param:Float xRa 添加一条绝对定位的[page:EllipseCurve EllipseCurve]到路径中。

    -

    [method:null arc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise] )

    +

    [method:this arc]( [param:Float x], [param:Float y], [param:Float radius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise] )

    x, y -- 弧线的中心来自上次调用后的偏移量。
    radius -- 弧线的半径。
    @@ -95,10 +95,10 @@

    [method:null arc]( [param:Float x], [param:Float y], [param:Float radius], [

    -

    [method:null bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

    +

    [method:this bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

    从[page:.currentPoint]创建一条贝塞尔曲线,以(cp1X, cp1Y)和(cp2X, cp2Y)作为控制点,并将[page:.currentPoint]更新到x,y。

    -

    [method:null ellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Float clockwise], [param:Float rotation] )

    +

    [method:this ellipse]( [param:Float x], [param:Float y], [param:Float xRadius], [param:Float yRadius], [param:Float startAngle], [param:Float endAngle], [param:Boolean clockwise], [param:Float rotation] )

    x, y -- 椭圆的中心来自上次调用后的偏移量。The center of the ellipse offset from the last call.
    xRadius -- 椭圆x轴方向的半径。
    @@ -111,25 +111,25 @@

    [method:null ellipse]( [param:Float x], [param:Float y], [param:Float xRadiu 添加一条[page:EllipseCurve EllipseCurve]到路径中,位置相对于[page:.currentPoint]。

    -

    [method:null lineTo]( [param:Float x], [param:Float y] )

    +

    [method:this lineTo]( [param:Float x], [param:Float y] )

    在当前路径上,从[page:.currentPoint]连接一条直线到x,y。

    -

    [method:null moveTo]( [param:Float x], [param:Float y] )

    +

    [method:this moveTo]( [param:Float x], [param:Float y] )

    将[page:.currentPoint]移动到x, y。

    -

    [method:null quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

    +

    [method:this quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

    从[page:.currentPoint]创建一条二次曲线,以(cpX,cpY)作为控制点,并将[page:.currentPoint]更新到x,y。

    -

    [method:null setFromPoints]( [param:Array vector2s] )

    +

    [method:this setFromPoints]( [param:Array vector2s] )

    points -- [page:Vector2 Vector2]数组。

    点将被作为[page:LineCurve LineCurves]加入到[page:CurvePath.curves curves]数组中。

    -

    [method:null splineThru] ( [param:Array points] )

    +

    [method:this splineThru] ( [param:Array points] )

    points -[page:Vector2 Vector2]数组。

    @@ -138,6 +138,8 @@

    [method:null splineThru] ( [param:Array points] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/core/Shape.html b/docs/api/zh/extras/core/Shape.html index f60299fc53c624..78d4d8747a1744 100644 --- a/docs/api/zh/extras/core/Shape.html +++ b/docs/api/zh/extras/core/Shape.html @@ -17,6 +17,8 @@

    形状([name])

    它可以和[page:ExtrudeGeometry]、[page:ShapeGeometry]一起使用,获取点,或者获取三角面。

    +

    代码示例

    + var heartShape = new THREE.Shape(); @@ -30,20 +32,19 @@

    形状([name])

    var extrudeSettings = { amount: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 }; - var geometry = new THREE.ExtrudeGeometry( heartShape, extrudeSettings ); + var geometry = new THREE.ExtrudeBufferGeometry( heartShape, extrudeSettings ); var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial() );
    -

    示例

    +

    例子

    [example:webgl_geometry_shapes geometry / shapes ]
    [example:webgl_geometry_extrude_shapes geometry / extrude / shapes ]
    - [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2 ]
    + [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2 ]

    -

    构造函数

    @@ -95,6 +96,8 @@

    [method:Array getPointsHoles]( [param:Integer divisions] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/core/ShapePath.html b/docs/api/zh/extras/core/ShapePath.html index 96185334e4c0e9..c483dd7216f85c 100644 --- a/docs/api/zh/extras/core/ShapePath.html +++ b/docs/api/zh/extras/core/ShapePath.html @@ -8,8 +8,6 @@ - [page:Curve] → [page:CurvePath] → -

    形状路径([name])

    @@ -17,9 +15,10 @@

    形状路径([name])

    在内部它由[page:Font]所使用,用于将JSON字体转换为一系列路径。

    -

    示例

    - - [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2] +

    例子

    +

    + [example:webgl_geometry_extrude_shapes2 geometry / extrude / shapes2] +

    构造函数

    @@ -44,27 +43,27 @@

    [property:array currentPath]

    方法

    -

    [method:null moveTo]( [param:Float x], [param:Float y] )

    +

    [method:this moveTo]( [param:Float x], [param:Float y] )

    创建一个新的[page:Path],并在[page:Path]上调用[page:Path.moveTo]( x, y )。

    -

    [method:null lineTo]( [param:Float x], [param:Float y] )

    +

    [method:this lineTo]( [param:Float x], [param:Float y] )

    这一方法从[page:ShapePath.currentPath currentPath](当前路径)的偏移量创建一条到X和Y的线,并将偏移量更新为X和Y。

    -

    [method:null quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

    +

    [method:this quadraticCurveTo]( [param:Float cpX], [param:Float cpY], [param:Float x], [param:Float y] )

    这一方法从[page:ShapePath.currentPath currentPath](当前路径)创建一条到X和Y的二次曲线,cpX和cpY作为控制点, 并将[page:ShapePath.currentPath currentPath]的偏移量更新为x和y。

    -

    [method:null bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

    +

    [method:this bezierCurveTo]( [param:Float cp1X], [param:Float cp1Y], [param:Float cp2X], [param:Float cp2Y], [param:Float x], [param:Float y] )

    这一方法从[page:ShapePath.currentPath currentPath](当前路径)的偏移量创建一条到X和Y的贝塞尔曲线, cp1X、cp1Y和cp1X、cp1Y为控制点,并将[page:ShapePath.currentPath currentPath]的偏移量更新为x和y。

    -

    [method:null splineThru] ( [param:Array points] )

    +

    [method:this splineThru] ( [param:Array points] )

    points - 一个[page:Vector2]数组。

    连接一个新的[page:SplineCurve](样条曲线)到[page:ShapePath.currentPath currentPath](当前路径)。

    @@ -84,7 +83,8 @@

    [method:Array toShapes]( [param:Boolean isCCW], [param:Boolean noHoles] )源代码

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js src/extras/core/Path.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js src/extras/core/Path.js] +

    diff --git a/docs/api/zh/extras/curves/ArcCurve.html b/docs/api/zh/extras/curves/ArcCurve.html index 0fd9e4d9a8dad1..fd26fad768d334 100644 --- a/docs/api/zh/extras/curves/ArcCurve.html +++ b/docs/api/zh/extras/curves/ArcCurve.html @@ -17,16 +17,11 @@

    弧线([name])

    属性

    共有属性请参见其基类[page:EllipseCurve]。

    -

    [property:Boolean isArcCurve]

    -

    - 用于检查该类或者其派生类是否为ArcCurves(弧线)。默认值为*true*。

    - - 你不应当对这一属性进行改变,它在内部使用,以用于优化。 -

    -

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/CatmullRomCurve3.html b/docs/api/zh/extras/curves/CatmullRomCurve3.html index ada08141e9aba4..123f9494af37fa 100644 --- a/docs/api/zh/extras/curves/CatmullRomCurve3.html +++ b/docs/api/zh/extras/curves/CatmullRomCurve3.html @@ -16,29 +16,32 @@

    [name]

    使用[link:https://en.wikipedia.org/wiki/Centripetal_Catmull-Rom_spline Catmull-Rom]算法, 从一系列的点创建一条平滑的三维样条曲线。

    -

    示例

    +

    代码示例

    - -//Create a closed wavey loop -var curve = new THREE.CatmullRomCurve3( [ - new THREE.Vector3( -10, 0, 10 ), - new THREE.Vector3( -5, 5, 5 ), - new THREE.Vector3( 0, 0, 0 ), - new THREE.Vector3( 5, -5, 5 ), - new THREE.Vector3( 10, 0, 10 ) -] ); + + //Create a closed wavey loop + var curve = new THREE.CatmullRomCurve3( [ + new THREE.Vector3( -10, 0, 10 ), + new THREE.Vector3( -5, 5, 5 ), + new THREE.Vector3( 0, 0, 0 ), + new THREE.Vector3( 5, -5, 5 ), + new THREE.Vector3( 10, 0, 10 ) + ] ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); + -

    [example:webgl_geometry_extrude_splines geometry / extrude / splines]

    +

    例子

    +

    + [example:webgl_geometry_extrude_splines WebGL / geometry / extrude / splines] +

    构造函数

    @@ -54,13 +57,6 @@

    [name]( [param:Array points], [param:Boolean closed], [param:String curveTyp

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isCatmullRomCurve3]

    -

    - 用于检查该类或者其派生类是否为CatmullRomCurve3。默认值为*true*。

    - - 你不应当对这一属性进行改变,它在内部使用,以用于优化。 -

    -

    [property:Array points]

    定义了这一曲线的[page:Vector3]点数组,数组中至少需要两个点。

    @@ -77,6 +73,8 @@

    [property:float tension]

    方法

    共有方法请参见其基类[page:Curve]。

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/CubicBezierCurve.html b/docs/api/zh/extras/curves/CubicBezierCurve.html index e6781e74cd3333..29b6a31ab2f007 100644 --- a/docs/api/zh/extras/curves/CubicBezierCurve.html +++ b/docs/api/zh/extras/curves/CubicBezierCurve.html @@ -18,24 +18,24 @@

    二维三次贝塞尔曲线([name])

    由起点、终点和两个控制点所定义。

    -

    示例

    +

    代码示例

    - -var curve = new THREE.CubicBezierCurve( - new THREE.Vector2( -10, 0 ), - new THREE.Vector2( -5, 15 ), - new THREE.Vector2( 20, 15 ), - new THREE.Vector2( 10, 0 ) -); + + var curve = new THREE.CubicBezierCurve( + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( -5, 15 ), + new THREE.Vector2( 20, 15 ), + new THREE.Vector2( 10, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); +

    构造函数

    @@ -51,14 +51,6 @@

    [name] ( [param:Vector2 v0], [param:Vector2 v1], [param:Vector2 v2], [param:

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isCubicBezierCurve]

    -

    - - 用于检查该类或者其派生类是否为CubicBezierCurves。默认值为*true*。

    - - 你不应当对这一属性进行改变,它在内部使用,以用于优化。 -

    -

    [property:Vector2 v0]

    起点

    @@ -77,6 +69,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/CubicBezierCurve3.html b/docs/api/zh/extras/curves/CubicBezierCurve3.html index 07aa0e393d9468..3d2b2260f73d4d 100644 --- a/docs/api/zh/extras/curves/CubicBezierCurve3.html +++ b/docs/api/zh/extras/curves/CubicBezierCurve3.html @@ -18,25 +18,25 @@

    三维三次贝塞尔曲线([name])

    由起点、终点和两个控制点所定义。

    -

    示例

    +

    代码示例

    - -var curve = new THREE.CubicBezierCurve3( - new THREE.Vector3( -10, 0, 0 ), - new THREE.Vector3( -5, 15, 0 ), - new THREE.Vector3( 20, 15, 0 ), - new THREE.Vector3( 10, 0, 0 ) -); + + var curve = new THREE.CubicBezierCurve3( + new THREE.Vector3( -10, 0, 0 ), + new THREE.Vector3( -5, 15, 0 ), + new THREE.Vector3( 20, 15, 0 ), + new THREE.Vector3( 10, 0, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); - +

    构造函数

    @@ -52,13 +52,6 @@

    [name]( [param:Vector3 v0], [param:Vector3 v1], [param:Vector3 v2], [param:V

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isCubicBezierCurve3]

    -

    - 用于检查该类或者其派生类是否为CubicBezierCurves3。默认值为*true*。

    - - 你不应当对这一属性进行改变,它在内部使用,以用于优化。 -

    -

    [property:Vector3 v0]

    起点

    @@ -77,6 +70,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/EllipseCurve.html b/docs/api/zh/extras/curves/EllipseCurve.html index c1aaa9a02b0a59..defec5173c521c 100644 --- a/docs/api/zh/extras/curves/EllipseCurve.html +++ b/docs/api/zh/extras/curves/EllipseCurve.html @@ -17,25 +17,25 @@

    椭圆曲线([name])

    将[page:Number xRadius]与[page:Number yRadius]设为相等的值它将会成为一个圆。

    -

    示例

    +

    代码示例

    - -var curve = new THREE.EllipseCurve( - 0, 0, // ax, aY - 10, 10, // xRadius, yRadius - 0, 2 * Math.PI, // aStartAngle, aEndAngle - false, // aClockwise - 0 // aRotation -); + + var curve = new THREE.EllipseCurve( + 0, 0, // ax, aY + 10, 10, // xRadius, yRadius + 0, 2 * Math.PI, // aStartAngle, aEndAngle + false, // aClockwise + 0 // aRotation + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var ellipse = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var ellipse = new THREE.Line( geometry, material ); +

    构造函数

    @@ -46,24 +46,15 @@

    [name]( [param:Float aX], [param:Float aY], [param:Float xRadius], [param:Fl [page:Float aY] – 椭圆的中心的Y坐标,默认值为*0*。
    [page:Float xRadius] – X轴向上椭圆的半径,默认值为*1*。
    [page:Float yRadius] – Y轴向上椭圆的半径,默认值为*1*。
    - [page:Radians aStartAngle] – 以弧度来表示,从正右侧算起曲线开始的角度,默认值为*0*。
    - [page:Radians aEndAngle] – 以弧度来表示,从正右侧算起曲线终止的角度,默认值为*2 x Math.PI*。
    + [page:Radians aStartAngle] – 以弧度来表示,从正X轴算起曲线开始的角度,默认值为*0*。
    + [page:Radians aEndAngle] – 以弧度来表示,从正X轴算起曲线终止的角度,默认值为*2 x Math.PI*。
    [page:Boolean aClockwise] – 椭圆是否按照顺时针方向来绘制,默认值为*false*。
    [page:Radians aRotation] – 以弧度表示,椭圆从X轴正方向逆时针的旋转角度(可选),默认值为*0*。

    - - 请注意: 当使用顺时针的时候,最好将起始角度角度设为(Math.PI * 2),并向着更小的数字运行。

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isEllipseCurve]

    -

    - 用于检查该类或者其派生类是否为EllipseCurves。默认值为*true*。 -

    - 你不应当更改这个属性,它在内部使用,以用于优化。 -

    -

    [property:Float aX]

    椭圆的中心的X坐标。

    @@ -93,6 +84,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/LineCurve.html b/docs/api/zh/extras/curves/LineCurve.html index 4dafbb251f29c1..8624aa9e5795ab 100644 --- a/docs/api/zh/extras/curves/LineCurve.html +++ b/docs/api/zh/extras/curves/LineCurve.html @@ -27,14 +27,6 @@

    [name]( [param:Vector2 v1], [param:Vector2 v2] )

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isLineCurve]

    -

    - 用于检查该类或者其派生类是否为LineCurves。默认值为*true*。 -

    - - 你不应当更改这个属性,它在内部使用,以用于优化。 -

    -

    [property:Vector2 v1]

    起点

    @@ -47,6 +39,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/LineCurve3.html b/docs/api/zh/extras/curves/LineCurve3.html index d1b46a1a4c80d6..7143306bee5f9b 100644 --- a/docs/api/zh/extras/curves/LineCurve3.html +++ b/docs/api/zh/extras/curves/LineCurve3.html @@ -27,14 +27,6 @@

    [name]( [param:Vector3 v1], [param:Vector3 v2] )

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isLineCurve3]

    -

    - 用于检查该类或者其派生类是否为LineCurves。默认值为*true*。 -

    - - 你不应当更改这个属性,它在内部使用,以用于优化。 -

    -

    [property:Vector3 v1]

    起点

    @@ -46,6 +38,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/QuadraticBezierCurve.html b/docs/api/zh/extras/curves/QuadraticBezierCurve.html index 103ca9a50103f1..8fa8ee83f330ac 100644 --- a/docs/api/zh/extras/curves/QuadraticBezierCurve.html +++ b/docs/api/zh/extras/curves/QuadraticBezierCurve.html @@ -18,23 +18,23 @@

    二维二次贝塞尔曲线([name])

    由起点、终点和一个控制点所定义。

    -

    示例

    +

    代码示例

    - -var curve = new THREE.QuadraticBezierCurve( - new THREE.Vector2( -10, 0 ), - new THREE.Vector2( 20, 15 ), - new THREE.Vector2( 10, 0 ) -); + + var curve = new THREE.QuadraticBezierCurve( + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( 20, 15 ), + new THREE.Vector2( 10, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -//Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + //Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); +

    构造函数

    @@ -50,14 +50,6 @@

    [name]( [param:Vector2 v0], [param:Vector2 v1], [param:Vector2 v2] )

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isQuadraticBezierCurve]

    -

    - 用于检查该类或者其派生类是否为QuadraticBezierCurve。默认值为*true*。

    - - 你不应当对这一属性进行改变,它在内部使用,以用于优化。 -

    - -

    [property:Vector2 v0]

    起点

    @@ -72,6 +64,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/QuadraticBezierCurve3.html b/docs/api/zh/extras/curves/QuadraticBezierCurve3.html index c5f31cbdb74216..a66e6ae944db1d 100644 --- a/docs/api/zh/extras/curves/QuadraticBezierCurve3.html +++ b/docs/api/zh/extras/curves/QuadraticBezierCurve3.html @@ -18,23 +18,23 @@

    三维二次贝塞尔曲线([name])

    由起点、终点和一个控制点所定义。

    -

    示例

    +

    代码示例

    - -var curve = new THREE.QuadraticBezierCurve3( - new THREE.Vector3( -10, 0, 0 ), - new THREE.Vector3( 20, 15, 0 ), - new THREE.Vector3( 10, 0, 0 ) -); + + var curve = new THREE.QuadraticBezierCurve3( + new THREE.Vector3( -10, 0, 0 ), + new THREE.Vector3( 20, 15, 0 ), + new THREE.Vector3( 10, 0, 0 ) + ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var curveObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var curveObject = new THREE.Line( geometry, material ); +

    构造函数

    @@ -51,13 +51,6 @@

    [name]( [param:Vector3 v0], [param:Vector3 v1], [param:Vector3 v2] )

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isQuadraticBezierCurve3]

    -

    - 用于检查该类或者其派生类是否为QuadraticBezierCurve3。默认值为*true*。

    - - 你不应当对这一属性进行改变,它在内部使用,以用于优化。 -

    -

    [property:Vector3 v0]

    起点

    @@ -72,6 +65,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/curves/SplineCurve.html b/docs/api/zh/extras/curves/SplineCurve.html index a78c2a0817ce3d..8c06f43ddc7786 100644 --- a/docs/api/zh/extras/curves/SplineCurve.html +++ b/docs/api/zh/extras/curves/SplineCurve.html @@ -16,26 +16,26 @@

    样条曲线([name])

    从一系列的点中,创建一个平滑的二维样条曲线。内部使用[page:Interpolations.CatmullRom]来创建曲线。

    -

    示例

    +

    代码示例

    - -// Create a sine-like wave -var curve = new THREE.SplineCurve( [ - new THREE.Vector2( -10, 0 ), - new THREE.Vector2( -5, 5 ), - new THREE.Vector2( 0, 0 ), - new THREE.Vector2( 5, -5 ), - new THREE.Vector2( 10, 0 ) -] ); + + // Create a sine-like wave + var curve = new THREE.SplineCurve( [ + new THREE.Vector2( -10, 0 ), + new THREE.Vector2( -5, 5 ), + new THREE.Vector2( 0, 0 ), + new THREE.Vector2( 5, -5 ), + new THREE.Vector2( 10, 0 ) + ] ); -var points = curve.getPoints( 50 ); -var geometry = new THREE.BufferGeometry().setFromPoints( points ); + var points = curve.getPoints( 50 ); + var geometry = new THREE.BufferGeometry().setFromPoints( points ); -var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); + var material = new THREE.LineBasicMaterial( { color : 0xff0000 } ); -// Create the final object to add to the scene -var splineObject = new THREE.Line( geometry, material ); - + // Create the final object to add to the scene + var splineObject = new THREE.Line( geometry, material ); +

    构造函数

    @@ -47,13 +47,6 @@

    [name]( [param:Array points] )

    属性

    共有属性请参见其基类[page:Curve]。

    -

    [property:Boolean isSplineCurve]

    -

    - 用于检查该类或者其派生类是否为样条曲线。默认值为*true*。

    - - 你不应当对这一属性进行改变,它在内部使用,以用于优化。 -

    -

    [property:Array points]

    定义这一曲线的[page:Vector2]点的数组。

    @@ -66,6 +59,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/extras/objects/ImmediateRenderObject.html b/docs/api/zh/extras/objects/ImmediateRenderObject.html index 3a9d4694a43a97..4e67346cb8d851 100644 --- a/docs/api/zh/extras/objects/ImmediateRenderObject.html +++ b/docs/api/zh/extras/objects/ImmediateRenderObject.html @@ -37,6 +37,8 @@

    [method:null render]([param:Function renderCallback])

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/BoxBufferGeometry.html b/docs/api/zh/geometries/BoxBufferGeometry.html index 5cdf7030041f04..0744de4cf8e7e1 100644 --- a/docs/api/zh/geometries/BoxBufferGeometry.html +++ b/docs/api/zh/geometries/BoxBufferGeometry.html @@ -33,7 +33,7 @@

    立方缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); @@ -75,6 +75,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js src/geometries/BoxGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js src/geometries/BoxGeometry.js] +

    diff --git a/docs/api/zh/geometries/BoxGeometry.html b/docs/api/zh/geometries/BoxGeometry.html index b403f67d6947f2..bda61d613518c7 100644 --- a/docs/api/zh/geometries/BoxGeometry.html +++ b/docs/api/zh/geometries/BoxGeometry.html @@ -33,7 +33,7 @@

    立方几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); @@ -75,6 +75,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/CircleBufferGeometry.html b/docs/api/zh/geometries/CircleBufferGeometry.html index 7f33a4e5aa90d8..55c1e6e320a30b 100644 --- a/docs/api/zh/geometries/CircleBufferGeometry.html +++ b/docs/api/zh/geometries/CircleBufferGeometry.html @@ -32,7 +32,7 @@

    圆形缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.CircleBufferGeometry( 5, 32 ); @@ -64,6 +64,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js src/geometries/CircleGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js src/geometries/CircleGeometry.js] +

    diff --git a/docs/api/zh/geometries/CircleGeometry.html b/docs/api/zh/geometries/CircleGeometry.html index bbf78c13579083..1b5d37b53a7911 100644 --- a/docs/api/zh/geometries/CircleGeometry.html +++ b/docs/api/zh/geometries/CircleGeometry.html @@ -34,7 +34,7 @@

    圆形几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.CircleGeometry( 5, 32 ); @@ -66,6 +66,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/ConeBufferGeometry.html b/docs/api/zh/geometries/ConeBufferGeometry.html index eda8d8f7c93e57..ba9f0c83e68f46 100644 --- a/docs/api/zh/geometries/ConeBufferGeometry.html +++ b/docs/api/zh/geometries/ConeBufferGeometry.html @@ -32,7 +32,7 @@

    圆锥缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.ConeBufferGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -66,6 +66,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js src/geometries/ConeGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js src/geometries/ConeGeometry.js] +

    diff --git a/docs/api/zh/geometries/ConeGeometry.html b/docs/api/zh/geometries/ConeGeometry.html index e8e80f244d0056..f58d3b3a391ef8 100644 --- a/docs/api/zh/geometries/ConeGeometry.html +++ b/docs/api/zh/geometries/ConeGeometry.html @@ -32,7 +32,7 @@

    圆锥几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.ConeGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -66,6 +66,8 @@

    方法(Methods)

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/CylinderBufferGeometry.html b/docs/api/zh/geometries/CylinderBufferGeometry.html index ad9ee853c6792a..1d94c86169a44b 100644 --- a/docs/api/zh/geometries/CylinderBufferGeometry.html +++ b/docs/api/zh/geometries/CylinderBufferGeometry.html @@ -32,7 +32,7 @@

    圆柱缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.CylinderBufferGeometry( 5, 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -67,6 +67,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js src/geometries/CylinderGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js src/geometries/CylinderGeometry.js] +

    diff --git a/docs/api/zh/geometries/CylinderGeometry.html b/docs/api/zh/geometries/CylinderGeometry.html index 4e9ea0657f8e00..d9fa4b0e9471c5 100644 --- a/docs/api/zh/geometries/CylinderGeometry.html +++ b/docs/api/zh/geometries/CylinderGeometry.html @@ -32,7 +32,7 @@

    圆柱几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -67,6 +67,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/DodecahedronBufferGeometry.html b/docs/api/zh/geometries/DodecahedronBufferGeometry.html index 5ca37d94d58f5c..c2cddce25af7cb 100644 --- a/docs/api/zh/geometries/DodecahedronBufferGeometry.html +++ b/docs/api/zh/geometries/DodecahedronBufferGeometry.html @@ -53,6 +53,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js src/geometries/DodecahedronGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js src/geometries/DodecahedronGeometry.js] +

    diff --git a/docs/api/zh/geometries/EdgesGeometry.html b/docs/api/zh/geometries/EdgesGeometry.html index 7ab54c077fc845..1a9e100bbf8849 100644 --- a/docs/api/zh/geometries/EdgesGeometry.html +++ b/docs/api/zh/geometries/EdgesGeometry.html @@ -14,17 +14,19 @@

    边缘几何体([name])

    这可以作为一个辅助对象来查看[page:Geometry Geometry]的边缘。

    -

    示例

    - - [example:webgl_helpers helpers] - +

    代码示例

    -var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 ); -var edges = new THREE.EdgesGeometry( geometry ); -var line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0xffffff } ) ); -scene.add( line ); + var geometry = new THREE.BoxBufferGeometry( 100, 100, 100 ); + var edges = new THREE.EdgesGeometry( geometry ); + var line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0xffffff } ) ); + scene.add( line ); +

    例子

    +

    + [example:webgl_helpers helpers] +

    +

    构造器

    [name]( [param:Geometry geometry], [param:Integer thresholdAngle] )

    @@ -46,6 +48,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/ExtrudeBufferGeometry.html b/docs/api/zh/geometries/ExtrudeBufferGeometry.html index cee937f412f1e5..6707f16caa3b78 100644 --- a/docs/api/zh/geometries/ExtrudeBufferGeometry.html +++ b/docs/api/zh/geometries/ExtrudeBufferGeometry.html @@ -32,7 +32,7 @@

    挤压缓冲几何体([name])

    -

    示例

    +

    代码示例

    @@ -106,6 +106,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js src/geometries/ExtrudeGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js src/geometries/ExtrudeGeometry.js] +

    diff --git a/docs/api/zh/geometries/ExtrudeGeometry.html b/docs/api/zh/geometries/ExtrudeGeometry.html index 6d849d67552ee7..42dad6c31a53b5 100644 --- a/docs/api/zh/geometries/ExtrudeGeometry.html +++ b/docs/api/zh/geometries/ExtrudeGeometry.html @@ -32,7 +32,7 @@

    挤压几何体([name])

    -

    示例

    +

    代码示例

    @@ -105,6 +105,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/IcosahedronBufferGeometry.html b/docs/api/zh/geometries/IcosahedronBufferGeometry.html index 5e4610c621a0af..11a956958f9d57 100644 --- a/docs/api/zh/geometries/IcosahedronBufferGeometry.html +++ b/docs/api/zh/geometries/IcosahedronBufferGeometry.html @@ -52,6 +52,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js src/geometries/IcosahedronGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js src/geometries/IcosahedronGeometry.js] +

    diff --git a/docs/api/zh/geometries/IcosahedronGeometry.html b/docs/api/zh/geometries/IcosahedronGeometry.html index 9caf3551ef99fa..83858d5f632b9b 100644 --- a/docs/api/zh/geometries/IcosahedronGeometry.html +++ b/docs/api/zh/geometries/IcosahedronGeometry.html @@ -53,6 +53,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/LatheBufferGeometry.html b/docs/api/zh/geometries/LatheBufferGeometry.html index ff15a02ed6e337..e3024e0a6f32f7 100644 --- a/docs/api/zh/geometries/LatheBufferGeometry.html +++ b/docs/api/zh/geometries/LatheBufferGeometry.html @@ -32,7 +32,7 @@

    车削缓冲几何体([name])

    -

    示例

    +

    代码示例

    var points = []; @@ -71,6 +71,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js src/geometries/LatheGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js src/geometries/LatheGeometry.js] +

    diff --git a/docs/api/zh/geometries/LatheGeometry.html b/docs/api/zh/geometries/LatheGeometry.html index 9982e64f076392..e32732e9471d88 100644 --- a/docs/api/zh/geometries/LatheGeometry.html +++ b/docs/api/zh/geometries/LatheGeometry.html @@ -32,7 +32,7 @@

    车削几何体([name])

    -

    示例

    +

    代码示例

    var points = []; @@ -71,6 +71,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/OctahedronBufferGeometry.html b/docs/api/zh/geometries/OctahedronBufferGeometry.html index 7fb23279023ccf..005acc6ce1d05e 100644 --- a/docs/api/zh/geometries/OctahedronBufferGeometry.html +++ b/docs/api/zh/geometries/OctahedronBufferGeometry.html @@ -53,6 +53,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js src/geometries/OctahedronGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js src/geometries/OctahedronGeometry.js] +

    diff --git a/docs/api/zh/geometries/OctahedronGeometry.html b/docs/api/zh/geometries/OctahedronGeometry.html index d4ba934afce50b..fc48d164365a0a 100644 --- a/docs/api/zh/geometries/OctahedronGeometry.html +++ b/docs/api/zh/geometries/OctahedronGeometry.html @@ -55,7 +55,9 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/ParametricBufferGeometry.html b/docs/api/zh/geometries/ParametricBufferGeometry.html index d9c16b7b17fab4..5747568944a22d 100644 --- a/docs/api/zh/geometries/ParametricBufferGeometry.html +++ b/docs/api/zh/geometries/ParametricBufferGeometry.html @@ -32,7 +32,7 @@

    参数化缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.ParametricBufferGeometry( THREE.ParametricGeometries.klein, 25, 25 ); @@ -65,6 +65,8 @@

    方法(Methods)

    方法

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ParametricGeometry.js src/geometries/ParametricGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ParametricGeometry.js src/geometries/ParametricGeometry.js] +

    diff --git a/docs/api/zh/geometries/ParametricGeometry.html b/docs/api/zh/geometries/ParametricGeometry.html index 83c63677249c5d..867c3fcfd9d962 100644 --- a/docs/api/zh/geometries/ParametricGeometry.html +++ b/docs/api/zh/geometries/ParametricGeometry.html @@ -32,7 +32,7 @@

    参数化几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.ParametricGeometry( THREE.ParametricGeometries.klein, 25, 25 ); @@ -66,6 +66,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/PlaneBufferGeometry.html b/docs/api/zh/geometries/PlaneBufferGeometry.html index 47a41c8b2b3dcb..66142d61cf6941 100644 --- a/docs/api/zh/geometries/PlaneBufferGeometry.html +++ b/docs/api/zh/geometries/PlaneBufferGeometry.html @@ -32,7 +32,7 @@

    平面缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.PlaneBufferGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ); @@ -63,6 +63,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js src/geometries/PlaneGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js src/geometries/PlaneGeometry.js] +

    diff --git a/docs/api/zh/geometries/PlaneGeometry.html b/docs/api/zh/geometries/PlaneGeometry.html index 388a64b1641351..5fcdf5d0431302 100644 --- a/docs/api/zh/geometries/PlaneGeometry.html +++ b/docs/api/zh/geometries/PlaneGeometry.html @@ -32,7 +32,7 @@

    平面几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.PlaneGeometry( 5, 20, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ); @@ -63,6 +63,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/PolyhedronBufferGeometry.html b/docs/api/zh/geometries/PolyhedronBufferGeometry.html index 3900bf2f317c3c..52e9415e5180da 100644 --- a/docs/api/zh/geometries/PolyhedronBufferGeometry.html +++ b/docs/api/zh/geometries/PolyhedronBufferGeometry.html @@ -18,7 +18,7 @@

    多面缓冲几何体([name])

    所使用,以生成它们各自的几何结构。

    -

    示例

    +

    代码示例

    var verticesOfCube = [ -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1, @@ -61,6 +61,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/PolyhedronGeometry.js src/geometries/PolyhedronGeometry.js] +

    diff --git a/docs/api/zh/geometries/PolyhedronGeometry.html b/docs/api/zh/geometries/PolyhedronGeometry.html index 6990323cb4e09b..e2ec3358f0516c 100644 --- a/docs/api/zh/geometries/PolyhedronGeometry.html +++ b/docs/api/zh/geometries/PolyhedronGeometry.html @@ -16,7 +16,7 @@

    多面几何体([name])

    多面体是在三维空间中具有一些平面的立体图形。这个类将一个顶点数组投射到一个球面上,之后将它们细分为所需的细节级别。

    -

    示例

    +

    代码示例

    var verticesOfCube = [ -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1, @@ -59,6 +59,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/RingBufferGeometry.html b/docs/api/zh/geometries/RingBufferGeometry.html index a59e4b7ab737b8..bf42fe76754661 100644 --- a/docs/api/zh/geometries/RingBufferGeometry.html +++ b/docs/api/zh/geometries/RingBufferGeometry.html @@ -32,7 +32,7 @@

    圆环缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.RingBufferGeometry( 1, 5, 32 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } ); @@ -66,6 +66,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js src/geometries/RingGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js src/geometries/RingGeometry.js] +

    diff --git a/docs/api/zh/geometries/RingGeometry.html b/docs/api/zh/geometries/RingGeometry.html index 6f9a09df8c8afd..b9e1b6e3682c2a 100644 --- a/docs/api/zh/geometries/RingGeometry.html +++ b/docs/api/zh/geometries/RingGeometry.html @@ -32,7 +32,7 @@

    圆环几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.RingGeometry( 1, 5, 32 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } ); @@ -65,6 +65,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/ShapeBufferGeometry.html b/docs/api/zh/geometries/ShapeBufferGeometry.html index d541dd016a9030..bb666f7c53d3ce 100644 --- a/docs/api/zh/geometries/ShapeBufferGeometry.html +++ b/docs/api/zh/geometries/ShapeBufferGeometry.html @@ -33,7 +33,7 @@

    形状缓冲几何体([name])

    -

    示例

    +

    代码示例

    @@ -77,6 +77,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js src/geometries/ShapeGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js src/geometries/ShapeGeometry.js] +

    diff --git a/docs/api/zh/geometries/ShapeGeometry.html b/docs/api/zh/geometries/ShapeGeometry.html index d325993863bfcd..dfd37deac0b3aa 100644 --- a/docs/api/zh/geometries/ShapeGeometry.html +++ b/docs/api/zh/geometries/ShapeGeometry.html @@ -33,7 +33,7 @@

    形状几何体([name])

    -

    示例

    +

    代码示例

    @@ -77,6 +77,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/SphereBufferGeometry.html b/docs/api/zh/geometries/SphereBufferGeometry.html index 5cc0066d9e1c21..ec9e416f50c247 100644 --- a/docs/api/zh/geometries/SphereBufferGeometry.html +++ b/docs/api/zh/geometries/SphereBufferGeometry.html @@ -32,7 +32,7 @@

    球缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -73,6 +73,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js src/geometries/SphereGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js src/geometries/SphereGeometry.js] +

    diff --git a/docs/api/zh/geometries/SphereGeometry.html b/docs/api/zh/geometries/SphereGeometry.html index fe26be13394019..68a80db33844bc 100644 --- a/docs/api/zh/geometries/SphereGeometry.html +++ b/docs/api/zh/geometries/SphereGeometry.html @@ -32,7 +32,7 @@

    球几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.SphereGeometry( 5, 32, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); @@ -73,6 +73,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/TetrahedronBufferGeometry.html b/docs/api/zh/geometries/TetrahedronBufferGeometry.html index 010ecf369ecc9f..dac272b5d04a90 100644 --- a/docs/api/zh/geometries/TetrahedronBufferGeometry.html +++ b/docs/api/zh/geometries/TetrahedronBufferGeometry.html @@ -53,6 +53,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js src/geometries/TetrahedronGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js src/geometries/TetrahedronGeometry.js] +

    diff --git a/docs/api/zh/geometries/TetrahedronGeometry.html b/docs/api/zh/geometries/TetrahedronGeometry.html index 6174ef7e1c0c4b..8537875fe4a6be 100644 --- a/docs/api/zh/geometries/TetrahedronGeometry.html +++ b/docs/api/zh/geometries/TetrahedronGeometry.html @@ -53,6 +53,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/TextBufferGeometry.html b/docs/api/zh/geometries/TextBufferGeometry.html index ddec90b31d4c90..a318fb6cccd094 100644 --- a/docs/api/zh/geometries/TextBufferGeometry.html +++ b/docs/api/zh/geometries/TextBufferGeometry.html @@ -36,11 +36,7 @@

    文本缓冲几何体([name])

    -

    示例

    - -

    - [example:webgl_geometry_text geometry / text ] -

    +

    代码示例

    var loader = new THREE.FontLoader(); @@ -60,6 +56,12 @@

    示例

    } );
    +

    例子

    + +

    + [example:webgl_geometry_text geometry / text ] +

    +

    构造器

    [name]([param:String text], [param:Object parameters])

    @@ -166,6 +168,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TextGeometry.js src/geometries/TextGeometry.js] +

    diff --git a/docs/api/zh/geometries/TextGeometry.html b/docs/api/zh/geometries/TextGeometry.html index b5357c0063d679..e0bb49c2ec0786 100644 --- a/docs/api/zh/geometries/TextGeometry.html +++ b/docs/api/zh/geometries/TextGeometry.html @@ -36,11 +36,7 @@

    文本几何体([name])

    -

    示例

    - -

    - [example:webgl_geometry_text geometry / text ] -

    +

    代码示例

    var loader = new THREE.FontLoader(); @@ -60,6 +56,12 @@

    示例

    } );
    +

    例子

    + +

    + [example:webgl_geometry_text geometry / text ] +

    +

    构造器

    [name]([param:String text], [param:Object parameters])

    @@ -166,6 +168,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/TorusBufferGeometry.html b/docs/api/zh/geometries/TorusBufferGeometry.html index 38367939c07b30..0b5b686babb3a2 100644 --- a/docs/api/zh/geometries/TorusBufferGeometry.html +++ b/docs/api/zh/geometries/TorusBufferGeometry.html @@ -32,7 +32,7 @@

    圆环缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.TorusBufferGeometry( 10, 3, 16, 100 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -64,6 +64,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js src/geometries/TorusGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js src/geometries/TorusGeometry.js] +

    diff --git a/docs/api/zh/geometries/TorusGeometry.html b/docs/api/zh/geometries/TorusGeometry.html index d5fcbb111af01b..96ee8707be89ae 100644 --- a/docs/api/zh/geometries/TorusGeometry.html +++ b/docs/api/zh/geometries/TorusGeometry.html @@ -32,7 +32,7 @@

    圆环几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.TorusGeometry( 10, 3, 16, 100 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -64,6 +64,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/TorusKnotBufferGeometry.html b/docs/api/zh/geometries/TorusKnotBufferGeometry.html index 62fba193247635..11491ab7af302c 100644 --- a/docs/api/zh/geometries/TorusKnotBufferGeometry.html +++ b/docs/api/zh/geometries/TorusKnotBufferGeometry.html @@ -10,7 +10,7 @@ [page:BufferGeometry] → -

    圆环缓冲几何体([name])

    +

    圆环缓冲扭结几何体([name])

    This is the [page:BufferGeometry] port of [page:TorusKnotGeometry].

    @@ -32,7 +32,7 @@

    圆环缓冲几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.TorusKnotBufferGeometry( 10, 3, 100, 16 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -67,6 +67,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js src/geometries/TorusKnotGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js src/geometries/TorusKnotGeometry.js] +

    diff --git a/docs/api/zh/geometries/TorusKnotGeometry.html b/docs/api/zh/geometries/TorusKnotGeometry.html index ee519b0a96339a..0bd08f9d5d89d4 100644 --- a/docs/api/zh/geometries/TorusKnotGeometry.html +++ b/docs/api/zh/geometries/TorusKnotGeometry.html @@ -33,7 +33,7 @@

    圆环扭结几何体([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 ); var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); @@ -68,6 +68,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/TubeBufferGeometry.html b/docs/api/zh/geometries/TubeBufferGeometry.html index 11da7d5bdc5004..374064036dbe5f 100644 --- a/docs/api/zh/geometries/TubeBufferGeometry.html +++ b/docs/api/zh/geometries/TubeBufferGeometry.html @@ -32,7 +32,7 @@

    管道缓冲几何体([name])

    -

    示例

    +

    代码示例

    function CustomSinCurve( scale ) { @@ -104,6 +104,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js src/geometries/TubeGeometry.js] +

    diff --git a/docs/api/zh/geometries/TubeGeometry.html b/docs/api/zh/geometries/TubeGeometry.html index 2d3111f1e2bdbd..18628c3cc22d24 100644 --- a/docs/api/zh/geometries/TubeGeometry.html +++ b/docs/api/zh/geometries/TubeGeometry.html @@ -32,7 +32,7 @@

    管道几何体([name])

    -

    示例

    +

    代码示例

    function CustomSinCurve( scale ) { @@ -104,6 +104,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/geometries/WireframeGeometry.html b/docs/api/zh/geometries/WireframeGeometry.html index 96eeb1bf02443d..8ee4e9bf7cff1b 100644 --- a/docs/api/zh/geometries/WireframeGeometry.html +++ b/docs/api/zh/geometries/WireframeGeometry.html @@ -14,41 +14,26 @@

    网格几何体([name])

    这个类可以被用作一个辅助物体,来对一个[page:Geometry Geometry]以线框的形式进行查看。

    - - -

    示例

    - - [example:webgl_helpers helpers] +

    代码示例

    -var geometry = new THREE.SphereBufferGeometry( 100, 100, 100 ); + var geometry = new THREE.SphereBufferGeometry( 100, 100, 100 ); -var wireframe = new THREE.WireframeGeometry( geometry ); + var wireframe = new THREE.WireframeGeometry( geometry ); -var line = new THREE.LineSegments( wireframe ); -line.material.depthTest = false; -line.material.opacity = 0.25; -line.material.transparent = true; + var line = new THREE.LineSegments( wireframe ); + line.material.depthTest = false; + line.material.opacity = 0.25; + line.material.transparent = true; -scene.add( line ); + scene.add( line ); +

    例子

    +

    + [example:webgl_helpers helpers] +

    +

    构造器

    [name]( [param:Geometry geometry] )

    @@ -64,6 +49,8 @@

    方法(Methods)

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/ArrowHelper.html b/docs/api/zh/helpers/ArrowHelper.html index 97eb1a14d176db..da6982d7e9cdfc 100644 --- a/docs/api/zh/helpers/ArrowHelper.html +++ b/docs/api/zh/helpers/ArrowHelper.html @@ -14,12 +14,7 @@

    [name]

    用于模拟方向的3维箭头对象.

    - -

    例子

    - -
    [example:webgl_geometries WebGL / geometries]
    -
    [example:webgl_geometry_normals WebGL / geometry / normals]
    -
    [example:webgl_shadowmesh WebGL / shadowmesh]
    +

    代码示例

    var dir = new THREE.Vector3( 1, 2, 0 ); @@ -35,7 +30,13 @@

    例子

    scene.add( arrowHelper );
    +

    例子

    +

    + [example:webgl_geometries WebGL / geometries]
    + [example:webgl_geometry_normals WebGL / geometry / normals]
    + [example:webgl_shadowmesh WebGL / shadowmesh] +

    构造函数

    @@ -47,7 +48,7 @@

    [name]([param:Vector3 dir], [param:Vector3 origin], [param:Number length], [ [page:Number length] -- 箭头的长度. 默认为 *1*.
    [page:Number hex] -- 定义的16进制颜色值. 默认为 0xffff00.
    [page:Number headLength] -- 箭头头部(锥体)的长度. 默认为箭头长度的0.2倍(0.2 * length).
    - [page:Number headWidth] -- 箭头的宽度. 默认为箭头头部(锥体)长度的0.2倍(0.2 * headLength). + [page:Number headWidth] -- The width of the head of the arrow. Default is 0.2 * headLength.

    属性

    @@ -60,13 +61,9 @@

    [property:Line line]

    [property:Mesh cone]

    包含箭头辅助对象的锥体部分.

    - - -

    方法

    请到基类 [page:Object3D] 页面查看公共方法.

    -

    [method:null setColor]([param:Color color])

    color -- 所需的颜色。

    @@ -78,7 +75,7 @@

    [method:null setLength]([param:Number length], [param:Number headLength], [p

    length -- 要设置的长度.
    headLength -- 要设置的箭头头部(锥体)的长度.
    - headWidth -- 要设置的箭头的宽度.

    + headWidth -- The width of the head of the arrow.

    设置箭头辅助对象的长度.

    @@ -92,6 +89,8 @@

    [method:null setDirection]([param:Vector3 dir])

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/AxesHelper.html b/docs/api/zh/helpers/AxesHelper.html index 2b3759c51f12c2..06cceda7e8685f 100644 --- a/docs/api/zh/helpers/AxesHelper.html +++ b/docs/api/zh/helpers/AxesHelper.html @@ -15,20 +15,20 @@

    [name]

    用于简单模拟3个坐标轴的对象.
    红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.

    +

    代码示例

    -

    例子

    - -
    [example:webgl_geometries WebGL / geometries]
    -
    [example:webgl_geometries2 WebGL / geometries2]
    -
    [example:webgl_geometry_convex WebGL / geometry / convex]
    -
    [example:webgl_geometry_spline_editor WebGL / geometry / spline / editor]
    - + + var axesHelper = new THREE.AxesHelper( 5 ); + scene.add( axesHelper ); + +

    例子

    - -var axesHelper = new THREE.AxesHelper( 5 ); -scene.add( axesHelper ); - +

    + [example:webgl_geometries WebGL / geometries]
    + [example:webgl_geometry_convex WebGL / geometry / convex]
    + [example:webgl_geometry_spline_editor WebGL / geometry / spline / editor] +

    构造函数

    @@ -46,6 +46,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/Box3Helper.html b/docs/api/zh/helpers/Box3Helper.html index 282d90c240d722..59f03048aff33d 100644 --- a/docs/api/zh/helpers/Box3Helper.html +++ b/docs/api/zh/helpers/Box3Helper.html @@ -16,8 +16,7 @@

    [name]

    模拟3维包围盒 [page:Box3] 的辅助对象.

    - -

    例子

    +

    代码示例

    var box = new THREE.Box3(); @@ -27,7 +26,6 @@

    例子

    scene.add( helper );
    -

    构造函数

    @@ -59,6 +57,8 @@

    [method:void updateMatrixWorld]( [param:Boolean force] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/BoxHelper.html b/docs/api/zh/helpers/BoxHelper.html index c5a2d3d6abdc14..0ef92dd74c5209 100644 --- a/docs/api/zh/helpers/BoxHelper.html +++ b/docs/api/zh/helpers/BoxHelper.html @@ -20,21 +20,22 @@

    [name]

    所以当目标对象是精灵 [page:Sprite Sprites] 时将不能正常运行.

    - -

    例子

    - -
    [example:webgl_helpers WebGL / helpers]
    -
    [example:webgl_loader_nrrd WebGL / loader / nrrd]
    -
    [example:webgl_buffergeometry_drawcalls advanced / buffergeometry / drawcalls]
    - +

    代码示例

    - var sphere = new THREE.SphereGeometry(); - var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ) ); - var box = new THREE.BoxHelper( object, 0xffff00 ); - scene.add( box ); + var sphere = new THREE.SphereBufferGeometry(); + var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ) ); + var box = new THREE.BoxHelper( object, 0xffff00 ); + scene.add( box ); +

    例子

    + +

    + [example:webgl_helpers WebGL / helpers]
    + [example:webgl_loader_nrrd WebGL / loader / nrrd]
    + [example:webgl_buffergeometry_drawrange WebGL / buffergeometry / drawrange] +

    构造函数

    @@ -70,6 +71,8 @@

    [method:BoxHelper setFromObject]( [param:Object3D object] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/CameraHelper.html b/docs/api/zh/helpers/CameraHelper.html index 341351bdf42877..1fa0fb7a56e5a1 100644 --- a/docs/api/zh/helpers/CameraHelper.html +++ b/docs/api/zh/helpers/CameraHelper.html @@ -17,17 +17,19 @@

    [name]

    它使用 [page:LineSegments] 来模拟相机视锥体.

    -

    例子

    - -
    [example:webgl_camera WebGL / camera]
    -
    [example:webgl_geometry_extrude_splines WebGL / extrude / splines]
    +

    代码示例

    -var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); -var helper = new THREE.CameraHelper( camera ); -scene.add( helper ); + var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); + var helper = new THREE.CameraHelper( camera ); + scene.add( helper ); +

    例子

    +

    + [example:webgl_camera WebGL / camera]
    + [example:webgl_geometry_extrude_splines WebGL / extrude / splines] +

    构造函数

    @@ -57,7 +59,7 @@

    [property:object matrix]

    [property:object matrixAutoUpdate]

    - 请查看 [page:Object3D.matrixAutoUpdate]. 这里设置为 *false* 表示辅助对象 + 请查看 [page:Object3D.matrixAutoUpdate]. 这里设置为 *false* 表示辅助对象 使用相机的 [page:Object3D.matrixWorld matrixWorld].

    @@ -74,6 +76,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/DirectionalLightHelper.html b/docs/api/zh/helpers/DirectionalLightHelper.html index cf996e46117820..da2bd21a193ab1 100644 --- a/docs/api/zh/helpers/DirectionalLightHelper.html +++ b/docs/api/zh/helpers/DirectionalLightHelper.html @@ -18,17 +18,14 @@

    [name]

    其中包含了表示光位置的平面和表示光方向的线段.

    -

    例子

    +

    代码示例

    var light = new THREE.DirectionalLight( 0xFFFFFF ); - var helper = new THREE.DirectionalLightHelper( light, 5 ); - scene.add( helper ); -

    构造函数

    @@ -80,6 +77,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/GridHelper.html b/docs/api/zh/helpers/GridHelper.html index 8624db994b8be4..3f0fb94930ea72 100644 --- a/docs/api/zh/helpers/GridHelper.html +++ b/docs/api/zh/helpers/GridHelper.html @@ -14,17 +14,21 @@

    [name]

    坐标格辅助对象. 坐标格实际上是2维线数组.

    +

    代码示例

    -

    例子

    - - var size = 10; + + var size = 10; var divisions = 10; var gridHelper = new THREE.GridHelper( size, divisions ); scene.add( gridHelper ); - [example:webgl_helpers Example using various helpers] +

    例子

    + +

    + [example:webgl_helpers WebGL / helpers] +

    构造函数

    @@ -41,6 +45,8 @@

    [name]( [param:number size], [param:Number divisions], [param:Color colorCen

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/HemisphereLightHelper.html b/docs/api/zh/helpers/HemisphereLightHelper.html index 659c83edd41853..78ebb48f7eb6eb 100644 --- a/docs/api/zh/helpers/HemisphereLightHelper.html +++ b/docs/api/zh/helpers/HemisphereLightHelper.html @@ -17,14 +17,12 @@

    [name]

    半球形光源 [page:HemisphereLight HemisphereLight].

    -

    例子

    +

    代码示例

    -var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); - -var helper = new THREE.HemisphereLightHelper( light, 5 ); - -scene.add( helper ); + var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); + var helper = new THREE.HemisphereLightHelper( light, 5 ); + scene.add( helper ); @@ -74,6 +72,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/PlaneHelper.html b/docs/api/zh/helpers/PlaneHelper.html index 55794288490fc5..ab67045c4f49af 100644 --- a/docs/api/zh/helpers/PlaneHelper.html +++ b/docs/api/zh/helpers/PlaneHelper.html @@ -16,8 +16,7 @@

    [name]

    用于模拟平面 [page:Plane] 的辅助对象.

    - -

    例子

    +

    代码示例

    var plane = new THREE.Plane( new THREE.Vector3( 1, 1, 0.2 ), 3 ); @@ -60,6 +59,8 @@

    [method:void updateMatrixWorld]( [param:Boolean force] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/PointLightHelper.html b/docs/api/zh/helpers/PointLightHelper.html index 717aed6d720ef6..b5356611357b95 100644 --- a/docs/api/zh/helpers/PointLightHelper.html +++ b/docs/api/zh/helpers/PointLightHelper.html @@ -17,10 +17,7 @@

    [name]

    点光源 [page:PointLight].

    - -

    例子

    - - [example:webgl_helpers WebGL / helpers] +

    代码示例

    var pointLight = new THREE.PointLight( 0xff0000, 1, 100 ); @@ -32,8 +29,11 @@

    例子

    scene.add( pointLightHelper );
    +

    例子

    - +

    + [example:webgl_helpers WebGL / helpers] +

    构造函数

    @@ -79,6 +79,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/PolarGridHelper.html b/docs/api/zh/helpers/PolarGridHelper.html index df9c51e6bf7142..c7e8fbc5ae4627 100644 --- a/docs/api/zh/helpers/PolarGridHelper.html +++ b/docs/api/zh/helpers/PolarGridHelper.html @@ -14,10 +14,10 @@

    [name]

    极坐标格辅助对象. 坐标格实际上是2维线数组.

    +

    代码示例

    -

    例子

    - - var radius = 10; + + var radius = 10; var radials = 16; var circles = 8; var divisions = 64; @@ -25,8 +25,12 @@

    例子

    var helper = new THREE.PolarGridHelper( radius, radials, circles, divisions ); scene.add( helper );
    - [example:webgl_helpers Example using various helpers] +

    例子

    + +

    + [example:webgl_helpers WebGL / helpers] +

    构造函数

    @@ -45,6 +49,8 @@

    [name]( [param:Number radius], [param:Number radials], [param:Number circles

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/SkeletonHelper.html b/docs/api/zh/helpers/SkeletonHelper.html index f34d9d0595c655..d71e0a1c98ba52 100644 --- a/docs/api/zh/helpers/SkeletonHelper.html +++ b/docs/api/zh/helpers/SkeletonHelper.html @@ -17,28 +17,28 @@

    [name]

    该辅助对象使用 [page:LineBasicMaterial LineBasicMaterial] 材质.

    - -

    例子

    - - [example:webgl_animation_skinning_blending animation / skinning / blending]
    - [example:webgl_animation_skinning_morph animation / skinning / morph]
    - [example:webgl_loader_bvh loader / bvh ] +

    代码示例

    -var helper = new THREE.SkeletonHelper( mesh ); -helper.material.linewidth = 3; -scene.add( helper ); + var helper = new THREE.SkeletonHelper( skinnedMesh ); + scene.add( helper ); +

    例子

    +

    + [example:webgl_animation_skinning_blending WebGL / animation / skinning / blending]
    + [example:webgl_animation_skinning_morph WebGL / animation / skinning / morph]
    + [example:webgl_loader_bvh WebGL / loader / bvh ] +

    构造函数

    -

    [name]( object )

    +

    [name]( [param:Object3D object] )

    - object -- 可以是任何拥有一组骨 [page:Bone Bone] 作为子对象的对象.
    - 比如, 一个骨骼 [page:Skeleton Skeleton] 或 一个蒙皮网格 [page:SkinnedMesh SkinnedMesh]. + object -- Usually an instance of [page:SkinnedMesh]. However, any instance of [page:Object3D] can be used if it represents + a hierarchy of [page:Bone Bone]s (via [page:Object3D.children]).

    @@ -49,7 +49,7 @@

    [property:Array bones]

    辅助对象使用 [page:Line Lines] 渲染的骨数组.

    -

    [property:Object root]

    +

    [property:Object3D root]

    构造函数传入的对象.

    @@ -57,6 +57,8 @@

    [property:Object root]

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/helpers/SpotLightHelper.html b/docs/api/zh/helpers/SpotLightHelper.html index 81e7428b5304a6..ebc07345c6b3cd 100644 --- a/docs/api/zh/helpers/SpotLightHelper.html +++ b/docs/api/zh/helpers/SpotLightHelper.html @@ -14,13 +14,6 @@

    [name]

    用于模拟聚光灯 [page:SpotLight] 的锥形辅助对象.

    -

    例子

    - - View in Examples
    -

    其他例子

    - -
    [example:webgl_lights_spotlights lights / spotlights ]
    -

    代码示例

    var spotLight = new THREE.SpotLight( 0xffffff ); @@ -31,6 +24,8 @@

    代码示例

    scene.add( spotLightHelper );
    +

    例子

    +

    [example:webgl_lights_spotlights WebGL / lights / spotlights ]

    构造函数

    @@ -78,6 +73,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/AmbientLight.html b/docs/api/zh/lights/AmbientLight.html index aec1c47d9b94f2..da08e9c645112b 100644 --- a/docs/api/zh/lights/AmbientLight.html +++ b/docs/api/zh/lights/AmbientLight.html @@ -18,20 +18,19 @@

    [name]

    环境光不能用来投射阴影,因为它没有方向。

    +

    代码示例

    -

    示例

    + + var light = new THREE.AmbientLight( 0x404040 ); // soft white light + scene.add( light ); + + +

    例子

    - [example:canvas_camera_orthographic camera / orthographic ]
    - [example:canvas_interactive_voxelpainter interactive / voxelpainter ]
    - [example:canvas_materials materials ]
    - [example:canvas_sandbox sandbox ]
    - [example:webgl_animation_cloth animation / cloth ]
    - [example:webgl_animation_skinning_blending animation / skinning / blending ] + [example:webgl_animation_cloth animation / cloth ]
    + [example:webgl_animation_skinning_blending animation / skinning / blending ]

    -var light = new THREE.AmbientLight( 0x404040 ); // soft white light -scene.add( light ); -

    构造函数

    [name]( [param:Integer color], [param:Float intensity] )

    @@ -53,14 +52,6 @@

    [property:Boolean castShadow]

    -

    [property:Boolean isAmbientLight]

    -

    - 用来校验这个类或者派生类是不是环境光.默认是 *true*。

    - - 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。 -

    - -

    方法

    @@ -68,6 +59,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/DirectionalLight.html b/docs/api/zh/lights/DirectionalLight.html index 3fe866eb89ddb8..193365c56814bf 100644 --- a/docs/api/zh/lights/DirectionalLight.html +++ b/docs/api/zh/lights/DirectionalLight.html @@ -33,12 +33,17 @@

    关于位置、目标和旋转说明

    有关更新目标的详细信息,请参阅 [page:.target target] 下面的目标属性。

    +

    代码示例

    -

    示例

    + + // White directional light at half intensity shining from the top. + var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 ); + scene.add( directionalLight ); + + +

    例子

    - [example:canvas_morphtargets_horse morphtargets / horse ]
    [example:misc_controls_fly controls / fly ]
    - [example:webvr_cubes cubes ]
    [example:webgl_effects_parallaxbarrier effects / parallaxbarrier ]
    [example:webgl_effects_stereo effects / stereo ]
    [example:webgl_geometry_extrude_splines geometry / extrude / splines ]
    @@ -46,13 +51,6 @@

    示例

    [example:webgl_materials_cubemap_balls_reflection materials / cubemap / balls / reflection ]

    - - // White directional light at half intensity shining from the top. - var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 ); - scene.add( directionalLight ); - - -

    构造器

    [name]( [param:Integer color], [param:Float intensity] )

    @@ -65,7 +63,7 @@

    [name]( [param:Integer color], [param:Float intensity] )

    属性

    - 公共属性请查看基类 [page:Light Light]。 +

    公共属性请查看基类 [page:Light Light]。

    [property:Boolean castShadow]

    @@ -73,13 +71,6 @@

    [property:Boolean castShadow]

    查看 [page:DirectionalLightShadow] 了解详细信息。该属性默认为 *false*。

    -

    [property:Boolean isDirectionalLight]

    -

    - 用来校验这个类或者派生类是不是平行光.默认是 *true*。

    - - 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。 -

    -

    [property:Vector3 position]

    @@ -119,7 +110,7 @@

    [property:Object3D target]

    方法

    - 公共方法请查看基类 [page:Light Light]。 +

    公共方法请查看基类 [page:Light Light]。

    [method:DirectionalLight copy]( [param:DirectionalLight source] )

    @@ -128,6 +119,8 @@

    [method:DirectionalLight copy]( [param:DirectionalLight source] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/HemisphereLight.html b/docs/api/zh/lights/HemisphereLight.html index 60d0b26c67963b..9a7cb7abb2fa89 100644 --- a/docs/api/zh/lights/HemisphereLight.html +++ b/docs/api/zh/lights/HemisphereLight.html @@ -8,7 +8,7 @@ - [page:Object3D] → [page:Light] → + [page:Object3D] → [page:Light] →

    半球光([name])

    @@ -19,25 +19,27 @@

    半球光([name])

    半球光不能投射阴影。

    -

    示例

    +

    代码示例

    -
    + + var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); + scene.add( light ); + + +

    例子

    + +

    [example:webgl_lights_hemisphere lights / hemisphere ]
    - [example:misc_controls_pointerlock controls / pointerlock ]
    - [example:webgl_decals decals ]
    - [example:webgl_loader_collada_kinematics loader / collada / kinematics ]
    - [example:webgl_materials_lightmap materials / lightmap ]
    - [example:webgl_shaders_ocean shaders / ocean ] -

    - - -var light = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 ); -scene.add( light ); - + [example:misc_controls_pointerlock controls / pointerlock ]
    + [example:webgl_decals decals ]
    + [example:webgl_loader_collada_kinematics loader / collada / kinematics ]
    + [example:webgl_materials_lightmap materials / lightmap ]
    + [example:webgl_shaders_ocean shaders / ocean ] +

    构造器(Constructor)

    [name]( [param:Integer skyColor], [param:Integer groundColor], [param:Float intensity] )

    -

    +

    [page:Integer skyColor] - (可选参数) 天空中发出光线的颜色。 缺省值 0xffffff。
    [page:Integer groundColor] - (可选参数) 地面发出光线的颜色。 缺省值 0xffffff。
    [page:Float intensity] - (可选参数) 光照强度。 缺省值 1。

    @@ -68,13 +70,6 @@

    [property:Float groundColor]

    默认会创建 [page:Color] 并设置为白色(0xffffff)。

    -

    [property:Boolean isHemisphereLight]

    -

    - 用来校验这个类或者派生类是不是半球光。缺省值为 *true*。

    - - 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。 -

    -

    [property:Vector3 position]

    假如这个值设置等于 [page:Object3D.DefaultUp] (0, 1, 0),那么光线将会从上往下照射。 @@ -84,7 +79,7 @@

    [property:Vector3 position]

    方法(Methods)

    - 公共方法请查看基类 [page:Light Light]。 +

    公共方法请查看基类 [page:Light Light]。

    [method:HemisphereLight copy]( [param:HemisphereLight source] )

    @@ -94,6 +89,8 @@

    [method:HemisphereLight copy]( [param:HemisphereLight source] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/Light.html b/docs/api/zh/lights/Light.html index 39d4dcbcaef699..ff1e4c310551b2 100644 --- a/docs/api/zh/lights/Light.html +++ b/docs/api/zh/lights/Light.html @@ -47,13 +47,6 @@

    [property:Float intensity]


    -

    [property:Boolean isLight]

    -

    - 用来校验这个类或者派生类是不是平行光。默认是 *true*。

    - - 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。 -

    -

    Methods

    @@ -78,6 +71,8 @@

    [method:Object toJSON]( [param:object meta] )

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/PointLight.html b/docs/api/zh/lights/PointLight.html index 24ad2113e3603b..81cb87ae7324e9 100644 --- a/docs/api/zh/lights/PointLight.html +++ b/docs/api/zh/lights/PointLight.html @@ -15,29 +15,27 @@

    点光源([name])

    从一个点向各个方向发射的光源。一个常见的例子是模拟一个灯泡发出的光。

    - 该光源可以投射阴影 - 跳转至 [page:LightShadow] 查看更多细节。 + 该光源可以投射阴影 - 跳转至 [page:PointLightShadow] 查看更多细节。

    +

    代码示例

    -

    示例

    + + var light = new THREE.PointLight( 0xff0000, 1, 100 ); + light.position.set( 50, 50, 50 ); + scene.add( light ); + + +

    例子

    - [example:canvas_lights_pointlights lights / pointlights ]
    [example:webgl_lights_pointlights lights / pointlights ]
    [example:webgl_lights_pointlights2 lights / pointlights2 ]
    - [example:webgldeferred_animation animation ]
    [example:webgl_effects_anaglyph effects / anaglyph ]
    [example:webgl_geometry_text geometry / text ]
    [example:webgl_lensflares lensflares ]

    - -var light = new THREE.PointLight( 0xff0000, 1, 100 ); -light.position.set( 50, 50, 50 ); -scene.add( light ); - - -

    构造器(Constructor)

    [name]( [param:Integer color], [param:Float intensity], [param:Number distance], [param:Float decay] )

    @@ -47,7 +45,7 @@

    [name]( [param:Integer color], [param:Float intensity], [param:Number distan [page:Number distance] - 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.
    [page:Float decay] - 沿着光照距离的衰退量。缺省值 1。 - + 在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式中,decay = 2。

    创建一个新的点光源(PointLight)。 @@ -71,19 +69,12 @@

    [property:Float distance]

    缺省值为 *0.0*。

    -

    [property:Boolean isPointLight]

    -

    - 用来校验这个类或者派生类是不是点光源。默认是 *true*。

    - - 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。 -

    -

    [property:Float power]

    光功率
    在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式中, 表示以"流明(光通量单位)"为单位的光功率。 缺省值 - *4Math.PI*。

    - + 该值与 [page:.intensity intensity] 直接关联 power = intensity * 4π @@ -91,12 +82,12 @@

    [property:Float power]

    修改该值也会导致光强度的改变。

    -

    [property:LightShadow shadow]

    +

    [property:PointLightShadow shadow]

    - [page:LightShadow]用与计算此光照的阴影。

    - + [page:PointLightShadow]用与计算此光照的阴影。

    + 此对象的摄像机被设置为 [page:PerspectiveCamera.fov fov] 为90度,[page:PerspectiveCamera.aspect aspect]为1 - ,近裁剪面 [page:PerspectiveCamera.near near] 为0,远裁剪面[page:PerspectiveCamera.far far] + ,近裁剪面 [page:PerspectiveCamera.near near] 为0,远裁剪面[page:PerspectiveCamera.far far] 为500的透视摄像机 [page:PerspectiveCamera]。

    @@ -112,6 +103,8 @@

    [method:PointLight copy]( [param:PointLight source] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/RectAreaLight.html b/docs/api/zh/lights/RectAreaLight.html index 173e09bb689a6b..7eb47f1776b6d1 100644 --- a/docs/api/zh/lights/RectAreaLight.html +++ b/docs/api/zh/lights/RectAreaLight.html @@ -19,33 +19,31 @@

    平面光光源([name])

    • 不支持阴影。
    • 只支持 [page:MeshStandardMaterial MeshStandardMaterial] 和 [page:MeshPhysicalMaterial MeshPhysicalMaterial] 两种材质。
    • -
    • 你必须在你的场景中加入 [link:https://threejs.org/examples/js/lights/RectAreaLightUniformsLib.js RectAreaLightUniformsLib] ,并调用*init()*。
    • +
    • 你必须在你的场景中加入 [link:https://threejs.org/examples/jsm/lights/RectAreaLightUniformsLib.js RectAreaLightUniformsLib] ,并调用*init()*。

    +

    代码示例

    + + var width = 10; + var height = 10; + var intensity = 1; + var rectLight = new THREE.RectAreaLight( 0xffffff, intensity, width, height ); + rectLight.position.set( 5, 5, 0 ); + rectLight.lookAt( 0, 0, 0 ); + scene.add( rectLight ) -

    示例

    + rectLightHelper = new THREE.RectAreaLightHelper( rectLight ); + scene.add( rectLightHelper ); +
    + +

    例子

    [example:webgl_lights_rectarealight WebGL / rectarealight ] - - -var width = 10; -var height = 10; -var intensity = 1; -var rectLight = new THREE.RectAreaLight( 0xffffff, intensity, width, height ); -rectLight.position.set( 5, 5, 0 ); -rectLight.lookAt( 0, 0, 0 ); -scene.add( rectLight ) - -rectLightHelper = new THREE.RectAreaLightHelper( rectLight ); -scene.add( rectLightHelper ); - -

    -

    构造器(Constructor)

    @@ -64,13 +62,6 @@

    属性(Properties)

    公共属性请查看基类[page:Light Light]。

    -

    [property:Boolean isRectAreaLight]

    -

    - 用来校验这个类或者它的派生类是不是平面光光源。缺省值是 *true*。

    - - 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。 -

    -

    方法(Methods)

    公共方法请查看基类 [page:Light Light]。 @@ -82,6 +73,8 @@

    [method:RectAreaLight copy]( [param:RectAreaLight source] )

    将所有属性的值从源 [page:RectAreaLight source] 复制到此平面光光源对象。

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/SpotLight.html b/docs/api/zh/lights/SpotLight.html index d257e03cb77c90..38a519d463e797 100644 --- a/docs/api/zh/lights/SpotLight.html +++ b/docs/api/zh/lights/SpotLight.html @@ -13,37 +13,11 @@

    聚光灯([name])

    - 聚光灯是从一个方向上的一个点发出,沿着一个圆锥体,它离光越远,它的尺寸就越大。

    + 光线从一个点沿一个方向射出,随着光线照射的变远,光线圆锥体的尺寸也逐渐增大。

    该光源可以投射阴影 - 跳转至 [page:SpotLightShadow] 查看更多细节。

    - - - -

    示例

    - - -

    - [example:webgl_lights_spotlight View in Examples ] -

    - -

    其他例子

    - -

    - [example:webgl_interactive_cubes_gpu interactive / cubes / gpu ]
    - [example:webgl_interactive_draggablecubes interactive / draggablecubes ]
    - [example:webgl_materials_bumpmap_skin materials / bumpmap / skin ]
    - [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic ]
    - [example:webgl_loader_md2 loader / md2 ]
    - [example:webgl_shading_physical shading / physical ]
    - [example:webgl_materials_bumpmap materials / bumpmap]
    - [example:webgl_shading_physical shading / physical]
    - [example:webgl_shadowmap shadowmap]
    - [example:webgl_shadowmap_performance shadowmap / performance]
    - [example:webgl_shadowmap_viewer shadowmap / viewer] -

    -

    代码示例

    // white spotlight shining from the side, casting a shadow @@ -63,6 +37,13 @@

    代码示例

    scene.add( spotLight );
    +

    例子

    + +

    + [example:webgl_lights_spotlight lights / spotlight ]
    + [example:webgl_lights_spotlights lights / spotlights ] +

    +

    构造器(Constructor)

    @@ -80,7 +61,7 @@

    [name]( [param:Integer color], [param:Float intensity], [param:Float distanc

    属性(Properties)

    - 公共属性请查看基类[page:Light Light]。 +

    公共属性请查看基类[page:Light Light]。

    [property:Float angle]

    @@ -108,13 +89,6 @@

    [property:Float distance]

    缺省值为 *0.0*。

    -

    [property:Boolean isSpotLight]

    -

    - 用来校验这个类或者它的派生类是不是聚光灯光源。缺省值是 *true*。

    - - 不应该去改变这个变量,因为内部使用这个变量做了些优化的工作。 -

    -

    [property:Float penumbra]

    聚光锥的半影衰减百分比。在0和1之间的值。 @@ -131,7 +105,7 @@

    [property:Float power]

    光功率
    在 [page:WebGLRenderer.physicallyCorrectLights physically correct] 模式中, 表示以"流明(光通量单位)"为单位的光功率。 缺省值 - *4Math.PI*。

    - + 该值与 [page:.intensity intensity] 直接关联 power = intensity * 4π @@ -169,13 +143,15 @@

    [property:Object3D target]

    方法(Methods)

    - 公共方法请查看基类 [page:Light Light]。 +

    公共方法请查看基类 [page:Light Light]。

    [method:SpotLight copy]( [param:SpotLight source] )

    将所有属性的值从源 [page:SpotLight source] 复制到此聚光灯光源对象。

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/lights/shadows/DirectionalLightShadow.html b/docs/api/zh/lights/shadows/DirectionalLightShadow.html index 6992201b9daa6f..c1fd298e9a6e25 100644 --- a/docs/api/zh/lights/shadows/DirectionalLightShadow.html +++ b/docs/api/zh/lights/shadows/DirectionalLightShadow.html @@ -18,46 +18,44 @@

    [name]

    与其他阴影类不同,它是使用OrthographicCamera来计算阴影,而不是PerspectiveCamera。这是因为来自DirectionalLight的光线是平行的。

    -

    例子

    -

    - -//Create a WebGLRenderer and turn on shadows in the renderer -var renderer = new THREE.WebGLRenderer(); -renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - -//Create a DirectionalLight and turn on shadows for the light -var light = new THREE.DirectionalLight( 0xffffff, 1, 100 ); -light.position.set( 0, 1, 0 ); //default; light shining from top -light.castShadow = true; // default false -scene.add( light ); - -//Set up shadow properties for the light -light.shadow.mapSize.width = 512; // default -light.shadow.mapSize.height = 512; // default -light.shadow.camera.near = 0.5; // default -light.shadow.camera.far = 500; // default - -//Create a sphere that cast shadows (but does not receive them) -var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); -var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); -var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -sphere.castShadow = true; //default is false -sphere.receiveShadow = false; //default -scene.add( sphere ); - -//Create a plane that receives shadows (but does not cast them) -var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); -var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.receiveShadow = true; -scene.add( plane ); - -//Create a helper for the shadow camera (optional) -var helper = new THREE.CameraHelper( light.shadow.camera ); -scene.add( helper ); - -

    +

    代码示例

    + + //Create a WebGLRenderer and turn on shadows in the renderer + var renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + //Create a DirectionalLight and turn on shadows for the light + var light = new THREE.DirectionalLight( 0xffffff, 1, 100 ); + light.position.set( 0, 1, 0 ); //default; light shining from top + light.castShadow = true; // default false + scene.add( light ); + + //Set up shadow properties for the light + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500; // default + + //Create a sphere that cast shadows (but does not receive them) + var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); + var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + //Create a plane that receives shadows (but does not cast them) + var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); + var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + //Create a helper for the shadow camera (optional) + var helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); +

    构造函数

    [name]( )

    @@ -76,14 +74,15 @@

    [property:Camera camera]

    在光的世界里。这用于生成场景的深度图;从光的角度来看,其他物体背后的物体将处于阴影中。

    -

    方法

    - 有关常用方法,请参阅基础[page:LightShadow LightShadow]类。 + 有关常用方法,请参阅基础[page:LightShadow LightShadow]类。

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    diff --git a/docs/api/zh/lights/shadows/LightShadow.html b/docs/api/zh/lights/shadows/LightShadow.html index b20431bc480469..ed96d88ee99472 100644 --- a/docs/api/zh/lights/shadows/LightShadow.html +++ b/docs/api/zh/lights/shadows/LightShadow.html @@ -12,58 +12,17 @@

    [name]

    - 这在 [page:PointLight PointLights] 内部用于计算阴影,也可用作其他阴影类的基类。 + 该类作为其他阴影类的基类来使用。

    -

    例子

    -

    - -//Create a WebGLRenderer and turn on shadows in the renderer -var renderer = new THREE.WebGLRenderer(); -renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - -//Create a PointLight and turn on shadows for the light -var light = new THREE.PointLight( 0xffffff, 1, 100 ); -light.position.set( 0, 10, 0 ); -light.castShadow = true; // default false -scene.add( light ); - -//Set up shadow properties for the light -light.shadow.mapSize.width = 512; // default -light.shadow.mapSize.height = 512; // default -light.shadow.camera.near = 0.5; // default -light.shadow.camera.far = 500 // default - -//Create a sphere that cast shadows (but does not receive them) -var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); -var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); -var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -sphere.castShadow = true; //default is false -sphere.receiveShadow = false; //default -scene.add( sphere ); - -//Create a plane that receives shadows (but does not cast them) -var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); -var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.receiveShadow = true; -scene.add( plane ); - -//Create a helper for the shadow camera (optional) -var helper = new THREE.CameraHelper( light.shadow.camera ); -scene.add( helper ); - -

    -

    构造函数

    [name]( [param:Camera camera] )

    [page:Camera camera] - 在光的世界里

    - 创建一个新的[name]。这不能直接调用的 - 它由[page:PointLight]在内部调用,或者由其他阴影用作基类。 + 创建一个新的[name]。这不能直接调用的 - 它由其他阴影用作基类。

    属性

    @@ -84,6 +43,11 @@

    [property:WebGLRenderTarget map]

    使用内置摄像头生成的深度图;超出像素深度的位置在阴影中。在渲染期间内部计算。

    +

    [property:WebGLRenderTarget mapPass]

    +

    + The distribution map generated using the internal camera; an occlusion is calculated based + on the distribution of depths. Computed internally during rendering. +

    [property:Vector2 mapSize]

    @@ -104,18 +68,41 @@

    [property:Float radius]

    将此值设置为大于1的值将模糊阴影的边缘。
    + 较高的值会在阴影中产生不必要的条带效果 - 更大的[page:.mapSize mapSize]将允许在这些效果变得可见之前使用更高的值。
    + If [page:WebGLRenderer.shadowMap.type] is set to [page:Renderer PCFSoftShadowMap], radius has + no effect and it is recommended to increase softness by decreasing [page:.mapSize mapSize] instead.

    + + 请注意,如果[page:WebGLRenderer.shadowMap.type]设置为[page:Renderer BasicShadowMap],将会无效。 +

    - 较高的值会在阴影中产生不必要的条带效果 - 更大的[page:.mapSize mapSize]将允许在这些效果变得可见之前使用更高的值。

    - 请注意,如果[page:WebGLRenderer.shadowMap.type]设置为[page:Renderer BasicShadowMap],将会无效。 +

    方法

    + +

    [method:Vector2 getFrameExtents]()

    +

    + Used internally by the renderer to extend the shadow map to contain all viewports +

    + +

    [method:null updateMatrices]( [param:Light light] )

    +

    + Update the matrices for the camera and shadow, used internally by the renderer.

    + light -- the light for which the shadow is being rendered.

    +

    [method:Frustum getFrustum]()

    +

    + Gets the shadow cameras frustum. Used internally by the renderer to cull objects. +

    + +

    [method:number getViewportCount]()

    +

    + Used internally by the renderer to get the number of viewports that need to be rendered for this shadow. +

    -

    方法

    [method:LightShadow copy]( [param:LightShadow source] )

    - 将[page:LightShadow]中的所有属性的值复制到 SpotLight。 + 将[page:LightShadow source]中的所有属性的值复制到该Light。

    [method:LightShadow clone]()

    @@ -129,7 +116,8 @@

    [method:Object toJSON]()

    源码

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    diff --git a/docs/api/zh/lights/shadows/PointLightShadow.html b/docs/api/zh/lights/shadows/PointLightShadow.html new file mode 100644 index 00000000000000..0c1320701e4975 --- /dev/null +++ b/docs/api/zh/lights/shadows/PointLightShadow.html @@ -0,0 +1,90 @@ + + + + + + + + + + + +

    [name]

    + +

    + 该类在内部由[page:PointLight PointLights]所使用,以用于计算阴影。 +

    + + +

    代码示例

    + + + //Create a WebGLRenderer and turn on shadows in the renderer + var renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + //Create a PointLight and turn on shadows for the light + var light = new THREE.PointLight( 0xffffff, 1, 100 ); + light.position.set( 0, 10, 0 ); + light.castShadow = true; // default false + scene.add( light ); + + //Set up shadow properties for the light + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500 // default + + //Create a sphere that cast shadows (but does not receive them) + var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); + var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + //Create a plane that receives shadows (but does not cast them) + var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); + var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + //Create a helper for the shadow camera (optional) + var helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); + + +

    构造函数

    +

    [name]( )

    +

    + 创建一个新的[name]。该方法不是直接调用的 —— 其在内部由[page:PointLight]调用。 +

    + +

    属性

    +

    + 共有属性请参见其基类[page:LightShadow LightShadow]。 +

    + +

    方法

    + +

    + 共有方法请参见其基类[page:LightShadow LightShadow]。 +

    + +

    [method:null updateMatrices]( [param:Light light], [param:number viewportIndex])

    +

    + Update the matrices for the camera and shadow, used internally by the renderer.

    + + light -- the light for which the shadow is being rendered.
    + viewportIndex -- calculates the matrix for this viewport +

    + +

    源代码

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + + diff --git a/docs/api/zh/lights/shadows/SpotLightShadow.html b/docs/api/zh/lights/shadows/SpotLightShadow.html index da851e75cb633f..6e0579ec811fae 100644 --- a/docs/api/zh/lights/shadows/SpotLightShadow.html +++ b/docs/api/zh/lights/shadows/SpotLightShadow.html @@ -16,68 +16,61 @@

    [name]

    这在SpotLights内部用于计算阴影。

    -

    例子

    -

    - -//Create a WebGLRenderer and turn on shadows in the renderer -var renderer = new THREE.WebGLRenderer(); -renderer.shadowMap.enabled = true; -renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - -//Create a SpotLight and turn on shadows for the light -var light = new THREE.SpotLight( 0xffffff ); -light.castShadow = true; // default false -scene.add( light ); - -//Set up shadow properties for the light -light.shadow.mapSize.width = 512; // default -light.shadow.mapSize.height = 512; // default -light.shadow.camera.near = 0.5; // default -light.shadow.camera.far = 500 // default - -//Create a sphere that cast shadows (but does not receive them) -var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); -var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); -var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); -sphere.castShadow = true; //default is false -sphere.receiveShadow = false; //default -scene.add( sphere ); - -//Create a plane that receives shadows (but does not cast them) -var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); -var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.receiveShadow = true; -scene.add( plane ); - -//Create a helper for the shadow camera (optional) -var helper = new THREE.CameraHelper( light.shadow.camera ); -scene.add( helper ); - -

    - +

    代码示例

    + + + //Create a WebGLRenderer and turn on shadows in the renderer + var renderer = new THREE.WebGLRenderer(); + renderer.shadowMap.enabled = true; + renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + + //Create a SpotLight and turn on shadows for the light + var light = new THREE.SpotLight( 0xffffff ); + light.castShadow = true; // default false + scene.add( light ); + + //Set up shadow properties for the light + light.shadow.mapSize.width = 512; // default + light.shadow.mapSize.height = 512; // default + light.shadow.camera.near = 0.5; // default + light.shadow.camera.far = 500 // default + + //Create a sphere that cast shadows (but does not receive them) + var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 ); + var sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } ); + var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial ); + sphere.castShadow = true; //default is false + sphere.receiveShadow = false; //default + scene.add( sphere ); + + //Create a plane that receives shadows (but does not cast them) + var planeGeometry = new THREE.PlaneBufferGeometry( 20, 20, 32, 32 ); + var planeMaterial = new THREE.MeshStandardMaterial( { color: 0x00ff00 } ) + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.receiveShadow = true; + scene.add( plane ); + + //Create a helper for the shadow camera (optional) + var helper = new THREE.CameraHelper( light.shadow.camera ); + scene.add( helper ); +

    构造函数

    - 构造函数创建一个 [param:PerspectiveCamera PerspectiveCamera] 来管理阴影的世界视图 +

    构造函数创建一个 [param:PerspectiveCamera PerspectiveCamera] 来管理阴影的世界视图

    +

    属性

    - 有关常用属性,请参阅基础LightShadow类。 +

    有关常用属性,请参阅基础LightShadow类。

    +

    [property:Camera camera]

    在光的世界里。这用于生成场景的深度图;从光的角度来看,其他物体背后的物体将处于阴影中。

    默认值为PerspectiveCamera,近剪裁平面为0.5。 fov将通过更新方法跟踪拥有SpotLight的角度属性。同样,aspect属性将跟踪mapSize的方面。如果设置了灯光的距离属性,则远剪裁平面将跟踪该值,否则默认为500。 - -

    - -

    [property:Boolean isSpotLightShadow]

    -

    - - 用于检查此类或派生类是否为聚光灯阴影。默认为true。

    - 您不应该更改它,因为它在内部用于优化。

    方法

    - 有关常用方法,请参阅基础LightShadow类。 +

    有关常用方法,请参阅基础LightShadow类。

    +

    [method:SpotLightShadow update]( [param:SpotLight light] )

    根据传入的[page:SpotLight light]更新内部透视[page:.camera camera]。 @@ -85,6 +78,8 @@

    [method:SpotLightShadow update]( [param:SpotLight light] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/lights/[name].js src/lights/[name].js] +

    diff --git a/docs/api/zh/loaders/AnimationLoader.html b/docs/api/zh/loaders/AnimationLoader.html index 4b17d4149ea70c..b5e28626db10b8 100644 --- a/docs/api/zh/loaders/AnimationLoader.html +++ b/docs/api/zh/loaders/AnimationLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -15,7 +17,7 @@

    [name]

    内部使用 [page:FileLoader] 来加载文件。

    -

    例子

    +

    代码示例

    // 初始化一个加载器 @@ -53,13 +55,10 @@

    [name]( [param:LoadingManager manager] )

    属性

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager]。默认为[page:DefaultLoadingManager]. -

    +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -69,7 +68,7 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onProgress] — 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含[page:Integer total]和[page:Integer loaded]字节。
    [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载并将动画传递给onLoad。 + 从URL中进行加载并将动画传递给onLoad。

    [method:Array parse]( [param:JSON json] )

    @@ -81,6 +80,8 @@

    [method:Array parse]( [param:JSON json] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/AudioLoader.html b/docs/api/zh/loaders/AudioLoader.html index c488b6bf6e20d9..18f1b0f282d02b 100644 --- a/docs/api/zh/loaders/AudioLoader.html +++ b/docs/api/zh/loaders/AudioLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -16,7 +18,7 @@

    [name]

    内部默认使用[page:FileLoader]来加载文件。

    -

    例子

    +

    代码示例

    // 初始化一个监听 @@ -62,23 +64,18 @@

    例子

    构造函数

    -

    [name]( [param:String context], [param:LoadingManager manager] )

    +

    [name]( [param:LoadingManager manager] )

    - [page:String context] — 加载器使用的[page:String AudioContext]。 默认为[page:String window.AudioContext].
    [page:LoadingManager manager] — 加载器使用的[page:LoadingManager loadingManager]。默认为[page:LoadingManager THREE.DefaultLoadingManager].

    创建一个新的[name].

    属性

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager]。默认为[page:DefaultLoadingManager]. -

    - +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -89,11 +86,13 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载并将已经加载的[page:String AudioBuffer]传递给onLoad。 + 从URL中进行加载并将已经加载的[page:String AudioBuffer]传递给onLoad。

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/BufferGeometryLoader.html b/docs/api/zh/loaders/BufferGeometryLoader.html index be792642c543ef..e64c340be175d7 100644 --- a/docs/api/zh/loaders/BufferGeometryLoader.html +++ b/docs/api/zh/loaders/BufferGeometryLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -15,9 +17,7 @@

    [name]

    内部使用[page:FileLoader]来加载文件。

    -

    例子

    - - [example:webgl_geometry_colors_lookuptable WebGL / geometry / colors / lookuptable] +

    代码示例

    // 初始化一个加载器 @@ -47,6 +47,12 @@

    例子

    );
    +

    例子

    + +

    + [example:webgl_performance WebGL / performance] +

    +

    构造函数

    [name]( [param:LoadingManager manager] )

    @@ -57,15 +63,11 @@

    [name]( [param:LoadingManager manager] )

    创建一个新的[name].

    -

    属性

    - -

    [property:LoadingManager manager]

    -

    - 正在使用的[page:LoadingManager loadingManager]。默认为[page:DefaultLoadingManager]. -

    +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -76,7 +78,7 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onError] —在加载错误时被调用。

    - 从URL中进行加载,并将已经以解析的响应内容传递给onLoad。 + 从URL中进行加载,并将已经以解析的响应内容传递给onLoad。

    [method:BufferGeometry parse]( [param:Object json] )

    @@ -87,6 +89,8 @@

    [method:BufferGeometry parse]( [param:Object json] )

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/Cache.html b/docs/api/zh/loaders/Cache.html index 15fd0b926610b6..693cad2f6f86f7 100644 --- a/docs/api/zh/loaders/Cache.html +++ b/docs/api/zh/loaders/Cache.html @@ -11,9 +11,17 @@

    [name]

    - 一个简单的缓存系统,内部使用[page:FileLoader]。 + 一个简单的缓存系统,内部使用[page:FileLoader]。

    +

    代码示例

    + +

    + 要在所有使用[page:FileLoader]的加载器上启用缓存, 需设置

    + +THREE.Cache.enabled = true. + +

    例子

    @@ -22,15 +30,6 @@

    例子

    [example:webgl_loader_ttf WebGL / loader / ttf]

    -

    Usage

    - -

    - 要在所有使用[page:FileLoader]的加载器上启用缓存, 需设置

    - -THREE.Cache.enabled = true. - - -

    属性

    [property:Boolean enabled]

    @@ -47,7 +46,7 @@

    [method:null add]( [param:String key], file )

    [page:String key] — 通过引用缓存文件的[page:String key]。
    [page:Object file] — 所被缓存的文件

    - 使用key为引用文件增加一个缓存入口。如果该key已持有一个文件,则会被覆盖。 + 使用key为引用文件增加一个缓存入口。如果该key已持有一个文件,则会被覆盖。

    [method:null get]( [param:String key] )

    @@ -70,6 +69,8 @@

    [method:null clear]()

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/CompressedTextureLoader.html b/docs/api/zh/loaders/CompressedTextureLoader.html index 57f06e8a7da6f1..17701e3fae6f3b 100644 --- a/docs/api/zh/loaders/CompressedTextureLoader.html +++ b/docs/api/zh/loaders/CompressedTextureLoader.html @@ -8,18 +8,20 @@ + [page:Loader] → +

    [name]

    - 基于块的纹理加载器 (dds, pvr, ...)的抽象类。 - 内部使用[page:FileLoader]来加载文件。 + 基于块的纹理加载器 (dds, pvr, ...)的抽象类。 + 内部使用[page:FileLoader]来加载文件。

    例子

    - 请参考[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/DDSLoader.js DDSLoader] - 和[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PVRLoader.js PVRLoader] + 请参考[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/DDSLoader.js DDSLoader] + 和[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PVRLoader.js PVRLoader] 子类的例子

    @@ -33,20 +35,11 @@

    [name]( [param:LoadingManager manager] )

    创建一个新的[name].

    -

    属性

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager]。默认为[page:DefaultLoadingManager]。 -

    - -

    [property:String path]

    -

    加载的基本路径。请参考[page:.setPath]。默认为*undefined*.

    - - +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有属性请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -57,16 +50,13 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载,并将被加载的纹理传递给onLoad。 -

    - -

    [method:FileLoader setPath]( [param:String path] )

    -

    - 设置加载文件的基本路径或URL。当加载同一目录中的许多模型,此方法将很有用。 + 从URL中进行加载,并将被加载的纹理传递给onLoad。

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/CubeTextureLoader.html b/docs/api/zh/loaders/CubeTextureLoader.html index faa2163d0d8bd3..36236e738644b1 100644 --- a/docs/api/zh/loaders/CubeTextureLoader.html +++ b/docs/api/zh/loaders/CubeTextureLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -15,16 +17,7 @@

    [name]

    内部使用[page:ImageLoader]来加载文件。

    -

    例子

    - -

    - [example:webgl_materials_cubemap materials / cubemap]
    - [example:webgl_materials_cubemap_balls_reflection materials / cubemap / balls / reflection]
    - [example:webgl_materials_cubemap_balls_refraction materials / cubemap / balls / refraction]
    - [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic]
    - [example:webgl_materials_cubemap_dynamic2 materials / cubemap / dynamic2]
    - [example:webgl_materials_cubemap_refraction materials / cubemap / refraction] -

    +

    代码示例

    var scene = new THREE.Scene(); @@ -40,6 +33,17 @@

    例子

    ] );
    +

    例子

    + +

    + [example:webgl_materials_cubemap materials / cubemap]
    + [example:webgl_materials_cubemap_balls_reflection materials / cubemap / balls / reflection]
    + [example:webgl_materials_cubemap_balls_refraction materials / cubemap / balls / refraction]
    + [example:webgl_materials_cubemap_dynamic materials / cubemap / dynamic]
    + [example:webgl_materials_cubemap_dynamic2 materials / cubemap / dynamic2]
    + [example:webgl_materials_cubemap_refraction materials / cubemap / refraction] +

    +

    构造函数

    [name]( [param:LoadingManager manager] )

    @@ -49,54 +53,33 @@

    [name]( [param:LoadingManager manager] )

    创建一个新的[name].

    -

    属性

    - -

    [property:String crossOrigin]

    -

    - 如果设置了,在开始加载前, 将为图片分配 [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - 属性,其值为 *crossOrigin*, 默认为"anonymous"。 -

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager]。默认为[page:DefaultLoadingManager]。 -

    - -

    [property:String path]

    -

    加载加载的文件的基本路径。 请参考[page:.setPath]。默认为*undefined*.

    - - +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String urls], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    [page:String urls] — 数组长度为6的图像数组,数组内容为URL,每一个URL用于CubeTexture的每一侧。 这些URL将被指定顺序: pos-x, neg-x, pos-y, neg-y, pos-z, neg-z. 数组内容也可以为 [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URIs].
    - 请注意,一般来说,在立方体贴图坐标系中,当查找positive-z轴时,positive-x表示右侧 - - 换句话说,此坐标系使用左手坐标系。 + 请注意,一般来说,在立方体贴图坐标系中,当查找positive-z轴时,positive-x表示右侧 + - 换句话说,此坐标系使用左手坐标系。 由于three.js使用右手坐标系, 环境贴图将在three.js进行pos-x和neg-x进行交互.
    [page:Function onLoad] — 加载完成时将调用。回调参数是已被加载的[page:Texture texture].
    [page:Function onProgress] — 将在加载过程中进行调用。参数为XMLHttpRequest实例, - 其中包含 [page:Integer total] 和 [page:Integer loaded] 字节。
    + 其中包含 [page:Integer total] 和 [page:Integer loaded] 字节。
    [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载,并将被加载的[page:Texture texture]传递给onLoad。 + 从URL中进行加载,并将被加载的[page:Texture texture]传递给onLoad。

    -

    [method:null setCrossOrigin]( [param:String value] )

    -

    设置[page:.crossOrigin]的属性。

    +

    -

    [method:FileLoader setPath]( [param:String path] )

    - 设置加载文件的基本路径或URL。当加载同一目录中的许多模型,此方法将很有用。 + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

    - -

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/loaders/DataTextureLoader.html b/docs/api/zh/loaders/DataTextureLoader.html index 96929b2cee168d..0f63995c315a8c 100644 --- a/docs/api/zh/loaders/DataTextureLoader.html +++ b/docs/api/zh/loaders/DataTextureLoader.html @@ -8,10 +8,12 @@ + [page:Loader] → +

    [name]

    - 用于加载二进制文件格式的(rgbe, hdr, ...)的抽象类。 + 用于加载二进制文件格式的(rgbe, hdr, ...)的抽象类。 内部使用[page:FileLoader]来加载文件, 和创建一个新的 [page:DataTexture].

    @@ -19,7 +21,7 @@

    [name]

    例子

    - 请参考[link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/RGBELoader.js RGBELoader] + 请参考[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/RGBELoader.js RGBELoader] 这个子类的例子。

    @@ -33,16 +35,11 @@

    [name]( [param:LoadingManager manager] )

    创建一个新的[name].

    -

    属性

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager]。默认为[page:DefaultLoadingManager]. -

    - +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -53,11 +50,13 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onError] —在加载错误时被调用。

    - 从URL中进行加载,并将被加载的纹理传递给onLoad。 + 从URL中进行加载,并将被加载的纹理传递给onLoad。

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/FileLoader.html b/docs/api/zh/loaders/FileLoader.html index b25abbba88d667..ea21b04c3e6b33 100644 --- a/docs/api/zh/loaders/FileLoader.html +++ b/docs/api/zh/loaders/FileLoader.html @@ -8,19 +8,16 @@ + [page:Loader] →

    [name]

    - 使用XMLHttpRequest来加载资源的低级类,并由大多数加载器内部使用。 - 它也可以直接用于加载任何没有对应加载器的文件类型。 + 使用XMLHttpRequest来加载资源的低级类,并由大多数加载器内部使用。 + 它也可以直接用于加载任何没有对应加载器的文件类型。

    -

    例子

    -

    - [example:webgl_loader_msgpack WebGL / loader / msgpack]
    - [example:webgl_morphtargets_human WebGL / morphtargets / human]
    -

    +

    代码示例

    var loader = new THREE.FileLoader(); @@ -49,13 +46,12 @@

    例子

    注意: - 必须启用缓存 + 必须启用缓存 THREE.Cache.enabled = true; - 这是一个全局属性,只需要设置一次,供内部使用FileLoader的所有加载器使用。 + 这是一个全局属性,只需要设置一次,供内部使用FileLoader的所有加载器使用。 [page:Cache Cache] 是​​一个缓存模块,用于保存通过此加载器发出的每个请求的响应,因此每个文件都会被请求一次。

    -

    构造函数

    [name] ( [param:LoadingManager manager] )

    @@ -64,13 +60,8 @@

    [name] ( [param:LoadingManager manager] )

    默认为 [page:DefaultLoadingManager].

    -

    属性

    - -

    [property:LoadingManager manager]

    -

    - [page:LoadingManager loadingManager] 是加载器所使用的加载管理器,默认为 [page:DefaultLoadingManager]. -

    +

    共有属性请参见其基类[page:Loader]。

    [property:String mimeType]

    @@ -78,9 +69,6 @@

    [property:String mimeType]

    请参考 [page:.setMimeType]。默认为 *undefined*。

    -

    [property:String path]

    -

    将要加载的文件的基本路径。请参考 [page:.setPath]。 默认为 *undefined*.

    -

    [property:object requestHeader]

    [link:https://developer.mozilla.org/en-US/docs/Glossary/Request_header request header] 在HTTP 请求中使用。 请参考 [page:.setRequestHeader]。 默认为 *undefined*.

    @@ -89,12 +77,12 @@

    [property:String responseType]

    [property:String withCredentials]

    - XMLHttpRequest是否使用证书。 请参考 [page:.setWithCredentials]. - 默认为 *undefined*. + XMLHttpRequest是否使用证书。 请参考 [page:.setWithCredentials]. + 默认为 *undefined*.

    -

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -102,21 +90,16 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].
    [page:Function onLoad] (可选) — 加载完成时将调用。回调参数将是加载的响应。
    [page:Function onProgress] (可选) — 将在加载过程中进行调用。参数将是XMLHttpRequest实例, - 其中包含 [page:Integer total] 和 [page:Integer loaded] 字节
    + 其中包含 [page:Integer total] 和 [page:Integer loaded] 字节
    [page:Function onError] (可选) — 在加载错误时被调用。

    - 加载URL并将响应传递给onLoad函数。 + 加载URL并将响应传递给onLoad函数。

    [method:FileLoader setMimeType]( [param:String mimeType] )

    - 设置正在加载的文件预期类型 [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types mimeType] - 。请注意,在许多情况下,这将自动确定,因此默认情况下它是 *undefined* 。 -

    - -

    [method:FileLoader setPath]( [param:String path] )

    -

    - 设置加载文件的基本路径或URL。当加载同一目录中的许多模型,此方法将很有用。 + 设置正在加载的文件预期类型 [link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types mimeType] + 。请注意,在许多情况下,这将自动确定,因此默认情况下它是 *undefined* 。

    [method:FileLoader setRequestHeader]( [param:object requestHeader] )

    @@ -138,13 +121,15 @@

    [method:FileLoader setResponseType]( [param:String responseType] )

    [method:FileLoader setWithCredentials]( [param:Boolean value] )

    - XMLHttpRequest是否使用cookie、授权头或TLS客户端证书等凭据。 请参考 [link:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials XMLHttpRequest.withCredentials].
    - 请注意,当您在本地或从同一域加载文件,则该方法无效。 + XMLHttpRequest是否使用cookie、授权头或TLS客户端证书等凭据。 请参考 [link:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials XMLHttpRequest.withCredentials].
    + 请注意,当您在本地或从同一域加载文件,则该方法无效。

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/FontLoader.html b/docs/api/zh/loaders/FontLoader.html index e8541ac5627b80..331ef5135f3993 100644 --- a/docs/api/zh/loaders/FontLoader.html +++ b/docs/api/zh/loaders/FontLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -17,12 +19,7 @@

    [name]

    你可以使用[link:https://gero3.github.io/facetype.js/ facetype.js]在线转换字体。

    -

    例子

    - -

    - [example:webgl_geometry_text_shapes geometry / text / shapes ]
    - [example:webgl_geometry_text geometry / text ] -

    +

    代码示例

    var loader = new THREE.FontLoader(); @@ -48,6 +45,13 @@

    例子

    );
    +

    例子

    + +

    + [example:webgl_geometry_text_shapes geometry / text / shapes ]
    + [example:webgl_geometry_text geometry / text ] +

    +

    构造函数

    [name]( [param:LoadingManager manager] )

    @@ -57,16 +61,10 @@

    [name]( [param:LoadingManager manager] )

    属性

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager]。默认值为[page:DefaultLoadingManager]. -

    - -

    [property:String path]

    -

    所要加载字体的基本路径。 具体参考[page:.setPath]。 默认为*undefined*.

    +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -76,7 +74,7 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onProgress] — 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含[page:Integer total]和[page:Integer loaded]字节。
    [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载,并将被加载的[page:Texture texture]传递给onLoad。 + 从URL中进行加载,并将被加载的[page:Texture texture]传递给onLoad。

    [method:Font parse]( [param:Object json] )

    @@ -85,13 +83,10 @@

    [method:Font parse]( [param:Object json] )

    JSON格式进行解析,并返回一个[page:Font].

    -

    [method:FontLoader setPath]( [param:String path] )

    -

    - 设置加载字体的基本路径或URL。当加载同一目录中下的许多字体时,此方法将很有用。 -

    -

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/ImageBitmapLoader.html b/docs/api/zh/loaders/ImageBitmapLoader.html index ac9d19d070a487..9ce3a3daaf2de4 100644 --- a/docs/api/zh/loaders/ImageBitmapLoader.html +++ b/docs/api/zh/loaders/ImageBitmapLoader.html @@ -8,11 +8,13 @@ + [page:Loader] → +

    [name]

    一个把[page:Image]加载为[link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap]的加载器。 - ImageBitmap提供了一种异步且有效的资源的途径,用于在WebGL中渲染的纹理。
    + ImageBitmap提供了一种异步且有效的资源的途径,用于在WebGL中渲染的纹理。
    不像[page:FileLoader], [name]无需避免对同一的URL进行多次请求。

    @@ -23,11 +25,7 @@

    [name]

    instead. Refer to [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.10 WebGL specification] for the detail.

    -

    例子

    - -

    - [example:webgl_loader_imagebitmap WebGL / loader / ImageBitmap] -

    +

    代码示例

    // 初始化一个加载器 @@ -57,6 +55,11 @@

    例子

    );
    +

    例子

    + +

    + [example:webgl_loader_imagebitmap WebGL / loader / ImageBitmap] +

    构造函数

    @@ -68,20 +71,15 @@

    [name]( [param:LoadingManager manager] )

    属性

    +

    共有属性请参见其基类[page:Loader]。

    -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager] ,默认为[page:DefaultLoadingManager]. -

    [property:String options]

    一个可选对象,用来设置内部使用的[link:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap createImageBitmap]工厂方法, - 默认为*undefined*.

    - -

    [property:String path]

    -

    所要加载文件的基本路径。 请参考[page:.setPath],默认为*undefined*。

    + 默认为*undefined*.

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -92,25 +90,18 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载,并返回将包含数据的[page:ImageBitmap image]对象。 + 从URL中进行加载,并返回将包含数据的[page:ImageBitmap image]对象。

    -

    [method:ImageBitmapLoader setCrossOrigin]()

    -

    此方法出于兼容性原因而存在,并且不实现逻辑。它确保[name]具有[page:ImageLoader]的类似接口。

    -

    [method:ImageBitmapLoader setOptions]( [param:Object options] )

    设置[link:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap createImageBitmap]的选项对象。

    -

    [method:ImageBitmapLoader setPath]( [param:String path] )

    -

    - 设置加载文件的基本路径或URL。当加载同一目录中下的许多图片时,此方法将很有用。 -

    - -

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/ImageLoader.html b/docs/api/zh/loaders/ImageLoader.html index 4cc529eb72eb1a..fc78c4e4198b76 100644 --- a/docs/api/zh/loaders/ImageLoader.html +++ b/docs/api/zh/loaders/ImageLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -16,12 +18,7 @@

    [name]

    [page:CubeTextureLoader]、[page:ObjectLoader]、[page:TextureLoader]所使用。

    -

    例子

    - -

    - [example:webgl_loader_obj WebGL / loader / obj]
    - [example:webgl_shaders_ocean WebGL / shaders / ocean] -

    +

    代码示例

    // 初始化一个加载器 @@ -55,6 +52,13 @@

    例子

    请参考[link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-275785639 this thread].

    +

    例子

    + +

    + [example:webgl_loader_obj WebGL / loader / obj]
    + [example:webgl_shaders_ocean WebGL / shaders / ocean] +

    +

    构造方法

    [name]( [param:LoadingManager manager] )

    @@ -65,22 +69,10 @@

    [name]( [param:LoadingManager manager] )

    属性

    - -

    [property:String crossOrigin]

    -

    - 如果设置了,在开始加载前, 将为图片分配 [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - 属性,其值为 *crossOrigin*, 默认为"anonymous"。 -

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager],默认值为[page:DefaultLoadingManager]. -

    - -

    [property:String path]

    -

    所要加载文件的基本路径。 请参考[page:.setPath],默认为*undefined*。

    +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -91,19 +83,13 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载,并返回将包含数据的[page:Image image]对象。 + 从URL中进行加载,并返回将包含数据的[page:Image image]对象。

    -

    [method:null setCrossOrigin]( [param:String value] )

    -

    设置[page:.crossOrigin]的属性。

    +

    -

    [method:FileLoader setPath]( [param:String path] )

    - 设置加载文件的基本路径或URL。当加载同一目录中下的许多图片时,此方法将很有用。 + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

    - -

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/loaders/Loader.html b/docs/api/zh/loaders/Loader.html index 7ea281fc73e6be..1ebb3fe4825a77 100644 --- a/docs/api/zh/loaders/Loader.html +++ b/docs/api/zh/loaders/Loader.html @@ -8,86 +8,79 @@ -

    [name]

    +

    加载器([name])

    -

    所有加载器的基类

    +

    用于实现加载器的基类。

    -

    构造方法

    +

    构造函数

    -

    [name]()

    +

    [name]( [param:LoadingManager manager] )

    - 当创建一个新的 [name], 将调用此基类。 + [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager]. +

    +

    + Creates a new [name].

    属性

    -

    [property:Function onLoadStart]

    -

    当加载开始时,将被调用。

    -

    默认实现是一个空函数体。

    - -

    [property:Function onLoadProgress]

    -

    当进入加载流程中,将被调用。

    -

    默认实现是一个空函数体。

    - -

    [property:Function onLoadComplete]

    -

    当加载完成时,将被调用。

    -

    默认实现是一个空函数体。

    -

    [property:string crossOrigin]

    - 跨域字符串,用于实现跨域,以便从允许CORS从其他域加载url。默认为"anonymous"。 + The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. + Default is *anonymous*.

    -

    Methods

    - -

    [method:Material createMaterial]( [param:object m], [param:string texturePath] )

    -

    - [page:Object m] — 所要创建的材质的参数。
    - [page:String texturePath] — 纹理加载路径。 -

    +

    [property:LoadingManager manager]

    - 基于参数m来创建材质。 + The [page:LoadingManager loadingManager] the loader is using. Default is [page:DefaultLoadingManager].

    -

    [method:Array initMaterials]( [param:Array materials], [param:string texturePath] )

    +

    [property:String path]

    - [page:Array materials] — 用于创建材质的参数数组。
    - [page:String texturePath] — 纹理加载路径。 + The base path from which the asset will be loaded. + Default is the empty string.

    + +

    [property:String resourcePath]

    - 基于参数数组m,来创建 [page:Material] 数组. 参数索引与材质的索引一致。 + The base path from which additional resources like textures will be loaded. + Default is the empty string.

    -

    Handlers

    +

    方法

    +

    [method:void load]()

    - *[name].Handlers* is a special object normally used by other loaders like [page:GLTFLoader] or [page:MTLLoader]. It provides an - API that allows the definition of special mappings: What loaders should be used in order to load specific files. A typical use case - is to overwrite the default loader for textures.

    - - Note: It's only possible to use *[name].Handlers* if the respective loader support the usage. + This method needs to be implement by all concrete loaders. It holds the logic for loading the asset from the backend.

    - -

    [method:null add]( [param:Object regex], [param:Loader loader] )

    + +

    [method:void parse]()

    - [page:Object regex] — A regular expression.
    - [page:Loader loader] — The loader. + This method needs to be implement by all concrete loaders. It holds the logic for parsing the asset into three.js entities. +

    + +

    [method:Loader setCrossOrigin]( [param:String crossOrigin] )

    - Registers a loader with the given regular expression. + [page:String crossOrigin] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS.

    - -

    [method:null get]( [param:String file] )

    + +

    [method:Loader setPath]( [param:String path] )

    - [page:String file] — The file path. + [page:String path] — Set the base path for the asset. +

    + +

    [method:Loader setResourcePath]( [param:String resourcePath] )

    - Can be used to retrieve the registered loader for the given file path. + [page:String resourcePath] — Set the base path for dependent resources like textures.

    - +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/LoaderUtils.html b/docs/api/zh/loaders/LoaderUtils.html index 52da894155bddd..9fe8cdda0a7578 100644 --- a/docs/api/zh/loaders/LoaderUtils.html +++ b/docs/api/zh/loaders/LoaderUtils.html @@ -19,7 +19,7 @@

    [method:String decodeText]( [param:TypedArray array] )

    [page:TypedArray array] — 作为类型化数组的字节流

    - 该函数将字节流作为输入并返回字符串作为表示。 + 该函数将字节流作为输入并返回字符串作为表示。

    [method:String extractUrlBase]( [param:string url] )

    @@ -33,6 +33,8 @@

    [method:String extractUrlBase]( [param:string url] )

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/MaterialLoader.html b/docs/api/zh/loaders/MaterialLoader.html index f73ee5ee2b438b..5c7baeb0df6b29 100644 --- a/docs/api/zh/loaders/MaterialLoader.html +++ b/docs/api/zh/loaders/MaterialLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -15,8 +17,7 @@

    [name]

    默认使用[page:FileLoader]进行加载文件。

    -

    例子

    - +

    代码示例

    // 初始化一个加载器 @@ -54,17 +55,14 @@

    [name]( [param:LoadingManager manager] )

    属性

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager],默认为[page:DefaultLoadingManager]. -

    +

    共有属性请参见其基类[page:Loader]。

    [property:Object textures]

    持有材质的任何纹理的对象,请参考 [page:.setTextures].

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -74,7 +72,7 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onProgress] — 将在加载过程中进行调用,参数为进度事件。
    [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载,并返回将包含数据的[page:Material]对象。 + 从URL中进行加载,并返回将包含数据的[page:Material]对象。

    [method:Material parse]( [param:Object json] )

    @@ -89,10 +87,10 @@

    [method:null setTextures]( [param:Object textures] )

    [page:Object textures] — 对象包含任何被材质所使用的纹理。

    - -

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/loaders/ObjectLoader.html b/docs/api/zh/loaders/ObjectLoader.html index 0d75f52c8473bf..4ace6ef8293c42 100644 --- a/docs/api/zh/loaders/ObjectLoader.html +++ b/docs/api/zh/loaders/ObjectLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -16,12 +18,7 @@

    [name]

    此加载器内部使用[page:FileLoader]进行加载文件。

    -

    例子

    - -

    - [example:webgl_loader_json_claraio WebGL / loader / json / claraio]
    - [example:webgl_materials_lightmap WebGL / materials / lightmap] -

    +

    代码示例

    var loader = new THREE.ObjectLoader(); @@ -55,7 +52,12 @@

    例子

    scene.add( object );
    +

    例子

    +

    + [example:webgl_loader_json_claraio WebGL / loader / json / claraio]
    + [example:webgl_materials_lightmap WebGL / materials / lightmap] +

    构造函数

    @@ -66,27 +68,11 @@

    [name]( [param:LoadingManager manager] )

    创建一个新的[name].

    -

    属性

    - -

    [property:String crossOrigin]

    -

    - 如果设置了,在开始加载前, 将为图片分配 [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - 属性,其值为 *crossOrigin*, 默认为"anonymous"。 -

    - -

    [property:LoadingManager manager]

    -

    - 加载器正在使用的[page:LoadingManager loadingManager],默认值为[page:DefaultLoadingManager]。 -

    - -

    [property:String texturePath]

    -

    - 将要被加载的纹理的路径或者URL,详情请参考[page:.setTexturePath]。 - 默认值为空字符串。 -

    +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -97,7 +83,7 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func [page:Function onError] — 在加载错误时被调用。

    - 从URL中进行加载,并将被解析的响应内容传递给onLoad。 + 从URL中进行加载,并将被解析的响应内容传递给onLoad。

    @@ -106,7 +92,7 @@

    [method:Object3D parse]( [param:Object json], [param:Function onLoad] )


    [page:Function onLoad] — 当解析完成时被调用,其中参数被解析为[page:Object3D object].

    - 解析一个JSON结构,并返回一个threejs对象. + 解析一个JSON结构,并返回一个threejs对象. 内部使用[page:.load]进行加载, 但也可以直接用于解析先前加载的JSON结构。

    @@ -114,7 +100,7 @@

    [method:Object3D parseGeometries]( [param:Object json] )

    [page:Object json] — 必选参数,需要被解析的JSON源。

    - 此函数以JSON结构,用[page:.parse]去解析[page:Geometry geometries]或[page:BufferGeometry buffer geometries]。 + 此函数以JSON结构,用[page:.parse]去解析[page:Geometry geometries]或[page:BufferGeometry buffer geometries]。

    [method:Object3D parseMaterials]( [param:Object json] )

    @@ -129,26 +115,26 @@

    [method:Object3D parseAnimations]( [param:Object json] )

    [page:Object json] — 必选参数,需要被解析的JSON源。

    此函数通过[page:.parse]来使用[page:AnimationClip.parse], 以解析JSON结构中任意动画。 -

    +

    [method:Object3D parseImages]( [param:Object json] )

    [page:Object json] — 必选参数,需要被解析的JSON源。

    - 此函数通过[page:.parse]来使用[page:ImageLoader], 以解析JSON结构中任意图片。 + 此函数通过[page:.parse]来使用[page:ImageLoader], 以解析JSON结构中任意图片。

    [method:Object3D parseTextures]( [param:Object json] )

    [page:Object json] — 必选参数,需要被解析的JSON源。

    - 此函数通过[page:.parse]来解析JSON结构中任意纹理。 + 此函数通过[page:.parse]来解析JSON结构中任意纹理。

    [method:Object3D parseObject]( [param:Object json] )

    [page:Object json] — 必选参数,需要被解析的JSON源。

    - 此函数通过[page:.parse]来解析JSON结构中任意对象。 + 此函数通过[page:.parse]来解析JSON结构中任意对象。 对象可以为如下类型:

      @@ -204,20 +190,10 @@

      [method:Object3D parseObject]( [param:Object json] )

    -

    [method:ObjectLoader setCrossOrigin]( [param:String value] )

    -

    - [page:String value] — 在允许CROS时,跨域字段通过实现CORS来加载不同域下的URL。 -

    +

    -

    [method:ObjectLoader setTexturePath]( [param:String value] )

    - [page:String value] — 设置将要加载为纹理的路径或者URL

    - - + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

    - -

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/loaders/TextureLoader.html b/docs/api/zh/loaders/TextureLoader.html index 05858f35d6a03c..cc0751c63001c0 100644 --- a/docs/api/zh/loaders/TextureLoader.html +++ b/docs/api/zh/loaders/TextureLoader.html @@ -8,6 +8,8 @@ + [page:Loader] → +

    [name]

    @@ -15,7 +17,7 @@

    [name]

    内部使用[page:ImageLoader]来加载文件。

    -

    例子

    +

    代码示例

    var texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' ); @@ -24,9 +26,7 @@

    例子

    var material = new THREE.MeshBasicMaterial( { map: texture } );
    - [example:webgl_geometry_cube geometry / cube] - -

    Example with Callbacks

    +

    Code Example with Callbacks

    // 初始化一个加载器 @@ -54,38 +54,31 @@

    Example with Callbacks

    } );
    - 请注意three.js r84遗弃了TextureLoader进度事件。对于支持进度事件的TextureLoader , - 请参考[link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-293260145 this thread]。 - -

    构造函数

    - -

    [name]( [param:LoadingManager manager] )

    - [page:LoadingManager manager] — 加载器使用的[page:LoadingManager loadingManager],默认值为[page:LoadingManager THREE.DefaultLoadingManager].

    - - 创建一个新的[name]. + 请注意three.js r84遗弃了TextureLoader进度事件。对于支持进度事件的TextureLoader , + 请参考[link:https://github.com/mrdoob/three.js/issues/10439#issuecomment-293260145 this thread]。

    +

    例子

    -

    属性

    - -

    [property:String crossOrigin]

    - 如果设置了,在开始加载前, 将为图片分配 [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - 属性,其值为 *crossOrigin*, 默认为"anonymous"。 + [example:webgl_geometry_cube geometry / cube]

    +

    构造函数

    -

    [property:LoadingManager manager]

    +

    [name]( [param:LoadingManager manager] )

    - 加载器正在使用的[page:LoadingManager loadingManager],默认值为[page:DefaultLoadingManager]. -

    + [page:LoadingManager manager] — 加载器使用的[page:LoadingManager loadingManager],默认值为[page:LoadingManager THREE.DefaultLoadingManager].

    -

    [property:String path]

    -

    被加载文件的基本路径,请参考[page:.setPath]。默认值为*undefined*.

    + 创建一个新的[name]. +

    +

    属性

    +

    共有属性请参见其基类[page:Loader]。

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:Texture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -95,21 +88,14 @@

    [method:Texture load]( [param:String url], [param:Function onLoad], [param:F [page:Function onProgress] — 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含[page:Integer total]和[page:Integer loaded]字节。
    [page:Function onError] — 在加载错误时被调用。

    - 从给定的URL开始加载并将完全加载的[page:Texture texture]传递给onLoad。该方法还返回一个新的纹理对象,该纹理对象可以直接用于材质创建。 - 如果采用此方法,一旦相应的加载过程完成,纹理可能会在场景中出现。 + 从给定的URL开始加载并将完全加载的[page:Texture texture]传递给onLoad。该方法还返回一个新的纹理对象,该纹理对象可以直接用于材质创建。 + 如果采用此方法,一旦相应的加载过程完成,纹理可能会在场景中出现。

    -

    [method:null setCrossOrigin]( [param:String value] )

    -

    设置[page:.crossOrigin]的属性。

    +

    -

    [method:FileLoader setPath]( [param:String path] )

    - 设置加载文件的基本路径或URL。当加载同一目录中的许多模型,此方法将很有用。 + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

    - - -

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] diff --git a/docs/api/zh/loaders/managers/DefaultLoadingManager.html b/docs/api/zh/loaders/managers/DefaultLoadingManager.html index 89d7f258ac5869..87a5c5bc397bd2 100644 --- a/docs/api/zh/loaders/managers/DefaultLoadingManager.html +++ b/docs/api/zh/loaders/managers/DefaultLoadingManager.html @@ -13,43 +13,43 @@

    [name]

    [page:LoadingManager LoadingManager]是一个全局实例, 当其他加载器没有指定加载管理器时,它将被其他大多数的加载器设为默认的加载管理器。

    - LoadingManager对于大多数加载器来说已经足够了,但有时您可能需要单独设置加载管理器,例如纹理、模型加载器。 + LoadingManager对于大多数加载器来说已经足够了,但有时您可能需要单独设置加载管理器,例如纹理、模型加载器。

    -

    例子

    +

    代码示例

    你可以选择性的为你的管理器设置 [page:LoadingManager.onStart onStart], [page:LoadingManager.onLoad onLoad], [page:LoadingManager.onProgress onProgress], [page:LoadingManager.onStart onError] 这些方法。 当你的加载器使用默认加载管理器时,这些方法都将被应用到加载器上。

    - 请注意,个人的加载器的不应具有类似上面类似的命名函数,以避免混淆。因为这些函数时用于显示有关加载总体状态的信息,而不是处理已加载的数据。 + 请注意,个人的加载器的不应具有类似上面类似的命名函数,以避免混淆。因为这些函数时用于显示有关加载总体状态的信息,而不是处理已加载的数据。

    -THREE.DefaultLoadingManager.onStart = function ( url, itemsLoaded, itemsTotal ) { + THREE.DefaultLoadingManager.onStart = function ( url, itemsLoaded, itemsTotal ) { - console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); + console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); -}; + }; -THREE.DefaultLoadingManager.onLoad = function ( ) { + THREE.DefaultLoadingManager.onLoad = function ( ) { - console.log( 'Loading Complete!'); + console.log( 'Loading Complete!'); -}; + }; -THREE.DefaultLoadingManager.onProgress = function ( url, itemsLoaded, itemsTotal ) { + THREE.DefaultLoadingManager.onProgress = function ( url, itemsLoaded, itemsTotal ) { - console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); + console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' ); -}; + }; -THREE.DefaultLoadingManager.onError = function ( url ) { + THREE.DefaultLoadingManager.onError = function ( url ) { - console.log( 'There was an error loading ' + url ); + console.log( 'There was an error loading ' + url ); -}; + }; @@ -62,7 +62,8 @@

    方法

    有关LoadingManager方法的详细信息,请查看[page:LoadingManager LoadingManager] 页面。

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

    diff --git a/docs/api/zh/loaders/managers/LoadingManager.html b/docs/api/zh/loaders/managers/LoadingManager.html index eaee4ce746a409..134bf0c6cacc96 100644 --- a/docs/api/zh/loaders/managers/LoadingManager.html +++ b/docs/api/zh/loaders/managers/LoadingManager.html @@ -12,24 +12,14 @@

    [name]

    - 其功能时处理并跟踪已加载和待处理的数据。如果未手动设置加强管理器,则会为加载器创建和使用默认全局实例加载器管理器 - - 请参阅 [page:DefaultLoadingManager].

    + 其功能时处理并跟踪已加载和待处理的数据。如果未手动设置加强管理器,则会为加载器创建和使用默认全局实例加载器管理器 + - 请参阅 [page:DefaultLoadingManager].

    - 一般来说,默认的加载管理器已足够使用了,但有时候也需要设置单独的加载器 - 例如,如果你想为对象和纹理显示单独的加载条。 + 一般来说,默认的加载管理器已足够使用了,但有时候也需要设置单独的加载器 - 例如,如果你想为对象和纹理显示单独的加载条。

    - -

    例子

    - -

    - [example:webgl_loader_babylon WebGL / loader / babylon]
    - [example:webgl_loader_fbx WebGL / loader / fbx]
    - [example:webgl_loader_obj WebGL / loader / obj]
    - [example:webgl_materials_reflectivity WebGL / materials / reflectivity]
    - [example:webgl_postprocessing_outline WebGL / postprocesing / outline]
    - [example:webgl_terrain_dynamic WebGL / terrain / dynamic] -

    +

    代码示例

    下面的例子将介绍,如何使用加载管理器来跟踪 [page:OBJLoader] 的加载进度流程。 @@ -72,8 +62,8 @@

    例子

    - 除了观察进度流程之外,还可以使用LoadingManager在加载期间覆写资源URL。当某资源来自拖拽事件、 - WebSockets、WebRTC或其他API时,此方法可以有所帮助。下面显示了如何使用Blob URL加载内存模型的示例。 + 除了观察进度流程之外,还可以使用LoadingManager在加载期间覆写资源URL。当某资源来自拖拽事件、 + WebSockets、WebRTC或其他API时,此方法可以有所帮助。下面显示了如何使用Blob URL加载内存模型的示例。

    @@ -105,6 +95,15 @@

    例子

    });
    +

    例子

    + +

    + [example:webgl_loader_fbx WebGL / loader / fbx]
    + [example:webgl_loader_obj WebGL / loader / obj]
    + [example:webgl_materials_physical_reflectivity WebGL / materials / physical / reflectivity]
    + [example:webgl_postprocessing_outline WebGL / postprocesing / outline] +

    +

    构造方法

    [name]( [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -132,49 +131,76 @@

    [property:Function onStart]

    [property:Function onLoad]

    - 所有的项加载完成后将调用此函数。默认情况下,此方法时未定义的,除非在构造函数中进行传递。 + 所有的项加载完成后将调用此函数。默认情况下,此方法时未定义的,除非在构造函数中进行传递。

    [property:Function onProgress]

    - 此方法加载每一个项,加载完成时进行调用。 - 有如下参数:
    + 此方法加载每一个项,加载完成时进行调用。 + 有如下参数:
    [page:String url] — 被加载的项的url。
    [page:Integer itemsLoaded] — 目前已加载项的个数。
    [page:Iteger itemsTotal] — 总共所需要加载项的个数。

    - 默认情况下,此方法时未定义的,除非在构造函数中进行传递。 + 默认情况下,此方法时未定义的,除非在构造函数中进行传递。

    [property:Function onError]

    - 此方法将在任意项加载错误时,进行调用。 - 有如下参数:
    + 此方法将在任意项加载错误时,进行调用。 + 有如下参数:
    [page:String url] — 所加载出错误的项的url

    - 默认情况下,此方法时未定义的,除非在构造函数中进行传递。 + 默认情况下,此方法时未定义的,除非在构造函数中进行传递。

    方法

    -

    [method:null setURLModifier]( [param:Function callback] )

    +

    [method:LoadingManager addHandler]( [param:Object regex], [param:Loader loader] )

    - [page:Function callback] — - 设置URL修饰符成功时回调。使用url参数进行回调,并且必须返回 [page:String resolvedURL] 。

    + [page:Object regex] — A regular expression.
    + [page:Loader loader] — The loader. +

    + Registers a loader with the given regular expression. Can be used to define what loader should be used in + order to load specific files. A typical use case is to overwrite the default loader for textures. +

    + +// add handler for TGA textures +manager.addHandler( /\.tga$/i, new TGALoader() ); + - 如果设置了回调,则在发送请求之前将向每个资源URL传递回调。回调可以返回最初的URL,也可以返回新URL以覆盖加载行为。 - 此行为可用于从.ZIP、拖拽API和数据URI中加载资源文件。 +

    [method:null getHandler]( [param:String file] )

    +

    + [page:String file] — The file path. +

    + Can be used to retrieve the registered loader for the given file path. +

    + +

    [method:LoadingManager removeHandler]( [param:Object regex] )

    +

    + [page:Object regex] — A regular expression. +

    + Removes the loader for the given regular expression.

    [method:String resolveURL]( [param:String url] )

    [page:String url] — 所要加载的url

    - 给定URL,使用URL修饰符回调(如果有)并返回已解析的URL。如果未设置URL修饰符,则返回原始URL。 + 给定URL,使用URL修饰符回调(如果有)并返回已解析的URL。如果未设置URL修饰符,则返回原始URL。 +

    + +

    [method:null setURLModifier]( [param:Function callback] )

    +

    + [page:Function callback] — 设置URL修饰符成功时回调。使用url参数进行回调,并且必须返回 [page:String resolvedURL] 。

    + + 如果设置了回调,则在发送请求之前将向每个资源URL传递回调。回调可以返回最初的URL,也可以返回新URL以覆盖加载行为。 + 此行为可用于从.ZIP、拖拽API和数据URI中加载资源文件。

    -

    + +

    Note: The following methods are designed to be called internally by loaders. You shouldn't call them directly. @@ -184,26 +210,26 @@

    [method:null itemStart]( [param:String url] )

    [page:String url] — 所要加载的url

    - 任何使用管理器的加载器都会调用此方法, 当加载器需要开始加载URL时。 + 任何使用管理器的加载器都会调用此方法, 当加载器需要开始加载URL时。

    [method:null itemEnd]( [param:String url] )

    [page:String url] — 所要加载的url

    - 任何使用管理器的加载器都会调用此方法, 当加载器需要加载URL结束时。 + 任何使用管理器的加载器都会调用此方法, 当加载器需要加载URL结束时。

    -

    [method:null itemError]( [param:String url] )

    [page:String url] — 所要加载的url

    - 任何使用管理器的加载器都会调用此方法, 当加载器出现加载错误时。 + 任何使用管理器的加载器都会调用此方法, 当加载器出现加载错误时。

    - - [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js] +

    diff --git a/docs/api/zh/materials/LineBasicMaterial.html b/docs/api/zh/materials/LineBasicMaterial.html index 2b57af5e2156d7..7d2e29db4bc76f 100644 --- a/docs/api/zh/materials/LineBasicMaterial.html +++ b/docs/api/zh/materials/LineBasicMaterial.html @@ -12,9 +12,20 @@

    基础线条材质([name])

    -

    一种用于绘制线框样式几何体的材质。

    +

    一种用于绘制线框样式几何体的材质。

    -

    例子(Examples)

    +

    代码示例

    + + + var material = new THREE.LineBasicMaterial( { + color: 0xffffff, + linewidth: 1, + linecap: 'round', //ignored by WebGLRenderer + linejoin: 'round' //ignored by WebGLRenderer + } ); + + +

    例子

    [example:webgl_buffergeometry_drawcalls WebGL / buffergeometry / drawcalls]
    @@ -29,20 +40,10 @@

    例子(Examples)

    [example:webgl_lines_colors WebGL / lines / colors]
    [example:webgl_lines_dashed WebGL / lines / dashed]
    [example:webgl_lines_sphere WebGL / lines / sphere]
    - [example:webgl_lines_splines WebGL / lines / splines]
    [example:webgl_materials WebGL / materials]
    [example:webgl_physics_rope WebGL / phyics / rope]

    - -var material = new THREE.LineBasicMaterial( { - color: 0xffffff, - linewidth: 1, - linecap: 'round', //ignored by WebGLRenderer - linejoin: 'round' //ignored by WebGLRenderer -} ); - -

    构造函数(Constructor)

    [name]( [param:Object parameters] )

    @@ -58,14 +59,6 @@

    属性(Properties)

    [property:Color color]

    材质的颜色([page:Color]),默认值为白色 (0xffffff)。

    -

    [property:Boolean isLineBasicMaterial]

    -

    用于检查此类或派生类是否为基础线条材质。默认值为 *true*。

    - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    - -

    [property:Boolean lights]

    -

    材质是否受到光照的影响。默认值为 *false*。

    -

    [property:Float linewidth]

    控制线宽。默认值为 *1*。

    由于[link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]与 @@ -90,6 +83,8 @@

    方法(Methods)

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/LineDashedMaterial.html b/docs/api/zh/materials/LineDashedMaterial.html index 7bc311b18bb641..8f80c041fa2ddb 100644 --- a/docs/api/zh/materials/LineDashedMaterial.html +++ b/docs/api/zh/materials/LineDashedMaterial.html @@ -8,44 +8,40 @@ - [page:Material] → + [page:Material] → [page:LineBasicMaterial] →

    虚线材质([name])

    一种用于绘制虚线样式几何体的材质。

    -

    例子(Examples)

    +

    代码示例

    + + + var material = new THREE.LineDashedMaterial( { + color: 0xffffff, + linewidth: 1, + scale: 1, + dashSize: 3, + gapSize: 1, + } ); + + +

    例子

    [example:webgl_lines_dashed WebGL / lines / dashed]
    - [example:canvas_lines_dashed Canvas / lines /dashed]

    - -var material = new THREE.LineDashedMaterial( { - color: 0xffffff, - linewidth: 1, - scale: 1, - dashSize: 3, - gapSize: 1, -} ); - -

    构造函数(Constructor)

    [name]( [param:Object parameters] )

    - [page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。材质的任何属性都可以从此处传入(包括从[page:Material]继承的任何属性)。

    - 属性[page:Hexadecimal color]例外,其可以作为十六进制字符串传递,默认情况下为 *0xffffff*(白色),内部调用[page:Color.set](color)。 + [page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。材质的任何属性都可以从此处传入(包括从[page:LineBasicMaterial]继承的任何属性)。

    -

    属性(Properties)

    -

    共有属性请参见其基类[page:Material]。

    - -

    [property:Color color]

    -

    材质的颜色([page:Color]),默认值为白色 (0xffffff)。

    +

    共有属性请参见其基类[page:LineBasicMaterial]。

    [property:number dashSize]

    虚线的大小,是指破折号和间隙之和。默认值为 *3*。

    @@ -53,33 +49,16 @@

    [property:number dashSize]

    [property:number gapSize]

    间隙的大小,默认值为 *1*。

    -

    [property:Boolean isLineDashedMaterial]

    -

    用于检查此类或派生类是否为虚线材质。默认值为 *true*。

    - - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    - -

    [property:Boolean lights]

    -

    材质是否受到光照的影响。默认值为 *false*。

    - -

    [property:Float linewidth]

    -

    - 控制线宽。默认值为 *1*。

    - - 由于[link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]与 - 大多数平台上[page:WebGLRenderer WebGL]渲染器的限制,无论如何设置该值,线宽始终为1。 -

    -

    [property:number scale]

    线条中虚线部分的占比。默认值为 *1*。

    方法(Methods)

    -

    共有方法请参见其基类[page:Material]。

    - - +

    共有方法请参见其基类[page:LineBasicMaterial]。

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/Material.html b/docs/api/zh/materials/Material.html index 24d921a41cd8d5..625e89af15cf81 100644 --- a/docs/api/zh/materials/Material.html +++ b/docs/api/zh/materials/Material.html @@ -1,19 +1,19 @@ - - - - - + + + + +

    材质([name])

    材质的抽象基类。

    - 材质描述了对象[page:Object objects]的外观。它们的定义方式与渲染器无关, - 因此,如果您决定使用不同的渲染器,不必重写材质。

    - 所有其他材质类型都继承了以下属性和方法(尽管它们可能具有不同的默认值)。 + 材质描述了对象[page:Object objects]的外观。它们的定义方式与渲染器无关, + 因此,如果您决定使用不同的渲染器,不必重写材质。

    + 所有其他材质类型都继承了以下属性和方法(尽管它们可能具有不同的默认值)。

    构造函数(Constructor)

    @@ -31,8 +31,8 @@

    [property:Float alphaTest]

    [property:Integer blendDst]

    混合目标。默认值为[page:CustomBlendingEquation OneMinusSrcAlphaFactor]。 - 目标因子所有可能的取值请参阅[page:CustomBlendingEquation constants]。 - 必须将材质的[page:Constant blending]设置为[page:Materials CustomBlending]才能生效。
    + 目标因子所有可能的取值请参阅[page:CustomBlendingEquation constants]。 + 必须将材质的[page:Constant blending]设置为[page:Materials CustomBlending]才能生效。

    [property:Integer blendDstAlpha]

    @@ -40,8 +40,8 @@

    [property:Integer blendDstAlpha]

    [property:Integer blendEquation]

    使用混合时所采用的混合方程式。默认值为[page:CustomBlendingEquation AddEquation]。 - 混合方程式所有可能的取值请参阅[page:CustomBlendingEquation constants]。 - 必须将材质的[page:Constant blending]设置为[page:Materials CustomBlending]才能生效。
    + 混合方程式所有可能的取值请参阅[page:CustomBlendingEquation constants]。 + 必须将材质的[page:Constant blending]设置为[page:Materials CustomBlending]才能生效。

    [property:Integer blendEquationAlpha]

    @@ -49,15 +49,15 @@

    [property:Integer blendEquationAlpha]

    [property:Blending blending]

    在使用此材质显示对象时要使用何种混合。
    - 必须将其设置为[page:Materials CustomBlending]才能使用自定义[page:Constant blendSrc], [page:Constant blendDst] 或者 [page:Constant - blendEquation]。 - 混合模式所有可能的取值请参阅[page:Materials constants]。默认值为[page:Materials NormalBlending]。 + 必须将其设置为[page:Materials CustomBlending]才能使用自定义[page:Constant blendSrc], [page:Constant blendDst] 或者 [page:Constant + blendEquation]。 + 混合模式所有可能的取值请参阅[page:Materials constants]。默认值为[page:Materials NormalBlending]。

    [property:Integer blendSrc]

    混合源。默认值为[page:CustomBlendingEquation SrcAlphaFactor]。 - 源因子所有可能的取值请参阅[page:CustomBlendingEquation constants]。
    - 必须将材质的[page:Constant blending]设置为[page:Materials CustomBlending]才能生效。 + 源因子所有可能的取值请参阅[page:CustomBlendingEquation constants]。
    + 必须将材质的[page:Constant blending]设置为[page:Materials CustomBlending]才能生效。

    [property:Integer blendSrcAlpha]

    @@ -69,9 +69,9 @@

    [property:Boolean clipIntersection]

    [property:Array clippingPlanes]

    - 用户定义的剪裁平面,在世界空间中指定为THREE.Plane对象。这些平面适用于所有使用此材质的对象。空间中与平面的有符号距离为负的点被剪裁(未渲染)。 - 这需要[page:WebGLRenderer.localClippingEnabled]为*true*。 - 示例请参阅[example:webgl_clipping_intersection WebGL / clipping /intersection]。默认值为 *null*。 + 用户定义的剪裁平面,在世界空间中指定为THREE.Plane对象。这些平面适用于所有使用此材质的对象。空间中与平面的有符号距离为负的点被剪裁(未渲染)。 + 这需要[page:WebGLRenderer.localClippingEnabled]为*true*。 + 示例请参阅[example:webgl_clipping_intersection WebGL / clipping /intersection]。默认值为 *null*。

    [property:Boolean clipShadows]

    @@ -80,17 +80,17 @@

    [property:Boolean clipShadows]

    [property:Boolean colorWrite]

    是否渲染材质的颜色。 - 这可以与网格的[page:Integer renderOrder]属性结合使用,以创建遮挡其他对象的不可见对象。默认值为*true*。 + 这可以与网格的[page:Integer renderOrder]属性结合使用,以创建遮挡其他对象的不可见对象。默认值为*true*。

    [property:Object defines]

    注入shader的自定义对象。 以键值对形式的对象传递,{ MY_CUSTOM_DEFINE: '' , PI2: Math.PI * 2 }。 - 这些键值对在顶点和片元着色器中定义。默认值为*undefined*。 + 这些键值对在顶点和片元着色器中定义。默认值为*undefined*。

    [property:Integer depthFunc]

    使用何种深度函数。默认为[page:Materials LessEqualDepth]。 - 深度模式所有可能的取值请查阅[page:Materials constants]。 + 深度模式所有可能的取值请查阅[page:Materials constants]。

    [property:Boolean depthTest]

    @@ -99,7 +99,7 @@

    [property:Boolean depthTest]

    [property:Boolean depthWrite]

    渲染此材质是否对深度缓冲区有任何影响。默认为*true*。

    - 在绘制2D叠加时,将多个事物分层在一起而不创建z-index时,禁用深度写入会很有用。 + 在绘制2D叠加时,将多个事物分层在一起而不创建z-index时,禁用深度写入会很有用。

    @@ -108,7 +108,12 @@

    [property:Boolean stencilWrite]

    Whether rendering this material has any effect on the stencil buffer. Default is *false*.

    -

    [property:Boolean stencilFunc]

    +

    [property:Integer stencilWriteMask]

    +

    +The bit mask to use when writing to the stencil buffer. Default is *0xFF*. +

    + +

    [property:Integer stencilFunc]

    The stencil comparison function to use. Default is [page:Materials AlwaysStencilFunc]. See stencil function [page:Materials constants] for all possible values.

    @@ -118,9 +123,9 @@

    [property:Integer stencilRef]

    The value to use when performing stencil comparisons or stencil operations. Default is *0*.

    -

    [property:Boolean stencilMask]

    +

    [property:Integer stencilFuncMask]

    -The bit mask to use when comparing against or writing to the stencil buffer. Default is *0xFF*. +The bit mask to use when comparing against the stencil buffer. Default is *0xFF*.

    [property:Integer stencilFail]

    @@ -128,12 +133,12 @@

    [property:Integer stencilFail]

    Which stencil operation to perform when the comparison function returns false. Default is [page:Materials KeepStencilOp]. See the stencil operations [page:Materials constants] for all possible values.

    -

    [property:Boolean stencilZFail]

    +

    [property:Integer stencilZFail]

    Which stencil operation to perform when the comparison function returns true but the depth test fails. Default is [page:Materials KeepStencilOp]. See the stencil operations [page:Materials constants] for all possible values.

    -

    [property:Boolean stencilZPass]

    +

    [property:Integer stencilZPass]

    Which stencil operation to perform when the comparison function returns true and the depth test passes. Default is [page:Materials KeepStencilOp]. See the stencil operations [page:Materials constants] for all possible values.

    @@ -148,27 +153,17 @@

    [property:Boolean fog]

    [property:Integer id]

    此材质实例的唯一编号。

    -

    [property:Boolean isMaterial]

    -

    用于检查此类或派生类是否为材质。默认值为 *true*。

    - - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    - -

    [property:Boolean lights]

    -

    材质是否受到光照的影响。默认为*true*。

    -

    [property:String name]

    对象的可选名称(不必是唯一的)。默认值为空字符串。

    [property:Boolean needsUpdate]

    -

    指定需要重新编译材质。
    - 实例化新材质时,此属性自动设置为true。 +

    指定需要重新编译材质。

    [property:Float opacity]

    在0.0 - 1.0的范围内的浮点数,表明材质的透明度。值*0.0*表示完全透明,*1.0*表示完全不透明。
    - 如果材质的[page:Boolean transparent]属性未设置为*true*,则材质将保持完全不透明,此值仅影响其颜色。 - 默认值为*1.0*。
    + 如果材质的[page:Boolean transparent]属性未设置为*true*,则材质将保持完全不透明,此值仅影响其颜色。 + 默认值为*1.0*。

    @@ -188,7 +183,7 @@

    [property:String precision]

    [property:Boolean premultipliedAlpha]

    是否预乘alpha(透明度)值。有关差异的示例,请参阅[Example:webgl_materials_transparency WebGL / Materials / Transparency]。 - 默认值为*false*。 + 默认值为*false*。

    [property:Boolean dithering]

    @@ -197,31 +192,31 @@

    [property:Boolean dithering]

    [property:Integer shadowSide]

    定义投影的面。设置时,可以是[page:Materials THREE.FrontSide], [page:Materials THREE.BackSide], 或[page:Materials]。默认值为 *null*。 -
    - 如果为*null*, 则面投射阴影确定如下:
    +
    + 如果为*null*, 则面投射阴影确定如下:
    - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + +
    [page:Material.side]Side casting shadows
    THREE.FrontSide背面
    THREE.BackSide前面
    THREE.DoubleSide双面
    [page:Material.side]Side casting shadows
    THREE.FrontSide背面
    THREE.BackSide前面
    THREE.DoubleSide双面
    @@ -229,15 +224,20 @@

    [property:Integer shadowSide]

    [property:Integer side]

    定义将要渲染哪一面 - 正面,背面或两者。 - 默认为[page:Materials THREE.FrontSide]。其他选项有[page:Materials THREE.BackSide]和[page:Materials THREE.DoubleSide]。 + 默认为[page:Materials THREE.FrontSide]。其他选项有[page:Materials THREE.BackSide]和[page:Materials THREE.DoubleSide]。 +

    + +

    [property:Boolean toneMapped]

    +

    +Defines whether this material is tone mapped according to the renderer's [page:WebGLRenderer.toneMapping toneMapping] setting. Default is *true*.

    [property:Boolean transparent]

    - 定义此材质是否透明。这对渲染有影响,因为透明对象需要特殊处理,并在非透明对象之后渲染。 -
    - 设置为true时,通过设置材质的[page:Float opacity]属性来控制材质透明的程度。
    - 默认值为*false*。 + 定义此材质是否透明。这对渲染有影响,因为透明对象需要特殊处理,并在非透明对象之后渲染。 +
    + 设置为true时,通过设置材质的[page:Float opacity]属性来控制材质透明的程度。
    + 默认值为*false*。

    [property:String type]

    @@ -248,15 +248,14 @@

    [property:String uuid]

    此材质实例的[link:http://en.wikipedia.org/wiki/Universally_unique_identifier UUID],会自动分配,不应该被更改。

    -

    [property:Integer vertexColors]

    -

    是否使用顶点着色。默认值为[page:Materials THREE.NoColors]。 - 其他选项有[page:Materials THREE.VertexColors] 和 [page:Materials THREE.FaceColors]。 +

    [property:Integer version]

    +

    +This starts at *0* and counts how many times [property:Boolean needsUpdate] is set to *true*.

    -

    [property:Boolean vertexTangents]

    -

    Defines whether precomputed vertex tangents, which must be provided in a vec4 "tangent" attribute, - are used. When disabled, tangents are derived automatically. Using precomputed tangents will give - more accurate normal map details in some cases, such as with mirrored UVs. Default is false. +

    [property:Boolean vertexColors]

    +

    +Defines whether vertex coloring is used. Default is *false*.

    [property:Boolean visible]

    @@ -284,20 +283,25 @@

    [method:null dispose]()

    [method:null onBeforeCompile]( [param:Shader shader], [param:WebGLRenderer renderer] )

    在编译shader程序之前立即执行的可选回调。此函数使用shader源码作为参数。用于修改内置材质。

    +

    +Unlike properties, the callback is not supported by [page:Material.clone .clone](), [page:Material.copy .copy]() and [page:Material.toJSON .toJSON](). +

    [method:null setValues]( [param:object values] )

    values -- 具有参数的容器。 - 根据*values*设置属性。
    + 根据*values*设置属性。

    [method:Object toJSON]( [param:object meta] )

    - meta -- 包含有元数据的对象,例如该对象的纹理或图片。 - 将material对象转换为 three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format](three.js JSON 物体/场景格式)。 + meta -- 包含有元数据的对象,例如该对象的纹理或图片。 + 将material对象转换为 three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format](three.js JSON 物体/场景格式)。

    源码(Source)

    -[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/MeshBasicMaterial.html b/docs/api/zh/materials/MeshBasicMaterial.html index 57a2cef607a655..b1e2c82840c757 100644 --- a/docs/api/zh/materials/MeshBasicMaterial.html +++ b/docs/api/zh/materials/MeshBasicMaterial.html @@ -47,9 +47,13 @@

    属性(Properties)

    共有属性请参见其基类[page:Material]。

    [property:Texture alphaMap]

    -

    alpha贴图是一种灰度纹理,用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)。默认值为null。

    - 仅使用纹理的颜色,忽略alpha通道(如果存在)。对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, - 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。Luminance-only以及luminance/alpha纹理也仍然有效。 +

    alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 + 默认值为null。

    + + 仅使用纹理的颜色,忽略alpha通道(如果存在)。 + 对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, + 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。 + Luminance-only以及luminance/alpha纹理也仍然有效。

    [property:Texture aoMap]

    @@ -67,12 +71,6 @@

    [property:Integer combine]

    [page:Materials THREE.AddOperation]。如果选择多个,则使用[page:.reflectivity]在两种颜色之间进行混合。

    -

    [property:Boolean isMeshBasicMaterial]

    -

    用于检查此类或派生类是否为网格基础材质。默认值为 *true*。

    - - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    -

    [property:TextureCube envMap]

    环境贴图。默认值为null。

    @@ -82,9 +80,6 @@

    [property:Texture lightMap]

    [property:Float lightMapIntensity]

    烘焙光的强度。默认值为1。

    -

    [property:Boolean lights]

    -

    材质是否受到光照的影响。默认值为 *false*。

    -

    [property:Texture map]

    颜色贴图。默认为null。

    @@ -135,6 +130,8 @@

    方法(Methods)

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/MeshDepthMaterial.html b/docs/api/zh/materials/MeshDepthMaterial.html index 4a2302863aa226..6c2bfedf9d6b7c 100644 --- a/docs/api/zh/materials/MeshDepthMaterial.html +++ b/docs/api/zh/materials/MeshDepthMaterial.html @@ -43,9 +43,13 @@

    属性(Properties)

    共有属性请参见其基类[page:Material]。

    [property:Texture alphaMap]

    -

    alpha贴图是一种灰度纹理,用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)。默认值为null。

    - 仅使用纹理的颜色,忽略alpha通道(如果存在)。对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, - 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。Luminance-only以及luminance/alpha纹理也仍然有效。 +

    alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 + 默认值为null。

    + + 仅使用纹理的颜色,忽略alpha通道(如果存在)。 + 对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, + 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。 + Luminance-only以及luminance/alpha纹理也仍然有效。

    [property:Constant depthPacking]

    @@ -67,15 +71,6 @@

    [property:Float displacementBias]

    [property:Boolean fog]

    材质是否受雾影响。默认值为*false*。

    -

    [property:Boolean isMeshDepthMaterial]

    -

    用于检查此类或派生类是否为深度网格材质。默认值为 *true*。

    - - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    - -

    [property:Boolean lights]

    -

    材质是否受到光照的影响。默认值为 *false*。

    -

    [property:Texture map]

    颜色贴图。默认为null。

    @@ -100,6 +95,8 @@

    方法(Methods)

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/MeshDistanceMaterial.html b/docs/api/zh/materials/MeshDistanceMaterial.html index 9ad1822ddd3b8a..28b77d09cccdbc 100644 --- a/docs/api/zh/materials/MeshDistanceMaterial.html +++ b/docs/api/zh/materials/MeshDistanceMaterial.html @@ -13,15 +13,17 @@

    [name]

    - [name] is internally used for implementing shadow mapping with [page:PointLight]s.

    + [name] 在内部用于使用[page:PointLight]来实现阴影映射。 - Can also be used to customize the shadow casting of an object by assigning an instance of [name] to [page:Object3D.customDistanceMaterial]. - The following examples demonstrates this approach in order to ensure transparent parts of objects do no cast shadows. + 也可以用于通过将[name]实例指定给[page:Object3D.customDistanceMaterial],来自定义物体阴影投射。 + 下列示例演示了这一方法,以确保物体的透明部分不投射阴影。

    -

    Example

    +

    例子

    - [example:webgl_shadowmap_pointlight WebGL / shadowmap / pointlight] +

    + [example:webgl_shadowmap_pointlight WebGL / shadowmap / pointlight] +

    -

    例子(Examples)

    - [example:webgl_materials_variations_physical materials / variations / physical]
    - [example:webgl_materials_reflectivity materials / reflectivity] +

    例子

    + +

    + [example:webgl_materials_variations_physical materials / variations / physical]
    + [example:webgl_materials_physical_clearcoat materials / physical / clearcoat]
    + [example:webgl_materials_physical_reflectivity materials / physical / reflectivity]
    + [example:webgl_materials_physical_transparency materials / physical / transparency] +

    构造函数(Constructor)

    @@ -50,24 +78,42 @@

    [name]( [param:Object parameters] )

    属性(Properties)

    共有属性请参见其基类[page:Material]。

    -

    [property:Float clearCoat]

    +

    [property:Float clearcoat]

    - ClearCoat级别,从*0.0*到*1.0*。默认值为*0.0*。 + Represents the thickness of the clear coat layer, from *0.0* to *1.0*. Use clear coat related properties to enable multilayer + materials that have a thin translucent layer over the base layer. Default is *0.0*.

    -

    [property:Float clearCoatRoughness]

    -

    clearCoat看起来的粗糙程度,从*0.0*到*1.0*。默认值为*0.0*。

    +

    [property:Texture clearcoatMap]

    +

    + The red channel of this texture is multiplied against [page:.clearcoat], for per-pixel control + over a coating's thickness. Default is *null*. +

    + +

    [property:Float clearcoatNormalMap]

    +

    Can be used to enable independent normals for the clear coat layer. Default is *null*.

    + +

    [property:Vector2 clearcoatNormalScale]

    +

    How much [page:.clearcoatNormalMap] affects the clear coat layer, from *(0,0)* to *(1,1)*. Default is *(1,1)*.

    -

    [property:Boolean isMeshPhysicalMaterial]

    -

    用于检查此类或派生类是否为Lambert网格材质。默认值为 *true*。

    +

    [property:Float clearcoatRoughness]

    +

    Roughness of the clear coat layer, from *0.0* to *1.0*. Default is *0.0*.

    - 因为其通常用在内部优化,所以不应该更改该属性值。 +

    [property:Texture clearcoatRoughnessMap]

    +

    + The green channel of this texture is multiplied against [page:.clearcoatRoughness], for per-pixel control + over a coating's roughness. Default is *null*.

    [property:Object defines]

    如下形式的对象: - { 'PHYSICAL': '' }; + { + + 'STANDARD': '' + 'PHYSICAL': '', + + }; [page:WebGLRenderer]使用它来选择shaders。

    @@ -77,12 +123,25 @@

    [property:Float reflectivity]

    这模拟了非金属材质的反射率。当[page:MeshStandardMaterial]为*1.0*时,此属性无效。

    +

    [property:Float transparency]

    +

    + Degree of transparency, from *0.0* to *1.0*. Default is *0.0*.
    + + Thin, transparent or semitransparent, plastic or glass materials remain largely reflective even if they are mostly transparent. + + The transparency property can be used to model these materials.
    + + When transparency is non-zero, [page:Material.opacity opacity] should be set to *1*. +

    +

    方法(Methods)

    共有方法请参见其基类[page:Material] 和[page:MeshStandardMaterial]。

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/MeshStandardMaterial.html b/docs/api/zh/materials/MeshStandardMaterial.html index 84985dc2d7bded..042956edef51bd 100644 --- a/docs/api/zh/materials/MeshStandardMaterial.html +++ b/docs/api/zh/materials/MeshStandardMaterial.html @@ -72,9 +72,13 @@

    属性(Properties)

    共有属性请参见其基类[page:Material]。

    [property:Texture alphaMap]

    -

    alpha贴图是一种灰度纹理,用于控制整个表面的不透明度(黑色:完全透明;白色:完全不透明)。默认值为null。

    - 仅使用纹理的颜色,忽略alpha通道(如果存在)。对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, - 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。Luminance-only以及luminance/alpha纹理也仍然有效。 +

    alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 + 默认值为null。

    + + 仅使用纹理的颜色,忽略alpha通道(如果存在)。 + 对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, + 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。 + Luminance-only以及luminance/alpha纹理也仍然有效。

    [property:Texture aoMap]

    @@ -136,18 +140,13 @@

    [property:TextureCube envMap]

    请确保将minFilter设置为其中一个MipMap选项,并且未强制禁用mip贴图。

    注意:MeshStandardMaterial 仅支持[link:https://threejs.org/docs/#api/textures/CubeTexture cube environment maps]。 - 如果要使用equirectangular贴图,则需要使用 [link:https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/EquirectangularToCubeGenerator.js EquirectangularToCubeGenerator]。 + 如果要使用equirectangular贴图,则需要使用 [page:WebGLCubeRenderTarget.fromEquirectangularTexture WebGLCubeRenderTarget.fromEquirectangularTexture]().。 详细信息请参阅此示例[link:https://threejs.org/examples/webgl_materials_envmaps_exr.html example]。

    [property:Float envMapIntensity]

    通过乘以环境贴图的颜色来缩放环境贴图的效果。

    -

    [property:Boolean isMeshStandardMaterial]

    -

    用于检查此类或派生类是否为标准网格材质。默认值为 *true*。

    - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    -

    [property:Texture lightMap]

    光照贴图。默认值为null。lightMap需要第二组UVs,因此将忽略[page:Texture repeat]和[page:Texture offset]纹理属性。

    @@ -160,7 +159,7 @@

    [property:Texture map]

    [property:Float metalness]

    材质与金属的相似度。非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 - 默认值为0.5。0.0到1.0之间的值可用于生锈金属的外观。如果还提供了metalnessMap,则两个值相乘。 + 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。如果还提供了metalnessMap,则两个值相乘。

    [property:Texture metalnessMap]

    @@ -193,7 +192,7 @@

    [property:Float refractionRatio]

    [property:Float roughness]

    -

    材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为0.5。如果还提供roughnessMap,则两个值相乘。 +

    材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。如果还提供roughnessMap,则两个值相乘。

    [property:Texture roughnessMap]

    @@ -202,6 +201,12 @@

    [property:Texture roughnessMap]

    [property:Boolean skinning]

    材质是否使用蒙皮。默认值为false。

    +

    [property:Boolean vertexTangents]

    +

    Defines whether precomputed vertex tangents, which must be provided in a vec4 "tangent" attribute, + are used. When disabled, tangents are derived automatically. Using precomputed tangents will give + more accurate normal map details in some cases, such as with mirrored UVs. Default is false. +

    +

    [property:Boolean wireframe]

    将几何体渲染为线框。默认值为*false*(即渲染为平面多边形)。

    @@ -230,6 +235,8 @@

    方法(Methods)

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/MeshToonMaterial.html b/docs/api/zh/materials/MeshToonMaterial.html index 05afebe8e5b26c..177cffd00fae01 100644 --- a/docs/api/zh/materials/MeshToonMaterial.html +++ b/docs/api/zh/materials/MeshToonMaterial.html @@ -8,11 +8,11 @@ - [page:Material] → [page:MeshPhongMaterial] → + [page:Material] → -

    卡通网格材质([name])

    +

    [name]

    -
    [page:MeshPhongMaterial]卡通着色的扩展。
    +
    A material implementing toon shading.
    @@ -32,46 +32,193 @@

    卡通网格材质([name])

    -

    例子(Examples)

    - [example:webgl_materials_variations_toon materials / variations / toon]
    +

    例子

    +

    + [example:webgl_materials_variations_toon materials / variations / toon] +

    -

    构造函数(Constructor)

    +

    Constructor

    [name]( [param:Object parameters] )

    -

    [page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。 - 材质的任何属性都可以从此处传入(包括从[page:Material]和[page:MeshStandardMaterial]继承的任何属性)。

    - 属性[page:Hexadecimal color]例外,其可以作为十六进制字符串传递,默认情况下为 *0xffffff*(白色),内部调用[page:Color.set](color)。 +

    + [page:Object parameters] - (optional) an object with one or more properties defining the material's appearance. + Any property of the material (including any property inherited from [page:Material]) can be passed in here.

    + + The exception is the property [page:Hexadecimal color], which can be passed in as a hexadecimal + string and is *0xffffff* (white) by default. [page:Color.set]( color ) is called internally. +

    + +

    Properties

    +

    See the base [page:Material] class for common properties.

    + +

    [property:Texture alphaMap]

    +

    The alpha map is a grayscale texture that controls the opacity across the surface + (black: fully transparent; white: fully opaque). Default is null.

    + + Only the color of the texture is used, ignoring the alpha channel if one exists. + For RGB and RGBA textures, the [page:WebGLRenderer WebGL] renderer will use the + green channel when sampling this texture due to the extra bit of precision provided + for green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and + luminance/alpha textures will also still work as expected.

    +

    [property:Texture aoMap]

    +

    The red channel of this texture is used as the ambient occlusion map. Default is null. + The aoMap requires a second set of UVs, and consequently will ignore the [page:Texture repeat] + and [page:Texture offset] Texture properties.

    -

    属性(Properties)

    -

    共有属性请参见其基类[page:Material]和[page:MeshPhongMaterial]。

    +

    [property:Float aoMapIntensity]

    +

    Intensity of the ambient occlusion effect. Default is 1. Zero is no occlusion effect.

    + +

    [property:Texture bumpMap]

    +

    + The texture to create a bump map. The black and white values map to the perceived depth in relation to the lights. + Bump doesn't actually affect the geometry of the object, only the lighting. If a normal map is defined this will + be ignored. +

    + +

    [property:Float bumpScale]

    +

    How much the bump map affects the material. Typical ranges are 0-1. Default is 1.

    + + +

    [property:Color color]

    +

    [page:Color] of the material, by default set to white (0xffffff).

    + +

    [property:Texture displacementMap]

    +

    + The displacement map affects the position of the mesh's vertices. Unlike other maps + which only affect the light and shade of the material the displaced vertices can cast shadows, + block other objects, and otherwise act as real geometry. The displacement texture is + an image where the value of each pixel (white being the highest) is mapped against, + and repositions, the vertices of the mesh. +

    + +

    [property:Float displacementScale]

    +

    + How much the displacement map affects the mesh (where black is no displacement, + and white is maximum displacement). Without a displacement map set, this value is not applied. + Default is 1. +

    + +

    [property:Float displacementBias]

    +

    + The offset of the displacement map's values on the mesh's vertices. + Without a displacement map set, this value is not applied. Default is 0. +

    + +

    [property:Color emissive]

    +

    + Emissive (light) color of the material, essentially a solid color unaffected by other lighting. + Default is black. +

    + +

    [property:Texture emissiveMap]

    +

    + Set emisssive (glow) map. Default is null. The emissive map color is modulated by + the emissive color and the emissive intensity. If you have an emissive map, be sure to + set the emissive color to something other than black. +

    + +

    [property:Float emissiveIntensity]

    +

    Intensity of the emissive light. Modulates the emissive color. Default is 1.

    [property:Texture gradientMap]

    -

    卡通着色的渐变贴图,默认值为*null*。

    +

    Gradient map for toon shading. It's required to set [page:Texture.minFilter] and [page:Texture.magFilter] to + [page:Textures THREE.NearestFilter] when using this type of texture. Default is *null*.

    + +

    [property:Texture lightMap]

    +

    The light map. Default is null. The lightMap requires a second set of UVs, + and consequently will ignore the [page:Texture repeat] and [page:Texture offset] + Texture properties.

    -

    [property:Boolean isMeshToonMaterial]

    -

    用于检查此类或派生类是否为卡通网格材质。默认值为 *true*。

    +

    [property:Float lightMapIntensity]

    +

    Intensity of the baked light. Default is 1.

    - 因为其通常用在内部优化,所以不应该更改该属性值。 +

    [property:Texture map]

    +

    The color map. Default is null. The texture map color is modulated by the diffuse [page:.color].

    + +

    [property:boolean morphNormals]

    +

    + Defines whether the material uses morphNormals. Set as true to pass morphNormal + attributes from the [page:Geometry] to the shader. Default is *false*. +

    + +

    [property:Boolean morphTargets]

    +

    Define whether the material uses morphTargets. Default is false.

    + +

    [property:Texture normalMap]

    +

    + The texture to create a normal map. The RGB values affect the surface normal for each pixel fragment and change + the way the color is lit. Normal maps do not change the actual shape of the surface, only the lighting.

    -

    [property:Object defines]

    -

    如下形式的对象: - - { 'TOON': '' }; - +

    [property:Integer normalMapType]

    +

    + The type of normal map.

    + + Options are [page:constant THREE.TangentSpaceNormalMap] (default), and [page:constant THREE.ObjectSpaceNormalMap]. +

    - [page:WebGLRenderer]使用它来选择shaders。 +

    [property:Vector2 normalScale]

    +

    + How much the normal map affects the material. Typical ranges are 0-1. + Default is a [page:Vector2] set to (1,1).

    +

    [property:Float shininess]

    +

    How shiny the [page:.specular] highlight is; a higher value gives a sharper highlight. Default is *30*.

    -

    方法(Methods)

    -

    共有方法请参见其基类[page:Material]和[page:MeshPhongMaterial]。

    +

    [property:Boolean skinning]

    +

    Define whether the material uses skinning. Default is false.

    + +

    [property:Color specular]

    +

    + Specular color of the material. Default is a [page:Color] set to *0x111111* (very dark grey).

    + + This defines how shiny the material is and the color of its shine. +

    + +

    [property:Texture specularMap]

    +

    + The specular map value affects both how much the specular surface highlight + contributes and how much of the environment map affects the surface. Default is null. +

    + +

    [property:Boolean wireframe]

    +

    Render geometry as wireframe. Default is *false* (i.e. render as flat polygons).

    -

    源码(Source)

    +

    [property:String wireframeLinecap]

    +

    + Define appearance of line ends. Possible values are "butt", "round" and "square". Default is 'round'.

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] + This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap 2D Canvas lineCap] + property and it is ignored by the [page:WebGLRenderer WebGL] renderer. +

    + +

    [property:String wireframeLinejoin]

    +

    + Define appearance of line joints. Possible values are "round", "bevel" and "miter". Default is 'round'.

    + + This corresponds to the [link:https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineJoin 2D Canvas lineJoin] + property and it is ignored by the [page:WebGLRenderer WebGL] renderer. +

    + +

    [property:Float wireframeLinewidth]

    +

    Controls wireframe thickness. Default is 1.

    + + Due to limitations of the [link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile] + with the [page:WebGLRenderer WebGL] renderer on most platforms linewidth will + always be 1 regardless of the set value. +

    + +

    Methods

    +

    See the base [page:Material] class for common methods.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/PointsMaterial.html b/docs/api/zh/materials/PointsMaterial.html index 26694f88af7ff1..5cbf490ca46b31 100644 --- a/docs/api/zh/materials/PointsMaterial.html +++ b/docs/api/zh/materials/PointsMaterial.html @@ -14,7 +14,32 @@

    点材质([name])

    [page:Points]使用的默认材质。

    -

    例子(Examples)

    +

    代码示例

    + + + var vertices = []; + + for ( var i = 0; i < 10000; i ++ ) { + + var x = THREE.MathUtils.randFloatSpread( 2000 ); + var y = THREE.MathUtils.randFloatSpread( 2000 ); + var z = THREE.MathUtils.randFloatSpread( 2000 ); + + vertices.push( x, y, z ); + + } + + var geometry = new THREE.BufferGeometry(); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + + var material = new THREE.PointsMaterial( { color: 0x888888 } ); + + var points = new THREE.Points( geometry, material ); + + scene.add( points ); + + +

    例子

    [example:misc_controls_fly misc / controls / fly]
    [example:webgl_buffergeometry_drawcalls WebGL / BufferGeometry / drawcalls]
    @@ -26,36 +51,12 @@

    例子(Examples)

    [example:webgl_interactive_raycasting_points WebGL / interactive / raycasting / points]
    [example:webgl_multiple_elements_text WebGL / multiple / elements / text]
    [example:webgl_points_billboards WebGL / points / billboards]
    - [example:webgl_points_billboards_colors WebGL / points / billboards / colors]
    [example:webgl_points_dynamic WebGL / points / dynamic]
    - [example:webgl_points_random WebGL / points / random]
    [example:webgl_points_sprites WebGL / points / sprites]
    [example:webgl_trails WebGL / trails]

    - -//This will add a starfield to the background of a scene -var starsGeometry = new THREE.Geometry(); - -for ( var i = 0; i < 10000; i ++ ) { - - var star = new THREE.Vector3(); - star.x = THREE.Math.randFloatSpread( 2000 ); - star.y = THREE.Math.randFloatSpread( 2000 ); - star.z = THREE.Math.randFloatSpread( 2000 ); - - starsGeometry.vertices.push( star ); - -} - -var starsMaterial = new THREE.PointsMaterial( { color: 0x888888 } ); - -var starField = new THREE.Points( starsGeometry, starsMaterial ); - -scene.add( starField ); - - -

    [name]( [param:Object parameters] )

    +

    [name]( [param:Object parameters] )

    [page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。 材质的任何属性都可以从此处传入(包括从[page:Material]继承的任何属性)。

    @@ -65,15 +66,19 @@

    [name]( [param:Object parameters] )

    属性(Properties)

    共有属性请参见其基类[page:Material]。

    -

    [property:Color color]

    -

    材质的颜色([page:Color]),默认值为白色 (0xffffff)。

    - -

    [property:Boolean isPointsMaterial]

    -

    用于检查此类或派生类是否为点材质。默认值为 *true*。

    +

    [property:Texture alphaMap]

    +

    alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 + 默认值为null。

    - 因为其通常用在内部优化,所以不应该更改该属性值。 + 仅使用纹理的颜色,忽略alpha通道(如果存在)。 + 对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, + 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。 + Luminance-only以及luminance/alpha纹理也仍然有效。

    +

    [property:Color color]

    +

    材质的颜色([page:Color]),默认值为白色 (0xffffff)。

    +

    [property:Texture map]

    使用[page:Texture]中的数据设置点的颜色。

    @@ -92,6 +97,8 @@

    方法(Methods)

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/RawShaderMaterial.html b/docs/api/zh/materials/RawShaderMaterial.html index 8dacde3f7e2959..2f99673a640ba3 100644 --- a/docs/api/zh/materials/RawShaderMaterial.html +++ b/docs/api/zh/materials/RawShaderMaterial.html @@ -15,7 +15,21 @@

    原始着色器材质([name])

    此类的工作方式与[page:ShaderMaterial]类似,不同之处在于内置的uniforms和attributes的定义不会自动添加到GLSL shader代码中。

    -

    例子(Examples)

    +

    代码示例

    + + + var material = new THREE.RawShaderMaterial( { + + uniforms: { + time: { value: 1.0 } + }, + vertexShader: document.getElementById( 'vertexShader' ).textContent, + fragmentShader: document.getElementById( 'fragmentShader' ).textContent, + + } ); + + +

    例子

    [example:webgl_buffergeometry_rawshader WebGL / buffergeometry / rawshader]
    [example:webgl_buffergeometry_instancing_billboards WebGL / buffergeometry / instancing / billboards]
    @@ -26,18 +40,6 @@

    例子(Examples)

    [example:webgl_raymarching_reflect WebGL / raymarching / reflect]

    - -var material = new THREE.RawShaderMaterial( { - - uniforms: { - time: { value: 1.0 } - }, - vertexShader: document.getElementById( 'vertexShader' ).textContent, - fragmentShader: document.getElementById( 'fragmentShader' ).textContent, - -} ); - -

    构造函数(Constructor)

    [name]( [param:Object parameters] )

    @@ -49,18 +51,14 @@

    [name]( [param:Object parameters] )

    属性(Properties)

    共有属性请参见其基类[page:Material]和[page:ShaderMaterial]。

    -

    [property:Boolean isRawShaderMaterial]

    -

    用于检查此类或派生类是否为点材质。默认值为 *true*。

    - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    - -

    方法(Methods)

    共有方法请参见其基类[page:Material]和[page:ShaderMaterial]。

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/ShaderMaterial.html b/docs/api/zh/materials/ShaderMaterial.html index 3e80a8ffa51a03..1e55df125f43de 100644 --- a/docs/api/zh/materials/ShaderMaterial.html +++ b/docs/api/zh/materials/ShaderMaterial.html @@ -29,13 +29,13 @@

    着色器材质([name])

  • 从 THREE r72开始,不再支持在ShaderMaterial中直接分配属性。 必须使用 [page:BufferGeometry]实例 (而不是 [page:Geometry] 实例),使用[page:BufferAttribute]实例来定义自定义属性。
  • -
  • 从 THREE r77开始,[page:WebGLRenderTarget] 或 [page:WebGLRenderTargetCube] 实例不再被用作uniforms。 +
  • 从 THREE r77开始,[page:WebGLRenderTarget] 或 [page:WebGLCubeRenderTarget] 实例不再被用作uniforms。 必须使用它们的[page:Texture texture] 属性。
  • 内置attributes和uniforms与代码一起传递到shaders。 如果您不希望[page:WebGLProgram]向shader代码添加任何内容,则可以使用[page:RawShaderMaterial]而不是此类。
  • -
  • 您可以使用指令#pragma unroll_loop,以便通过shader预处理器在GLSL中展开for循环。 +
  • 您可以使用指令#pragma unroll_loop_start,#pragma unroll_loop_end 以便通过shader预处理器在GLSL中展开for循环。 该指令必须放在循环的正上方。循环格式必须与定义的标准相对应。
    • 循环必须标准化[link:https://en.wikipedia.org/wiki/Normalized_loop normalized]。 @@ -48,18 +48,38 @@

      着色器材质([name])

    - #pragma unroll_loop + #pragma unroll_loop_start for ( int i = 0; i < 10; i ++ ) { // ... } + #pragma unroll_loop_end
  • -

    例子(Examples)

    +

    代码示例

    + + + var material = new THREE.ShaderMaterial( { + + uniforms: { + + time: { value: 1.0 }, + resolution: { value: new THREE.Vector2() } + + }, + + vertexShader: document.getElementById( 'vertexShader' ).textContent, + + fragmentShader: document.getElementById( 'fragmentShader' ).textContent + + } ); + + +

    例子

    [example:webgl_animation_cloth webgl / animation / cloth ]
    @@ -91,26 +111,8 @@

    例子(Examples)

    [example:webgl_nearestneighbour webgl / nearestneighbour]
    [example:webgl_postprocessing_dof2 webgl / postprocessing / dof2]
    [example:webgl_postprocessing_godrays webgl / postprocessing / godrays] -

    - - var material = new THREE.ShaderMaterial( { - - uniforms: { - - time: { value: 1.0 }, - resolution: { value: new THREE.Vector2() } - - }, - - vertexShader: document.getElementById( 'vertexShader' ).textContent, - - fragmentShader: document.getElementById( 'fragmentShader' ).textContent - - } ); - -

    顶点着色器和片元着色器(Vertex shaders and fragment shaders)

    @@ -314,14 +316,6 @@

    [property:String index0AttributeName]

    -

    [property:Boolean isShaderMaterial]

    -

    用于检查此类或派生类是否为着色器材质。默认值为 *true*。

    - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    - - - -

    [property:Boolean lights]

    材质是否受到光照的影响。默认值为 *false*。如果传递与光照相关的uniform数据到这个材质,则为true。默认是false。

    @@ -331,7 +325,6 @@

    [property:Float linewidth]

    由于[link:https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf OpenGL Core Profile]与大多数平台上[page:WebGLRenderer WebGL]渲染器的限制,无论如何设置该值,线宽始终为1。

    -

    [property:Boolean morphTargets]

    When set to true, morph target attributes are available in the vertex shader. Default is *false*.

    @@ -340,7 +333,6 @@

    [property:boolean morphNormals]

    When set to true, morph normal attributes are available in the vertex shader. Default is *false*.

    -

    [property:WebGLProgram program]

    与此材质相关联的编译后的shader程序,由[page:WebGLRenderer]生成。您应该不需要访问此属性。

    @@ -367,11 +359,14 @@

    [property:Object uniforms]

    注意,uniforms逐帧被刷新,所以更新uniform值将立即更新GLSL代码中的相应值。

    +

    [property:Boolean uniformsNeedUpdate]

    +

    + Can be used to force a uniform update while changing uniforms in [page:Object3D.onBeforeRender](). Default is *false*. +

    -

    [property:Number vertexColors]

    -

    通过定义*colors*属性的生成方式来定义顶点是如何着色的。 - 可选值为[page:Materials THREE.NoColors], [page:Materials THREE.FaceColors] 和 - [page:Materials THREE.VertexColors]。 缺省为 THREE.NoColors。 +

    [property:Boolean vertexColors]

    +

    + Defines whether vertex coloring is used. Default is *false*.

    [property:String vertexShader]

    @@ -403,6 +398,8 @@

    [method:ShaderMaterial clone]() [param:ShaderMaterial this]

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/ShadowMaterial.html b/docs/api/zh/materials/ShadowMaterial.html index 1169a7edee5f8b..72ce9d8ae32695 100644 --- a/docs/api/zh/materials/ShadowMaterial.html +++ b/docs/api/zh/materials/ShadowMaterial.html @@ -8,7 +8,7 @@ - [page:Material] → [page:ShaderMaterial] → + [page:Material] →

    阴影材质([name])

    @@ -16,49 +16,48 @@

    阴影材质([name])

    此材质可以接收阴影,但在其他方面完全透明。

    -

    例子(Example)

    - [example:webgl_geometry_spline_editor geometry / spline / editor] +

    代码示例

    -var planeGeometry = new THREE.PlaneGeometry( 2000, 2000 ); -planeGeometry.rotateX( - Math.PI / 2 ); + var planeGeometry = new THREE.PlaneBufferGeometry( 2000, 2000 ); + planeGeometry.rotateX( - Math.PI / 2 ); -var planeMaterial = new THREE.ShadowMaterial(); -planeMaterial.opacity = 0.2; + var planeMaterial = new THREE.ShadowMaterial(); + planeMaterial.opacity = 0.2; -var plane = new THREE.Mesh( planeGeometry, planeMaterial ); -plane.position.y = -200; -plane.receiveShadow = true; -scene.add( plane ); + var plane = new THREE.Mesh( planeGeometry, planeMaterial ); + plane.position.y = -200; + plane.receiveShadow = true; + scene.add( plane ); +

    例子

    + +

    + [example:webgl_geometry_spline_editor geometry / spline / editor] +

    +

    构造函数(Constructor)

    [name]( [param:Object parameters] )

    [page:Object parameters] - (可选)用于定义材质外观的对象,具有一个或多个属性。 - 材质的任何属性都可以从此处传入(包括从[page:Material] 和 [page:ShaderMaterial]继承的任何属性)。

    + 材质的任何属性都可以从此处传入(包括从[page:Material]]继承的任何属性)。

    属性(Properties)

    -

    共有属性请参见其基类[page:Material]和[page:ShaderMaterial]。

    - -

    [property:Boolean isShadowMaterial]

    -

    用于检查此类或派生类是否为阴影材质。默认值为 *true*。

    - 因为其通常用在内部优化,所以不应该更改该属性值。 -

    - -

    [property:Boolean lights]

    -

    材质是否受到光照的影响。默认值为 *true*。

    +

    共有属性请参见其基类[page:Material]。

    [property:Boolean transparent]

    定义此材质是否透明。默认值为 *true*。

    方法(Methods)

    -

    共有方法请参见其基类[page:Material]和[page:ShaderMaterial]。

    +

    共有方法请参见其基类[page:Material]。

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/materials/SpriteMaterial.html b/docs/api/zh/materials/SpriteMaterial.html index a5ea7f4875fb52..8a9426db73f58d 100644 --- a/docs/api/zh/materials/SpriteMaterial.html +++ b/docs/api/zh/materials/SpriteMaterial.html @@ -14,26 +14,28 @@

    点精灵材质([name])

    一种使用[page:Sprite]的材质。

    -

    例子(Examples)

    -
    - [example:webgl_sprites WebGL / sprites]
    - [example:software_sandbox software / sandbox]
    - [example:svg_sandbox svg / sandbox]
    - [example:webgl_materials_cubemap_dynamic webgl / materials / cubemap / dynamic] -
    +

    代码示例

    -var spriteMap = new THREE.TextureLoader().load( 'textures/sprite.png' ); - -var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } ); + var spriteMap = new THREE.TextureLoader().load( 'textures/sprite.png' ); -var sprite = new THREE.Sprite( spriteMaterial ); -sprite.scale.set(200, 200, 1) + var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } ); -scene.add( sprite ); + var sprite = new THREE.Sprite( spriteMaterial ); + sprite.scale.set(200, 200, 1) + scene.add( sprite ); +

    例子

    +

    + [example:webgl_sprites WebGL / sprites]
    + [example:software_sandbox software / sandbox]
    + [example:svg_sandbox svg / sandbox]
    + [example:webgl_materials_cubemap_dynamic webgl / materials / cubemap / dynamic] +

    + +

    构造函数(Constructor)

    [name]( [param:Object parameters] )

    @@ -49,15 +51,22 @@

    [name]( [param:Object parameters] )

    属性(Properties)

    共有属性请参见其基类[page:Material]。

    +

    [property:Texture alphaMap]

    +

    alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 + 默认值为null。

    + + 仅使用纹理的颜色,忽略alpha通道(如果存在)。 + 对于RGB和RGBA纹理,[page:WebGLRenderer WebGL]渲染器在采样此纹理时将使用绿色通道, + 因为在DXT压缩和未压缩RGB 565格式中为绿色提供了额外的精度。 + Luminance-only以及luminance/alpha纹理也仍然有效。 +

    +

    [property:Color color]

    材质的颜色([page:Color]),默认值为白色 (0xffffff)。 [page:.map]会和 color 相乘。

    [property:boolean fog]

    材质是否受场景雾的影响。默认值为*false*。

    -

    [property:Boolean lights]

    -

    材质是否受到光照的影响。默认值为 *false*。

    -

    [property:Texture map]

    颜色贴图。默认为null。

    @@ -72,6 +81,8 @@

    方法(Methods)

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Box2.html b/docs/api/zh/math/Box2.html index 9e85ba69a64332..e2c5e124b9130a 100644 --- a/docs/api/zh/math/Box2.html +++ b/docs/api/zh/math/Box2.html @@ -60,7 +60,7 @@

    [method:Box2 clone]()

    [method:Boolean containsBox]( [param:Box2 box] )

    [page:Box2 box] - 要检查是否被包含的盒子。

    - 如果盒子包含整个被检查盒子,则返回true。如果两者重叠,
    + 如果盒子包含整个被检查盒子,则返回true。如果两者重叠,
    也会返回true。

    @@ -187,6 +187,8 @@

    [method:Box2 union]( [param:Box2 box] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Box3.html b/docs/api/zh/math/Box3.html index 9cfec34248be84..ac03c31bd380a1 100644 --- a/docs/api/zh/math/Box3.html +++ b/docs/api/zh/math/Box3.html @@ -14,23 +14,24 @@

    [name]

    在3D空间中表示一个盒子或立方体。其主要用于表示物体在世界坐标中的边界框。

    -

    示例

    +

    代码示例

    - // Creating the object whose bounding box we want to compute - var sphereObject = new THREE.Mesh( - new THREE.SphereGeometry(), - new THREE.MeshBasicMaterial( 0xff0000 ) + var box = new THREE.Box3(); + + var mesh = new THREE.Mesh( + new THREE.SphereBufferGeometry(), + new THREE.MeshBasicMaterial() ); - // Creating the actual bounding box with Box3 - sphereObject.geometry.computeBoundingBox(); - var box = sphereObject.geometry.boundingBox.clone(); + + // ensure the bounding box is computed for its geometry + // this should be done only once (assuming static geometries) + mesh.geometry.computeBoundingBox(); // ... - - // In the animation loop, to keep the bounding box updated after move/rotate/scale operations - sphereObject.updateMatrixWorld( true ); - box.copy( sphereObject.geometry.boundingBox ).applyMatrix4( sphereObject.matrixWorld ); + + // in the animation loop, compute the current bounding box with the world matrix + box.copy( mesh.geometry.boundingBox ).applyMatrix4( mesh.matrixWorld );

    构造器(Constructor)

    @@ -49,13 +50,6 @@

    [name]( [param:Vector3 min], [param:Vector3 max] )

    属性(Properties)

    -

    [property:Boolean isBox3]

    -

    - 用于检测当前对象或者派生类对象是否是Box3。默认为 *true*。

    - - 不应该修改这个值,因为内部使用该属性做了优化的任务。 -

    -

    [property:Vector3 min]

    [page:Vector3] 表示包围盒的下边界。
    @@ -294,6 +288,8 @@

    [method:Box3 union]( [param:Box3 box] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Color.html b/docs/api/zh/math/Color.html index 0b378f1eacb815..a1b635999786ff 100644 --- a/docs/api/zh/math/Color.html +++ b/docs/api/zh/math/Color.html @@ -15,28 +15,28 @@

    颜色([name])

    -

    示例(Examples)

    +

    代码示例

    颜色可以用以下任意一种方式初始化。 -//empty constructor - will default white -var color = new THREE.Color(); + //empty constructor - will default white + var color = new THREE.Color(); -//Hexadecimal color (recommended) -var color = new THREE.Color( 0xff0000 ); + //Hexadecimal color (recommended) + var color = new THREE.Color( 0xff0000 ); -//RGB string -var color = new THREE.Color("rgb(255, 0, 0)"); -var color = new THREE.Color("rgb(100%, 0%, 0%)"); + //RGB string + var color = new THREE.Color("rgb(255, 0, 0)"); + var color = new THREE.Color("rgb(100%, 0%, 0%)"); -//X11 color name - all 140 color names are supported. -//Note the lack of CamelCase in the name -var color = new THREE.Color( 'skyblue' ); + //X11 color name - all 140 color names are supported. + //Note the lack of CamelCase in the name + var color = new THREE.Color( 'skyblue' ); -//HSL string -var color = new THREE.Color("hsl(0, 100%, 50%)"); + //HSL string + var color = new THREE.Color("hsl(0, 100%, 50%)"); -//Separate RGB values between 0 and 1 -var color = new THREE.Color( 1, 0, 0 ); + //Separate RGB values between 0 and 1 + var color = new THREE.Color( 1, 0, 0 ); @@ -75,13 +75,6 @@

    [name]( [param:Color_Hex_or_String r], [param:Float g], [param:Float b] )属性(Properties)

    -

    [property:Boolean isColor]

    -

    - 用来检测此类或者派生类是否为颜色。默认值是 *true*。

    - - 不应该去改变这个值,因为它在内部用于优化。 -

    -

    [property:Float r]

    红色通道的值在0到1之间。默认值为1。 @@ -126,7 +119,7 @@

    [method:Color convertGammaToLinear]( [param:Float gammaFactor] )

    [page:Float gammaFactor] - (可选参数). 默认值 *2.0*.

    通过取颜色 [page:.r r], [page:.g g] and [page:.b b] 的 [page:Float gammaFactor] 次方将颜色从伽马空间转换成线性空间。

    - +

    [method:Color convertLinearToGamma]( [param:Float gammaFactor] )

    [page:Float gammaFactor] - (可选参数). 默认值 *2.0*.

    @@ -296,6 +289,15 @@

    [method:Color setStyle]( [param:String style] )

    注意,对于X11颜色名称,多个单词(如暗橙色)变成字符串“darkorange”(全部是小写字母)。

    +

    [method:Color setColorName]( [param:String style] )

    +

    + [page:String style] — color name ( from [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart X11 color names] ).

    + + Sets this color from a color name. Faster than [page:.setStyle] method if you don't need the other CSS-style formats.

    + + For convenience, the list of names is exposed in Color.NAMES as a hash: Color.NAMES.aliceblue // returns 0xF0F8FF +

    +

    [method:Color sub]( [param:Color color] )

    从该颜色的RGB分量中减去传入颜色的RGB分量。如果分量结果是负,则该分量为零。 @@ -311,6 +313,8 @@

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Cylindrical.html b/docs/api/zh/math/Cylindrical.html index b0cad2517a6475..2b916694a4b4a5 100644 --- a/docs/api/zh/math/Cylindrical.html +++ b/docs/api/zh/math/Cylindrical.html @@ -66,6 +66,8 @@

    [method:Cylindrical setFromCartesianCoords]( [param:Float x], [param:Float y

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Euler.html b/docs/api/zh/math/Euler.html index 6a0cf7960e312f..58bf9deb6db61f 100644 --- a/docs/api/zh/math/Euler.html +++ b/docs/api/zh/math/Euler.html @@ -15,9 +15,10 @@

    欧拉角([name])

    欧拉角描述一个旋转变换,通过指定轴顺序和其各个轴向上的指定旋转角度来旋转一个物体。

    -

    示例(Example)

    +

    代码示例

    - var a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); + + var a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); var b = new THREE.Vector3( 1, 0, 1 ); b.applyEuler(a); @@ -38,13 +39,6 @@

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:String ord

    属性(Properties)

    -

    [property:Boolean isEuler]

    -

    - 用于判定此对象或者此类的派生对象是否是欧拉角。默认值为 *true*。

    - - 不应该改变该值,因为它在内部用于优化。 -

    -

    [property:String order]

    order值应用于旋转顺序。默认值为 'XYZ',这意味着对象将首先是 @@ -84,7 +78,7 @@

    [method:Boolean equals]( [param:Euler euler] )

    [method:Euler fromArray]( [param:Array array] )

    长度为3或4的一个 [page:Array array] 。array[3] 是一个可选的 [page:.order order] 参数。

    - + 将欧拉角的x分量设置为 array[0]。
    将欧拉角的x分量设置为 array[1]。
    将欧拉角的x分量设置为 array[2]。
    @@ -153,6 +147,8 @@

    [method:Vector3 toVector3]( [param:Vector3 optionalResult] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Frustum.html b/docs/api/zh/math/Frustum.html index f879fdbfbc85fc..e02fb53c6f5677 100644 --- a/docs/api/zh/math/Frustum.html +++ b/docs/api/zh/math/Frustum.html @@ -86,33 +86,23 @@

    [method:Boolean intersectsSprite]( [param:Sprite sprite] )

    检查精灵[page:Sprite sprite]是否与截锥体相交。

    -

    [method:Frustum set]( [param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5] )

    +

    [method:this set]( [param:Plane p0], [param:Plane p1], [param:Plane p2], [param:Plane p3], [param:Plane p4], [param:Plane p5] )

    - 使用传入的平面设置当前视锥体。没有隐式的顺序。 + Sets the frustum from the passed planes. No plane order is implied.
    + Note that this method only copies the values from the given objects.

    -

    [method:Frustum setFromMatrix]( [param:Matrix4 matrix] )

    +

    [method:this setFromProjectionMatrix]( [param:Matrix4 matrix] )

    - [page:Matrix4 matrix] - [page:Matrix4] 用于设置 [page:.planes planes]

    - - [page:WebGLRenderer] 使用 [page:Camera Camera]的投影矩阵([page:Camera.projectionMatrix projectionMatrix] ) - 和相机世界变换矩阵的逆矩阵 [page:Camera.matrixWorldInverse matrixWorldInverse] 来设置视锥体。 -

    - - - - - - - - - - - + [page:Matrix4 matrix] - Projection [page:Matrix4] used to set the [page:.planes planes]

    + Sets the frustum planes from the projection matrix. +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Interpolant.html b/docs/api/zh/math/Interpolant.html index f4ef7fa3ad42b9..79b775da60756d 100644 --- a/docs/api/zh/math/Interpolant.html +++ b/docs/api/zh/math/Interpolant.html @@ -78,6 +78,8 @@

    [method:null evaluate]( [param:Number t] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Line3.html b/docs/api/zh/math/Line3.html index c1b828e34970e4..eaeac0e4245d96 100644 --- a/docs/api/zh/math/Line3.html +++ b/docs/api/zh/math/Line3.html @@ -112,6 +112,8 @@

    [method:Line3 set]( [param:Vector3 start], [param:Vector3 end] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Math.html b/docs/api/zh/math/MathUtils.html similarity index 79% rename from docs/api/zh/math/Math.html rename to docs/api/zh/math/MathUtils.html index 557774a800f021..97ac7a41ce6bd7 100644 --- a/docs/api/zh/math/Math.html +++ b/docs/api/zh/math/MathUtils.html @@ -100,8 +100,23 @@

    [method:Float smootherstep]( [param:Float x], [param:Float min], [param:Floa 返回一个0-1之间的值。它和smoothstep相同,但变动更平缓。[link:https://en.wikipedia.org/wiki/Smoothstep#Variations variation on smoothstep] 在x=0和x=1处有0阶和二阶导数。

    +

    [method:null setQuaternionFromProperEuler]( [param:Quaternion q], [param:Float a], [param:Float b], [param:Float c], [param:String order] )

    +

    + [page:Quaternion q] - the quaternion to be set
    + [page:Float a] - the rotation applied to the first axis, in radians
    + [page:Float b] - the rotation applied to the second axis, in radians
    + [page:Float c] - the rotation applied to the third axis, in radians
    + [page:String order] - a string specifying the axes order: 'XYX', 'XZX', 'YXY', 'YZY', 'ZXZ', or 'ZYZ'

    + + Sets quaternion [page:Quaternion q] from the [link:http://en.wikipedia.org/wiki/Euler_angles intrinsic Proper Euler Angles] defined by angles [page:Float a], [page:Float b], and [page:Float c], and order [page:String order].
    + + Rotations are applied to the axes in the order specified by [page:String order]: rotation by angle [page:Float a] is applied first, then by angle [page:Float b], then by angle [page:Float c]. Angles are in radians. +

    +

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Matrix3.html b/docs/api/zh/math/Matrix3.html index 3935219ef822cf..4887463fadd3b8 100644 --- a/docs/api/zh/math/Matrix3.html +++ b/docs/api/zh/math/Matrix3.html @@ -14,7 +14,7 @@

    三维矩阵([name])

    一个表示3X3矩阵[link:https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix].的类。

    -

    示例(Example)

    +

    代码示例

    var m = new Matrix3(); @@ -58,25 +58,10 @@

    [property:Array elements]

    矩阵列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]列表。

    -

    [property:Boolean isMatrix3]

    -

    - 用于判定此对象或者此类的派生对象是否是三维矩阵。默认值为 *true*。

    - - 不应该改变该值,因为它在内部用于优化。 -

    -

    方法(Methods)

    -

    [method:Array applyToBufferAttribute]( [param:BufferAttribute attribute] )

    -

    - [page:BufferAttribute attribute] - 表示三维向量缓存属性。

    - - 用这个矩阵乘以缓存属性[page:BufferAttribute attribute]里的所有3d向量。 -

    - -

    [method:Matrix3 clone]()

    创建一个新的矩阵,元素 [page:.elements elements] 与该矩阵相同。

    @@ -91,6 +76,23 @@

    [method:Float determinant]()

    [method:Boolean equals]( [param:Matrix3 m] )

    如果矩阵[page:Matrix3 m] 与当前矩阵所有对应元素相同则返回true。

    +

    [method:this extractBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    +

    + Extracts the [link:https://en.wikipedia.org/wiki/Basis_(linear_algebra) basis] of this + matrix into the three axis vectors provided. If this matrix is: + +a, b, c, +d, e, f, +g, h, i + + then the [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] will be set to: + +xAxis = (a, d, g) +yAxis = (b, e, h) +zAxis = (c, f, i) + +

    +

    [method:this fromArray]( [param:Array array], [param:Integer offset] )

    [page:Array array] - 用来存储设置元素数据的数组
    @@ -191,6 +193,8 @@

    [method:this transposeIntoArray]( [param:Array array] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Matrix4.html b/docs/api/zh/math/Matrix4.html index 2ec9a769a74b19..16c7fa168e4512 100644 --- a/docs/api/zh/math/Matrix4.html +++ b/docs/api/zh/math/Matrix4.html @@ -51,7 +51,7 @@

    注意行优先列优先的顺序。

    这意味着 -var m = new Matrix4(); +var m = new THREE.Matrix4(); m.set( 11, 12, 13, 14, 21, 22, 23, 24, @@ -71,6 +71,24 @@

    注意行优先列优先的顺序。

    请记住,如果您正在阅读源代码,您必须对这里列出的任何矩阵进行转置[link:https://en.wikipedia.org/wiki/Transpose transpose],以理解计算。

    +

    Extracting position, rotation and scale

    +

    + There are several options available for extracting position, rotation and scale from a Matrix4. +

      +
    • + [page:Vector3.setFromMatrixPosition]: can be used to extract the translation component. +
    • +
    • + [page:Vector3.setFromMatrixScale]: can be used to extract the scale component. +
    • +
    • + [page:Quaternion.setFromRotationMatrix], [page:Euler.setFromRotationMatrix] or [page:.extractRotation extractRotation] can be used to extract the rotation component. +
    • +
    • + [page:.decompose decompose] can be used to extract position, rotation and scale all at once. +
    • +
    +

    构造器(Constructor)

    @@ -88,26 +106,11 @@

    [property:Array elements]

    矩阵列优先[link:https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major]列表。

    -

    [property:Boolean isMatrix4]

    -

    - 用于判定此对象或者此类的派生对象是否是三维矩阵。默认值为 *true*。

    - - 不应该改变该值,因为它在内部用于优化。 -

    -

    方法(Methods)

    -

    [method:Array applyToBufferAttribute]( [param:BufferAttribute attribute] )

    -

    - [page:BufferAttribute attribute] - 表示三维向量缓存属性。

    - - 用这个矩阵乘以缓存属性[page:BufferAttribute attribute]里的所有3d向量。 -

    - -

    [method:Matrix4 clone]()

    创建一个新的矩阵,元素[page:.elements elements]与该矩阵相同。

    @@ -203,7 +206,7 @@

    [method:this makeRotationAxis]( [param:Vector3 axis], [param:Float theta] )< 设置当前矩阵为围绕轴 [page:Vector3 axis] 旋转量为 [page:Float theta]弧度。
    - 这是一种有点争议但在数学上可以替代通过四元数[page:Quaternions]旋转的办法。 请参阅此处[link:http://www.gamedev.net/reference/articles/article1199.asp here]的讨论。 + 这是一种有点争议但在数学上可以替代通过四元数[page:Quaternions]旋转的办法。 请参阅此处[link:https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199 here]的讨论。

    [method:this makeBasis]( [param:Vector3 xAxis], [param:Vector3 yAxis], [param:Vector3 zAxis] )

    @@ -387,6 +390,8 @@

    [method:this transpose]()

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Plane.html b/docs/api/zh/math/Plane.html index 44534cfe7dc7f6..8697ce2653a34a 100644 --- a/docs/api/zh/math/Plane.html +++ b/docs/api/zh/math/Plane.html @@ -162,6 +162,8 @@

    [method:Plane translate]( [param:Vector3 offset] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Quaternion.html b/docs/api/zh/math/Quaternion.html index 00d541bbbec4c0..c5c5657d6b6a64 100644 --- a/docs/api/zh/math/Quaternion.html +++ b/docs/api/zh/math/Quaternion.html @@ -11,15 +11,11 @@

    [name]

    - Implementation of a [link:http://en.wikipedia.org/wiki/Quaternion quaternion]. - This is used for [link:https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation rotating things] - without encountering the dreaded - [link:http://en.wikipedia.org/wiki/Gimbal_lock gimbal lock] issue, amongst other - advantages. + Implementation of a [link:http://en.wikipedia.org/wiki/Quaternion quaternion].
    + Quaternions are used in three.js to represent [link:https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation rotations].

    - -

    Example

    +

    代码示例

    var quaternion = new THREE.Quaternion(); @@ -44,13 +40,6 @@

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    Properties

    -

    [property:Boolean isQuaternion]

    -

    - Used to check whether this or derived classes are Quaternions. Default is *true*.

    - - You should not change this, as it is used internally for optimisation. -

    -

    [property:Float x]

    [property:Float y]

    @@ -264,6 +253,8 @@

    [method:null slerpFlat]( [param:Array dst], [param:Integer dstOffset], [para

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Ray.html b/docs/api/zh/math/Ray.html index 4808264c5161a8..fcc7356d5fec0d 100644 --- a/docs/api/zh/math/Ray.html +++ b/docs/api/zh/math/Ray.html @@ -24,7 +24,7 @@

    [name]( [param:Vector3 origin], [param:Vector3 direction] )

    [page:Vector3 origin] - (可选)[page:Ray](射线)的原点,默认值是一个位于(0, 0, 0)的[page:Vector3]。
    [page:Vector3 direction] - [page:Vector3] [page:Ray](射线)的方向。该向量必须经过标准化(使用[page:Vector3.normalize]),这样才能使方法正常运行。 - 默认值是一个位于(0, 0, 0)的[page:Vector3]。

    + 默认值是一个位于(0, 0, -1)的[page:Vector3]。

    创建一个新的[name]。

    @@ -37,7 +37,7 @@

    [property:Vector3 origin]

    [property:Vector3 direction]

    [page:Ray](射线)的方向。该向量必须经过标准化(使用[page:Vector3.normalize]),这样才能使方法正常运行。 - 默认值是一个位于(0, 0, 0)的[page:Vector3]。 + 默认值是一个位于(0, 0, -1)的[page:Vector3]。

    @@ -190,7 +190,7 @@

    [method:Ray set]( [param:Vector3 origin], [param:Vector3 direction] )

    [page:Vector3 origin] - [page:Ray](射线)的[page:.origin origin](原点)。
    [page:Vector3 origin] - [page:Ray](射线)的[page:.direction direction](方向)。 - + 该向量必须经过标准化(使用[page:Vector3.normalize]),这样才能使方法正常运行。

    @@ -201,6 +201,8 @@

    [method:Ray set]( [param:Vector3 origin], [param:Vector3 direction] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Sphere.html b/docs/api/zh/math/Sphere.html index fe37fa23638cae..b73ac6e9b8a8aa 100644 --- a/docs/api/zh/math/Sphere.html +++ b/docs/api/zh/math/Sphere.html @@ -130,6 +130,8 @@

    [method:Sphere translate]( [param:Vector3 offset] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Spherical.html b/docs/api/zh/math/Spherical.html index ee1b55b98a4902..f449aa6bd3f2a0 100644 --- a/docs/api/zh/math/Spherical.html +++ b/docs/api/zh/math/Spherical.html @@ -70,6 +70,8 @@

    [method:Spherical setFromCartesianCoords]( [param:Float x], [param:Float y],

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Triangle.html b/docs/api/zh/math/Triangle.html index de75647b74caa5..6e5b59462f1af9 100644 --- a/docs/api/zh/math/Triangle.html +++ b/docs/api/zh/math/Triangle.html @@ -106,7 +106,7 @@

    [method:Vector3 getNormal]( [param:Vector3 target] )

    [method:Plane getPlane]( [param:Plane target] )

    - [page:Vector3 target] — 结果将会被拷贝到这一Plane中。

    + [page:Plane target] — 结果将会被拷贝到这一Plane中。

    基于三角形计算出一个平面([page:Plane plane])。

    @@ -135,6 +135,8 @@

    [method:Triangle setFromPointsAndIndices]( [param:Array points], [param:Inte

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/Vector2.html b/docs/api/zh/math/Vector2.html index 80ebc395256a2e..9f832d4502389e 100644 --- a/docs/api/zh/math/Vector2.html +++ b/docs/api/zh/math/Vector2.html @@ -34,8 +34,7 @@

    二维向量([name])

    其他的一些事物也可以使用二维向量进行表示,比如说动量矢量、复数等等;但以上这些是它在three.js中的常用用途。

    -

    示例

    - +

    代码示例

    var a = new THREE.Vector2( 0, 1 ); @@ -60,13 +59,6 @@

    [name]( [param:Float x], [param:Float y] )

    属性

    -

    [property:Boolean isVector2]

    -

    - 用于测试这个类或者派生类是否为Vector2,默认为*true*。

    - - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:Float height]

    [page:.y y]的别名。

    @@ -175,10 +167,10 @@

    [method:Float dot]( [param:Vector2 v] )

    计算该vector和所传入[page:Vector2 v]的点积([link:https://en.wikipedia.org/wiki/Dot_product dot product])。

    - +

    [method:Float cross]( [param:Vector2 v] )

    - 计算该vector和所传入[page:Vector2 v]的叉积([link:https://en.wikipedia.org/wiki/Cross_product cross product])。 + 计算该vector和所传入[page:Vector2 v]的叉积([link:https://en.wikipedia.org/wiki/Cross_product cross product])。 请注意,“叉积”在2D中并没有被明确定义。该函数计算的是2D图形中经常使用的几何叉积。

    @@ -203,7 +195,7 @@

    [method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param [page:BufferAttribute attribute] - 来源的attribute。
    [page:Integer index] - 在attribute中的索引。

    - 从[page:BufferAttribute attribute]中设置向量的[page:.x x]值和[page:.y y]值。 + 从[page:BufferAttribute attribute]中设置向量的[page:.x x]值和[page:.y y]值。 、

    [method:Float getComponent]( [param:Integer index] )

    @@ -287,7 +279,7 @@

    [method:this rotateAround]( [param:Vector2 center], [param:float angle] )

    [method:this round]()

    -

    +

    向量中的[page:.x x]分量和[page:.y y]分量四舍五入取整为最接近的整数值。

    @@ -343,6 +335,8 @@

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    - \ No newline at end of file + diff --git a/docs/api/zh/math/Vector3.html b/docs/api/zh/math/Vector3.html index bb25abb4885691..43df0e1dc356a0 100644 --- a/docs/api/zh/math/Vector3.html +++ b/docs/api/zh/math/Vector3.html @@ -14,7 +14,7 @@

    三维向量([name])

    一个三维向量表示的是一个有顺序的、三个为一组的数字组合(标记为x、y和z), 可被用来表示很多事物,例如: - +

      @@ -36,16 +36,15 @@

      三维向量([name])

      但以上这些是它在three.js中的常用用途。

      - -

      示例

      +

      代码示例

      -var a = new THREE.Vector3( 0, 1, 0 ); + var a = new THREE.Vector3( 0, 1, 0 ); -//no arguments; will be initialised to (0, 0, 0) -var b = new THREE.Vector3( ); + //no arguments; will be initialised to (0, 0, 0) + var b = new THREE.Vector3( ); -var d = a.distanceTo( b ); + var d = a.distanceTo( b ); @@ -63,13 +62,6 @@

      [name]( [param:Float x], [param:Float y], [param:Float z] )

      属性

      -

      [property:Boolean isVector3]

      -

      - 用于测试这个类或者派生类是否为Vector3,默认为*true*。

      - - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

      -

      [property:Float x]

      [property:Float y]

      @@ -308,7 +300,7 @@

      [method:this project]( [param:Camera camera] )

      [page:Camera camera] — 在投影中使用的摄像机。

      - 使用所传入的摄像机来投影([link:https://en.wikipedia.org/wiki/Vector_projection projects])该向量。 + Projects this vector from world space into the camera's normalized device coordinate (NDC) space.

      [method:this projectOnPlane]( [param:Vector3 planeNormal] )

      @@ -320,7 +312,7 @@

      [method:this projectOnPlane]( [param:Vector3 planeNormal] )

      [method:this projectOnVector]( [param:Vector3] )

      -

      投影([link:https://en.wikipedia.org/wiki/Vector_projection Projects])该向量到另一个向量上。

      +

      投影([link:https://en.wikipedia.org/wiki/Vector_projection Projects])该向量到向量[page:Vector3 v]上。

      [method:this reflect]( [param:Vector3 normal] )

      @@ -431,13 +423,14 @@

      [method:this unproject]( [param:Camera camera] )

      [page:Camera camera] — 在投影中使用的摄像机。

      - [link:https://en.wikipedia.org/wiki/Vector_projection Unprojects] the vector with the - camera's projection matrix. + Projects this vector from the camera's normalized device coordinate (NDC) space into world space.

      源代码

      - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

      + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

      diff --git a/docs/api/zh/math/Vector4.html b/docs/api/zh/math/Vector4.html index 28ea3e0bfdb5d6..33e156afbfe0f0 100644 --- a/docs/api/zh/math/Vector4.html +++ b/docs/api/zh/math/Vector4.html @@ -32,19 +32,18 @@

      四维向量([name])

    - 其他的一些事物也可以使用二维向量进行表示,但以上这些是它在three.js中的常用用途。 + 其他的一些事物也可以使用四维向量进行表示,但以上这些是它在three.js中的常用用途。

    - -

    示例

    +

    代码示例

    -var a = new THREE.Vector4( 0, 1, 0, 0 ); + var a = new THREE.Vector4( 0, 1, 0, 0 ); -//no arguments; will be initialised to (0, 0, 0, 1) -var b = new THREE.Vector4( ); + //no arguments; will be initialised to (0, 0, 0, 1) + var b = new THREE.Vector4( ); -var d = a.dot( b ); + var d = a.dot( b ); @@ -63,13 +62,6 @@

    [name]( [param:Float x], [param:Float y], [param:Float z], [param:Float w] )

    属性

    -

    [property:Boolean isVector4]

    -

    - 用于测试这个类或者派生类是否为Vector4,默认为*true*。

    - - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:Float x]

    [property:Float y]

    @@ -332,6 +324,8 @@

    [method:Array toArray]( [param:Array array], [param:Integer offset] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/interpolants/CubicInterpolant.html b/docs/api/zh/math/interpolants/CubicInterpolant.html index 003f95a860257d..c9e31d53ee417c 100644 --- a/docs/api/zh/math/interpolants/CubicInterpolant.html +++ b/docs/api/zh/math/interpolants/CubicInterpolant.html @@ -16,7 +16,7 @@

    三次插值([name])

    -

    例子(Example)

    +

    代码示例

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/interpolants/DiscreteInterpolant.html b/docs/api/zh/math/interpolants/DiscreteInterpolant.html index 5b1ce572a108f5..ed31af68290bd4 100644 --- a/docs/api/zh/math/interpolants/DiscreteInterpolant.html +++ b/docs/api/zh/math/interpolants/DiscreteInterpolant.html @@ -16,7 +16,7 @@

    离散插值([name])

    -

    例子(Example)

    +

    代码示例

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/interpolants/LinearInterpolant.html b/docs/api/zh/math/interpolants/LinearInterpolant.html index 1670033ce1afaa..aeb72723a111f3 100644 --- a/docs/api/zh/math/interpolants/LinearInterpolant.html +++ b/docs/api/zh/math/interpolants/LinearInterpolant.html @@ -16,7 +16,7 @@

    线性插值([name])

    -

    例子(Example)

    +

    代码示例

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/math/interpolants/QuaternionLinearInterpolant.html b/docs/api/zh/math/interpolants/QuaternionLinearInterpolant.html index 5bcc2cc36602fd..eaa26f20548efc 100644 --- a/docs/api/zh/math/interpolants/QuaternionLinearInterpolant.html +++ b/docs/api/zh/math/interpolants/QuaternionLinearInterpolant.html @@ -16,7 +16,7 @@

    四元数线性插值([name])

    -

    例子(Example)

    +

    代码示例

    var interpolant = new THREE.[name]( @@ -80,6 +80,8 @@

    [method:null evaluate]( [param:Number t] )

    源码(Source)

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/Bone.html b/docs/api/zh/objects/Bone.html index a4b34b0c3b90ff..87746a5cb4caf0 100644 --- a/docs/api/zh/objects/Bone.html +++ b/docs/api/zh/objects/Bone.html @@ -17,7 +17,7 @@

    骨骼([name])

    骨骼几乎和空白[page:Object3D]相同。

    -

    示例

    +

    代码示例

    var root = new THREE.Bone(); @@ -37,12 +37,6 @@

    [name]( )

    属性

    共有属性请参见其基类[page:Object3D]。

    -

    [property:Boolean isBone]

    -

    - 用于检查这个类或其派生类是否为骨骼。默认值为*true*。

    - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:String type]

    设置为“Bone”,这可以用于在一个场景中找到所有的Bones。

    @@ -53,6 +47,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/Group.html b/docs/api/zh/objects/Group.html index 3aecec28b1e901..937c8799176f54 100644 --- a/docs/api/zh/objects/Group.html +++ b/docs/api/zh/objects/Group.html @@ -16,8 +16,7 @@

    组([name])

    它几乎和[page:Object3D Object3D]是相同的,其目的是使得组中对象在语法上的结构更加清晰。

    - -

    示例

    +

    代码示例

    var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); @@ -54,6 +53,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/InstancedMesh.html b/docs/api/zh/objects/InstancedMesh.html new file mode 100644 index 00000000000000..76c92c9782a49b --- /dev/null +++ b/docs/api/zh/objects/InstancedMesh.html @@ -0,0 +1,91 @@ + + + + + + + + + + + [page:Mesh] → + +

    [name]

    + +

    + A special version of [page:Mesh] with instanced rendering support. Use [name] if you have to render a large number of + objects with the same geometry and material but with different world transformations. The usage of [name] will help you + to reduce the number of draw calls and thus improve the overall rendering performance in your application. +

    +

    + The current implementation requires that materials are not shared between [name] and other 3D objects. +

    + +

    Examples

    + +

    + [example:webgl_instancing_dynamic WebGL / instancing / dynamic]
    + [example:webgl_instancing_modified WebGL / instancing / modified]
    + [example:webgl_instancing_performance WebGL / instancing / performance]
    + [example:webgl_instancing_scatter WebGL / instancing / scatter]
    + [example:webgl_instancing_raycast WebGL / instancing / raycast] +

    + +

    Constructor

    +

    [name]( [param:BufferGeometry geometry], [param:Material material], [param:Integer count] )

    +

    + [page:Geometry geometry] - an instance of [page:BufferGeometry].
    + [page:Material material] - an instance of [page:Material]. Default is a new [page:MeshBasicMaterial].
    + [page:Integer count] - the number of instances.
    +

    + +

    Properties

    +

    See the base [page:Mesh] class for common properties.

    + +

    [property:Integer count]

    +

    + The number of instances. The *count* value passed into the constructor represents the maximum number of + instances of this mesh. You can change the number of instances at runtime to an integer value + in the range [0, count]. +

    +

    + If you need more instances than the original count value, you have to create a new [name]. +

    + +

    [property:BufferAttribute instanceMatrix]

    +

    + Represents the local transformation of all instances. For internal use only. +

    + +

    Methods

    +

    See the base [page:Mesh] class for common methods.

    + +

    [method:null getMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )

    +

    + [page:Integer index]: The index of an instance. Values have to be in the range [0, count]. +

    +

    + [page:Matrix4 matrix]: This 4x4 matrix will be set to the local transformation matrix of the defined instance. +

    +

    + Get the local transformation matrix of the defined instance. +

    + +

    [method:null setMatrixAt]( [param:Integer index], [param:Matrix4 matrix] )

    +

    + [page:Integer index]: The index of an instance. Values have to be in the range [0, count]. +

    +

    + [page:Matrix4 matrix]: A 4x4 matrix representing the local transformation of a single instance. +

    +

    + Sets the given local transformation matrix to the defined instance. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + + diff --git a/docs/api/zh/objects/LOD.html b/docs/api/zh/objects/LOD.html index b740c7f23edece..9dea6fd3232653 100644 --- a/docs/api/zh/objects/LOD.html +++ b/docs/api/zh/objects/LOD.html @@ -18,29 +18,31 @@

    多细节层次([name],Levels of Detail)

    通常情况下,你会创建多个几何体,比如说三个,一个距离很远(低细节),一个距离适中(中等细节),还有一个距离非常近(高质量)。

    -

    示例

    - -

    - [example:webgl_lod webgl / lod ] -

    +

    代码示例

    -var lod = new THREE.LOD(); + var lod = new THREE.LOD(); -//Create spheres with 3 levels of detail and create new LOD levels for them -for( var i = 0; i < 3; i++ ) { + //Create spheres with 3 levels of detail and create new LOD levels for them + for( var i = 0; i < 3; i++ ) { - var geometry = new THREE.IcosahedronBufferGeometry( 10, 3 - i ) + var geometry = new THREE.IcosahedronBufferGeometry( 10, 3 - i ) - var mesh = new THREE.Mesh( geometry, material ); + var mesh = new THREE.Mesh( geometry, material ); - lod.addLevel( mesh, i * 75 ); + lod.addLevel( mesh, i * 75 ); -} + } -scene.add( lod ); + scene.add( lod ); +

    例子

    + +

    + [example:webgl_lod webgl / lod ] +

    +

    Constructor

    [name]( )

    @@ -108,6 +110,8 @@

    [method:null update]( [param:Camera camera] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/Line.html b/docs/api/zh/objects/Line.html index ac85641a4f95d0..1a64ad5742da8f 100644 --- a/docs/api/zh/objects/Line.html +++ b/docs/api/zh/objects/Line.html @@ -19,19 +19,19 @@

    线([name])

    而不是[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements gl.LINES]。

    +

    代码示例

    -

    示例

    - - var material = new THREE.LineBasicMaterial({ + + var material = new THREE.LineBasicMaterial({ color: 0x0000ff }); - var geometry = new THREE.Geometry(); - geometry.vertices.push( - new THREE.Vector3( -10, 0, 0 ), - new THREE.Vector3( 0, 10, 0 ), - new THREE.Vector3( 10, 0, 0 ) - ); + var points = []; + points.push( new THREE.Vector3( - 10, 0, 0 ) ); + points.push( new THREE.Vector3( 0, 10, 0 ) ); + points.push( new THREE.Vector3( 10, 0, 0 ) ); + + var geometry = new THREE.BufferGeometry().setFromPoints( points ); var line = new THREE.Line( geometry, material ); scene.add( line ); @@ -47,20 +47,9 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    [page:Material material] —— 线的材质,默认值是一个新的具有随机颜色的[page:LineBasicMaterial]。

    -

    如果没有指定材质,一个随机颜色的线的材质将会被创建,并应用到该物体上。

    - -

    属性

    共有属性请参见其基类[page:Object3D]。

    -

    [property:Boolean isLine]

    -

    - 用于检查这个类或者其派生类是否为线,默认值为*true*。 - -

    - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:Geometry geometry]

    表示线段的顶点。

    @@ -92,6 +81,8 @@

    [method:Line clone]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/LineLoop.html b/docs/api/zh/objects/LineLoop.html index 3273e9564fc99b..3e3676ba47ebd6 100644 --- a/docs/api/zh/objects/LineLoop.html +++ b/docs/api/zh/objects/LineLoop.html @@ -29,18 +29,9 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    [page:Material material] —— 线的材质,默认值是[page:LineBasicMaterial LineBasicMaterial]。

    -

    如果没有指定材质,一个随机颜色的线的材质将会被创建,并应用到该物体上。

    - -

    属性

    共有属性请参见其基类[page:Line]。

    -

    [property:Boolean isLineLoop]

    -

    - 用于检查这个类或者其派生类是否为环线,默认值为*true*。

    - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    方法

    @@ -48,6 +39,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/LineSegments.html b/docs/api/zh/objects/LineSegments.html index 738747519e5e09..cf6caa5b53d784 100644 --- a/docs/api/zh/objects/LineSegments.html +++ b/docs/api/zh/objects/LineSegments.html @@ -28,24 +28,17 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    [page:Material material] —— 线的材质,默认值是[page:LineBasicMaterial LineBasicMaterial]。

    -

    如果没有指定材质,一个随机颜色的线的材质将会被创建,并应用到该物体上。

    - -

    属性

    共有属性请参见其基类[page:Line]。

    -

    [property:Boolean isLineSegments]

    -

    - 用于检查这个类或者其派生类是否为线段,默认值为*true*。 - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    方法

    共有方法请参见其基类[page:Line]。

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/Mesh.html b/docs/api/zh/objects/Mesh.html index 500c85bc32a466..7f50dc3d63b29a 100644 --- a/docs/api/zh/objects/Mesh.html +++ b/docs/api/zh/objects/Mesh.html @@ -18,7 +18,7 @@

    网格([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); @@ -40,20 +40,6 @@

    [name]( [param:Geometry geometry], [param:Material material] )

    属性

    共有属性请参见其基类[page:Object3D]。

    -

    [property:Integer drawMode]

    -

    - 决定了网格中的三角形将如何从顶点来构造。 - 请参阅draw mode [page:DrawModes constants](绘图模式常量)来查看其所有可能的值。 - 其默认值是[page:DrawModes TrianglesDrawMode]。 -

    - - -

    [property:Boolean isMesh]

    -

    - 用于检查这个类或者其派生类是否为网格,默认值为*true*。

    - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:Geometry geometry]

    [page:Geometry] 或 [page:BufferGeometry] 的实例或者派生类,定义了物体的结构。

    @@ -82,9 +68,6 @@

    [property:Object morphTargetDictionary]

    方法

    共有方法请参见其基类[page:Object3D]。

    -

    [method:null setDrawMode]( [param:Integer value] )

    -

    设置[page:.drawMode drawMode]的值。

    -

    [method:Mesh clone]()

    返回这个[name]对象及其子级的克隆。

    @@ -103,6 +86,8 @@

    [method:null updateMorphTargets]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/Points.html b/docs/api/zh/objects/Points.html index 4294b0218a398a..19d3e384e79936 100644 --- a/docs/api/zh/objects/Points.html +++ b/docs/api/zh/objects/Points.html @@ -40,11 +40,6 @@

    [property:Geometry geometry]

    如有可能,推荐总是使用[page:BufferGeometry]来获得最佳表现。

    -

    [property:Boolean isPoints]

    -

    用于检查这个类或者其派生类是否为点,默认值为*true*。

    - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:Material material]

    [page:Material]的实例。定义了物体的外观。默认值是一个具有随机颜色的[page:PointsMaterial]。 @@ -84,7 +79,9 @@

    [method:null updateMorphTargets]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/Skeleton.html b/docs/api/zh/objects/Skeleton.html index 8512ae3586bf49..d865380107fbcd 100644 --- a/docs/api/zh/objects/Skeleton.html +++ b/docs/api/zh/objects/Skeleton.html @@ -15,29 +15,30 @@

    骨架([name])

    使用一个[page:Bone bones]数组来创建一个可以由[page:SkinnedMesh]使用的骨架。

    -

    实例

    - -// Create a simple "arm" +

    代码示例

    + + // Create a simple "arm" -var bones = []; + var bones = []; -var shoulder = new THREE.Bone(); -var elbow = new THREE.Bone(); -var hand = new THREE.Bone(); + var shoulder = new THREE.Bone(); + var elbow = new THREE.Bone(); + var hand = new THREE.Bone(); -shoulder.add( elbow ); -elbow.add( hand ); + shoulder.add( elbow ); + elbow.add( hand ); -bones.push( shoulder ); -bones.push( elbow ); -bones.push( hand ); + bones.push( shoulder ); + bones.push( elbow ); + bones.push( hand ); -shoulder.position.y = -5; -elbow.position.y = 0; -hand.position.y = 5; + shoulder.position.y = -5; + elbow.position.y = 0; + hand.position.y = 5; + + var armSkeleton = new THREE.Skeleton( bones ); + -var armSkeleton = new THREE.Skeleton( bones ); -

    请查看[page:SkinnedMesh]页面,来查看其在标准的[page:BufferGeometry]中使用的示例。

    @@ -102,13 +103,15 @@

    [method:null update]()

    [method:Bone getBoneByName]( [param:String name] )

    - + name —— 匹配Bone对象中.name属性的字符串。

    在骨架中的骨骼数组中遍览,并返回第一个能够和name匹配上的骨骼对象。

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/SkinnedMesh.html b/docs/api/zh/objects/SkinnedMesh.html index 44588318870f98..e5e8b137881775 100644 --- a/docs/api/zh/objects/SkinnedMesh.html +++ b/docs/api/zh/objects/SkinnedMesh.html @@ -35,7 +35,7 @@

    蒙皮网格([name])

    -

    示例

    +

    代码示例

    var geometry = new THREE.CylinderBufferGeometry( 5, 5, 5, 5, 15, 5, 30 ); @@ -65,8 +65,8 @@

    示例

    } - geometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); - geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); + geometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); + geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); // create skinned mesh and skeleton @@ -91,8 +91,8 @@

    示例

    构造器

    [name]( [param:BufferGeometry geometry], [param:Material material] )

    - [page:BufferGeometry geometry] —— 一个[page:BufferGeometry]实例。
    - [page:Material material] —— (可选)一个[page:Material]实例,默认值是一个新的[page:MeshBasicMaterial]。 + [page:BufferGeometry geometry] —— 一个[page:BufferGeometry]实例。
    + [page:Material material] —— (可选)一个[page:Material]实例,默认值是一个新的[page:MeshBasicMaterial]。

    @@ -119,12 +119,6 @@

    [property:Matrix4 bindMatrixInverse]

    该基础矩阵用于重置绑定骨骼的变换。

    -

    [property:Boolean isSkinnedMesh]

    -

    - 用于检查这个类或者其派生类是否为蒙皮网格,默认值为*true*。

    - 你不应当对这个属性进行改变,因为它在使用,以用于优化。 -

    -

    [property:Skeleton skeleton]

    用于表示蒙皮网格中骨骼的层次结构的[page:Skeleton](骨架)。 @@ -163,6 +157,8 @@

    [method:null updateMatrixWorld]( [param:Boolean force] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/objects/Sprite.html b/docs/api/zh/objects/Sprite.html index 41bd15c3976435..5e006d6701ae72 100644 --- a/docs/api/zh/objects/Sprite.html +++ b/docs/api/zh/objects/Sprite.html @@ -17,11 +17,11 @@

    精灵([name])

    精灵不会投射任何阴影,即使设置了castShadow = true也将不会有任何效果。

    -

    示例

    +

    代码示例

    var spriteMap = new THREE.TextureLoader().load( "sprite.png" ); -var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } ); +var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap } ); var sprite = new THREE.Sprite( spriteMaterial ); scene.add( sprite ); @@ -31,7 +31,7 @@

    构造器

    [name]( [param:Material material] )

    - [page:Material material] - (可选值)是[page:SpriteMaterial]的一个实例。 默认值是一个白色的[page:SpriteMaterial]。

    + [page:Material material] - (可选值)是[page:SpriteMaterial]的一个实例。 默认值是一个白色的[page:SpriteMaterial]。

    创建一个新的[name]。

    @@ -40,12 +40,6 @@

    [name]( [param:Material material] )

    属性

    共有属性请参见其基类[page:Object3D]。

    -

    [property:Boolean isSprite]

    -

    - 用于检查这个类或者其派生类是否为精灵,默认值为*true*。

    - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:SpriteMaterial material]

    @@ -80,6 +74,8 @@

    [method:null raycast]( [param:Raycaster raycaster], [param:Array intersects]

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/WebGLRenderTargetCube.html b/docs/api/zh/renderers/WebGLCubeRenderTarget.html similarity index 75% rename from docs/api/zh/renderers/WebGLRenderTargetCube.html rename to docs/api/zh/renderers/WebGLCubeRenderTarget.html index 26c8b9fbcf2543..11a11e3ab5cbef 100644 --- a/docs/api/zh/renderers/WebGLRenderTargetCube.html +++ b/docs/api/zh/renderers/WebGLCubeRenderTarget.html @@ -24,10 +24,9 @@

    例子

    构造器

    -

    [name]([param:Number width], [param:Number height], [param:Object options])

    +

    [name]([param:Number size], [param:Object options])

    - [page:Float width] - renderTarget的宽度
    - [page:Float height] - renderTarget的高度
    + [page:Float size] - the size, in pixels.
    options - (可选)一个保存着自动生成的目标纹理的纹理参数以及表示是否使用深度缓存/模板缓存的布尔值的对象。 有关纹理参数的说明,请参阅[page:Texture Texture]. 以下是合理选项:

    @@ -54,9 +53,19 @@

    方法

    继承方法,请参阅[page:WebGLRenderTarget]

    +

    [method:WebGLCubeRenderTarget fromEquirectangularTexture]( [param:WebGLRenderer renderer], [param:Texture texture] )

    +

    + [page:WebGLRenderer renderer] — 渲染器。
    + [page:Texture texture] — equirectangular 纹理。 +

    +

    + 如果你想将一张equirectangular格式的全景图转换到cubemap格式,则使用此方法。 +

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/WebGLMultisampleRenderTarget.html b/docs/api/zh/renderers/WebGLMultisampleRenderTarget.html index b0cda86fc81061..b5691980d9d550 100644 --- a/docs/api/zh/renderers/WebGLMultisampleRenderTarget.html +++ b/docs/api/zh/renderers/WebGLMultisampleRenderTarget.html @@ -11,7 +11,8 @@

    [name]

    - TODO + A special render target that can be used to utilize multi-sampled renderbuffers. + Heads up: [name] can only be used with a WebGL 2 rendering context.

    @@ -21,26 +22,30 @@

    Constructor

    [name]([param:Number width], [param:Number height], [param:Object options])

    - [page:Float width] - TODO
    - [page:Float height] - TODO
    - [page:Object options] - TODO + [page:Float width] - The width of the render target.
    + [page:Float height] - The height of the render target.
    + [page:Object options] - (optional) object that holds texture parameters for an auto-generated target + texture and depthBuffer/stencilBuffer booleans.

    Properties

    -

    [property:Number samples]

    +

    [property:number samples]

    - TODO + Specifies the number of samples to be used for the renderbuffer storage. However, the maximum supported + size for multisampling is platform dependent and defined via *gl.MAX_SAMPLES*.

    -

    [page:WebGLRenderTarget WebGLRenderTarget] TODO

    +

    [page:WebGLRenderTarget WebGLRenderTarget] properties are available on this class.

    Methods

    -

    [page:WebGLRenderTarget WebGLRenderTarget] TODO

    +

    [page:WebGLRenderTarget WebGLRenderTarget] methods are available on this class.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/WebGLRenderTarget.html b/docs/api/zh/renderers/WebGLRenderTarget.html index 89809a1ff68602..dbad6f3a64eeea 100644 --- a/docs/api/zh/renderers/WebGLRenderTarget.html +++ b/docs/api/zh/renderers/WebGLRenderTarget.html @@ -56,12 +56,12 @@

    [property:number height]

    [property:Vector4 scissor]

    - 渲染目标视口内的一个矩形区域,区域之外的片元将会被丢弃 + 渲染目标视口内的一个矩形区域,区域之外的片元将会被丢弃

    [property:boolean scissorTest]

    - 表明是否激活了剪裁测试 + 表明是否激活了剪裁测试

    [property:Vector4 viewport]

    @@ -71,7 +71,7 @@

    [property:Vector4 viewport]

    [property:Texture texture]

    - 纹理实例保存这渲染的像素,用作进一步处理的输入值 + 纹理实例保存这渲染的像素,用作进一步处理的输入值

    [property:boolean depthBuffer]

    @@ -81,12 +81,12 @@

    [property:boolean depthBuffer]

    [property:boolean stencilBuffer]

    - 渲染到模板缓冲区。默认true. + 渲染到模板缓冲区。默认true.

    [property:DepthTexture depthTexture]

    - 如果设置,那么场景的深度将会被渲染到慈纹理上。默认是null. + 如果设置,那么场景的深度将会被渲染到慈纹理上。默认是null.

    @@ -104,7 +104,7 @@

    [method:WebGLRenderTarget clone]()

    [method:WebGLRenderTarget copy]( [param:WebGLRenderTarget source] )

    - 采用传入的渲染目标的设置 + 采用传入的渲染目标的设置

    [method:null dispose]()

    @@ -115,6 +115,8 @@

    [page:EventDispatcher EventDispatcher]方法可从此类中获得

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/WebGLRenderer.html b/docs/api/zh/renderers/WebGLRenderer.html index ca044c63d9b473..11239b27f208ec 100644 --- a/docs/api/zh/renderers/WebGLRenderer.html +++ b/docs/api/zh/renderers/WebGLRenderer.html @@ -11,15 +11,15 @@

    [name]

    - WebGL Render 用[link:https://en.wikipedia.org/wiki/WebGL WebGL]渲染出你精心制作的场景。 + WebGL Render 用[link:https://en.wikipedia.org/wiki/WebGL WebGL]渲染出你精心制作的场景。

    构造器

    [name]( [param:Object parameters] )

    - [page:Object parameters] - (可选) 该对象的属性定义了渲染器的行为。也可以完全不传参数。在所有情况下,当缺少参数时,它将采用合理的默认值。 - 以下是合法参数:

    + [page:Object parameters] - (可选) 该对象的属性定义了渲染器的行为。也可以完全不传参数。在所有情况下,当缺少参数时,它将采用合理的默认值。 + 以下是合法参数:

    [page:DOMElement canvas] - 一个供渲染器绘制其输出的[link:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas canvas] 它和下面的[page:WebGLRenderer.domElement domElement]属性对应。 @@ -29,7 +29,7 @@

    [name]( [param:Object parameters] )

    [page:WebGLRenderingContext context] - 可用于将渲染器附加到已有的渲染环境([link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext])中。默认值是null
    [page:String precision] - 着色器精度. 可以是 *"highp"*, *"mediump"* 或者 *"lowp"*. - 如果设备支持,默认为*"highp"* . 点击[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices here] 查看"应该避免的事"
    + 如果设备支持,默认为*"highp"* . 点击[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices here] 查看"应该避免的事"
    [page:Boolean alpha] - canvas是否包含alpha (透明度)。默认为 *false*
    @@ -46,7 +46,7 @@

    [name]( [param:Object parameters] )

    [page:String powerPreference] - 提示用户代理怎样的配置更适用于当前WebGL环境。 可能是*"high-performance"*, *"low-power"* 或 *"default"*。默认是*"default"*. 详见[link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec]
    - + [page:Boolean failIfMajorPerformanceCaveat] - whether the renderer creation will fail upon low perfomance is detected. Default is *false*. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.
    @@ -54,6 +54,8 @@

    [name]( [param:Object parameters] )

    默认是*true*.
    [page:Boolean logarithmicDepthBuffer] - 是否使用对数深度缓存。如果要在单个场景中处理巨大的比例差异,就有必要使用。 + Note that this setting uses gl_FragDepth if available which disables the [link:https://www.khronos.org/opengl/wiki/Early_Fragment_Test Early Fragment Test] + optimization and can cause a decrease in performance. 默认是*false*。 示例:[example:webgl_camera_logarithmicdepthbuffer camera / logarithmicdepthbuffer]

    @@ -94,7 +96,7 @@

    [property:Boolean debug.checkShaderErrors]

    [property:Object capabilities]

    - 一个包含当前渲染环境([link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext])的功能细节的对象。
    + 一个包含当前渲染环境([link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext RenderingContext])的功能细节的对象。
    - [page:Boolean floatFragmentTextures]: 环境是否支持[link:https://developer.mozilla.org/en-US/docs/Web/API/OES_texture_float OES_texture_float]扩展。 根据[link:https://webglstats.com/ WebGLStats], 截至2016年2月,超过95%的支持WebGL的设备支持此功能
    @@ -119,9 +121,9 @@

    [property:Object capabilities]

    [property:Array clippingPlanes]

    - 用户自定义的剪裁平面,在世界空间中被指定为THREE.Plane对象。 - 这些平面全局使用。空间中与该平面点积为负的点将被切掉。 - 默认值是[] + 用户自定义的剪裁平面,在世界空间中被指定为THREE.Plane对象。 + 这些平面全局使用。空间中与该平面点积为负的点将被切掉。 + 默认值是[]

    [property:DOMElement domElement]

    @@ -141,13 +143,9 @@

    [property:Object extensions]

    [property:Float gammaFactor]

    默认是 *2*.

    - -

    [property:Boolean gammaInput]

    -

    如果设置,那么所有的纹理和颜色都会预乘gamma。 默认值是*false*.

    - - -

    [property:Boolean gammaOutput]

    -

    如果设置, 那么它期望所有纹理和颜色需要乘以gamma输出。 默认值*false*.

    +

    [property:number outputEncoding]

    +

    Defines the output encoding of the renderer. Default is [page:Textures THREE.LinearEncoding].

    +

    See the [page:Textures texture constants] page for details of other formats.

    [property:Object info]

    一个对象,包含有关图形板内存和渲染过程的一系列统计信息。这些信息可用于调试或仅仅满足下好奇心。改对象包含以下字段:

    @@ -165,6 +163,7 @@

    [property:Object info]

  • triangles
  • points
  • lines
  • +
  • frame
  • programs @@ -183,8 +182,8 @@

    [property:Boolean localClippingEnabled]

    [property:Integer maxMorphTargets]

    - 默认是8。 一个着色器中允许的最大MorphTargets数。 - 切记标准材质只允许8个MorphTargets。 + 默认是8。 一个着色器中允许的最大MorphTargets数。 + 切记标准材质只允许8个MorphTargets。

    [property:Integer maxMorphNormals]

    @@ -206,16 +205,16 @@

    [property:Object properties]

    [property:WebGLRenderLists renderLists]

    - 在内部用于处理场景渲染对象的排序。 + 在内部用于处理场景渲染对象的排序。

    [property:WebGLShadowMap shadowMap]

    - 如果使用,它包含阴影贴图的引用。 + 如果使用,它包含阴影贴图的引用。

    [property:Boolean shadowMap.enabled]

    -

    如果设置, 请在场景中使用阴影贴图。 默认是 *false*

    +

    如果设置开启,允许在场景中使用阴影贴图。默认是 *false*。

    [property:Boolean shadowMap.autoUpdate]

    启用场景中的阴影自动更新。默认是*true*

    @@ -227,19 +226,19 @@

    [property:Boolean shadowMap.needsUpdate]

    [property:Integer shadowMap.type]

    定义阴影贴图类型 (未过滤, 关闭部分过滤, 关闭部分双线性过滤)

    -

    可选值有THREE.BasicShadowMap, THREE.PCFShadowMap (默认)和 THREE.PCFSoftShadowMap。 详见[page:Renderer Renderer constants]

    +

    可选值有THREE.BasicShadowMap, THREE.PCFShadowMap (默认), THREE.PCFSoftShadowMap 和 THREE.VSMShadowMap。详见[page:Renderer Renderer constants]

    [property:Boolean sortObjects]

    - 定义渲染器是否应对对象进行排序。默认是*true*.

    + 定义渲染器是否应对对象进行排序。默认是*true*.

    - 说明: 排序用于尝试正确渲染出具有一定透明度的对象。根据定义,排序可能不总是有用。根据应用的需求,可能需要关闭排序并使其他方法来处理透明度的渲染,例如, - 手动确定每个对象的显然顺序。 + 说明: 排序用于尝试正确渲染出具有一定透明度的对象。根据定义,排序可能不总是有用。根据应用的需求,可能需要关闭排序并使其他方法来处理透明度的渲染,例如, + 手动确定每个对象的显然顺序。

    [property:Object state]

    - 包含设置[page:WebGLRenderer.context]状态的各种属性的函数。 + 包含设置[page:WebGLRenderer.context]状态的各种属性的函数。

    [property:Constant toneMapping]

    @@ -257,6 +256,16 @@

    [property:Number toneMappingWhitePoint]

    色调映射的白点。默认是*1*

    +

    [property:Object xr]

    +

    + Provides access to the WebXR related interface of the renderer. +

    + +

    [property:Boolean xr.enabled]

    +

    + Whether the renderer should enable XR rendering or not. Default is *false*. +

    +

    方法

    [method:null clear]( [param:Boolean color], [param:Boolean depth], [param:Boolean stencil] )

    @@ -299,8 +308,8 @@

    [method:null dispose]( )

    [method:Object extensions.get]( [param:String extensionName] )

    - 用于检查是否支持各种扩展,并返回一个对象,其中包含扩展的详细信息。 - 该方法检查以下扩展:

    + 用于检查是否支持各种扩展,并返回一个对象,其中包含扩展的详细信息。 + 该方法检查以下扩展:

    - *WEBGL_depth_texture*
    - *EXT_texture_filter_anisotropic*
    @@ -311,7 +320,7 @@

    [method:Object extensions.get]( [param:String extensionName] )

    [method:null forceContextLoss]( )

    - 模拟WebGL环境的丢失。需要支持 + 模拟WebGL环境的丢失。需要支持 [link:https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context WEBGL_lose_context]扩展才能用。 根据[link:https://webglstats.com/ WebGLStats], as of February 2016 90% of WebGL enabled devices support this.

    @@ -349,6 +358,9 @@

    [method:number getPixelRatio]()

    [method:Object getSize]()

    返回包含渲染器输出canvas的宽度和高度(单位像素)的对象。

    +

    [method:null initTexture]( [param:Texture texture] )

    +

    Initializes the given texture. Useful for preloading a texture rather than waiting until first render (which can cause noticeable lags due to decode and GPU upload overhead).

    +

    [method:null resetGLState]( )

    将GL状态重置为默认值。WebGL环境丢失时会内部调用

    @@ -356,7 +368,7 @@

    [method:null readRenderTargetPixels]( [param:WebGLRenderTarget renderTarget]

    buffer - Uint8Array is the only destination type supported in all cases, other types are renderTarget and platform dependent. See [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 WebGL spec] for details.

    将enderTarget中的像素数据读取到传入的缓冲区中。这是[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels WebGLRenderingContext.readPixels]()的包装器
    示例:[example:webgl_interactive_cubes_gpu interactive / cubes / gpu]

    -

    For reading out a [page:WebGLRenderTargetCube WebGLRenderTargetCube] use the optional parameter activeCubeFaceIndex to determine which face should be read.

    +

    For reading out a [page:WebGLCubeRenderTarget WebGLCubeRenderTarget] use the optional parameter activeCubeFaceIndex to determine which face should be read.

    [method:null render]( [param:Scene scene], [param:Camera camera], [param:WebGLRenderTarget renderTarget], [param:Boolean forceClear] )

    @@ -382,7 +394,7 @@

    [method:null renderBufferImmediate]( [param:Object3D object], [param:shaderp

    [method:null setAnimationLoop]( [param:Function callback] )

    [page:Function callback] — 每个可用帧都会调用的函数。 如果传入‘null’,所有正在进行的动画都会停止。

    -

    可用来代替[link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]的内置函数. 对于WebVR项目,必须使用此函数。

    +

    可用来代替[link:https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame]的内置函数. 对于WebXR项目,必须使用此函数。

    [method:null setClearAlpha]( [param:Float alpha] )

    设置alpha。合法参数是一个*0.0*到 *1.0*之间的浮点数

    @@ -390,26 +402,29 @@

    [method:null setClearAlpha]( [param:Float alpha] )

    [method:null setClearColor]( [param:Color color], [param:Float alpha] )

    设置颜色及其透明度

    +

    [method:null setFramebuffer]( [param:WebGLFramebuffer value] )

    +

    Sets the given WebGLFramebuffer. This method can only be used if no render target is set via [page:WebGLRenderer.setRenderTarget .setRenderTarget]().

    +

    [method:null setPixelRatio]( [param:number value] )

    设置设备像素比。通常用于避免HiDPI设备上绘图模糊

    [method:null setRenderTarget]( [param:WebGLRenderTarget renderTarget], [param:Integer activeCubeFace], [param:Integer activeMipmapLevel] )

    renderTarget -- 需要被激活的[page:WebGLRenderTarget renderTarget](可选)。若此参数为空,则将canvas设置成活跃render target。
    - activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLRenderTargetCube] (optional).
    + activeCubeFace -- Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of [page:WebGLCubeRenderTarget] (optional).
    activeMipmapLevel -- Specifies the active mipmap level (optional).

    该方法设置活跃rendertarget。

    [method:null setScissor]( [param:Integer x], [param:Integer y], [param:Integer width], [param:Integer height] )

    - 将剪裁区域设为(x, y)到(x + width, y + height) + 将剪裁区域设为(x, y)到(x + width, y + height) Sets the scissor area from

    [method:null setScissorTest]( [param:Boolean boolean] )

    - 启用或禁用剪裁检测. 若启用,则只有在所定义的裁剪区域内的像素才会受之后的渲染器影响。 + 启用或禁用剪裁检测. 若启用,则只有在所定义的裁剪区域内的像素才会受之后的渲染器影响。

    [method:null setSize]( [param:Integer width], [param:Integer height], [param:Boolean updateStyle] )

    @@ -423,6 +438,8 @@

    [method:null setViewport]( [param:Integer x], [param:Integer y], [param:Inte

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/shaders/ShaderChunk.html b/docs/api/zh/renderers/shaders/ShaderChunk.html index 6bf5cec6daf51c..d3e059aea45b8f 100644 --- a/docs/api/zh/renderers/shaders/ShaderChunk.html +++ b/docs/api/zh/renderers/shaders/ShaderChunk.html @@ -24,6 +24,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/shaders/ShaderLib.html b/docs/api/zh/renderers/shaders/ShaderLib.html index 8144f0fb201847..e336826ec36ffd 100644 --- a/docs/api/zh/renderers/shaders/ShaderLib.html +++ b/docs/api/zh/renderers/shaders/ShaderLib.html @@ -23,6 +23,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/shaders/UniformsLib.html b/docs/api/zh/renderers/shaders/UniformsLib.html index 491b4bd9c30af1..4f6c4ac6b69cdf 100644 --- a/docs/api/zh/renderers/shaders/UniformsLib.html +++ b/docs/api/zh/renderers/shaders/UniformsLib.html @@ -24,6 +24,8 @@

    方法

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/shaders/UniformsUtils.html b/docs/api/zh/renderers/shaders/UniformsUtils.html index 4bfc3890a5674b..8ba568f66e5598 100644 --- a/docs/api/zh/renderers/shaders/UniformsUtils.html +++ b/docs/api/zh/renderers/shaders/UniformsUtils.html @@ -12,16 +12,29 @@

    [name]

    Uniform工具. 支持uniform变量的合并和克隆

    -

    属性

    - +

    方法

    +

    [method:Object clone]( [param:Object src] )

    +

    + src -- An object representing uniform definitions.

    -

    方法

    + Clones the given uniform definitions by performing a deep-copy. That means if + the [page:Uniform.value value] of a uniform refers to an object like a [page:Vector3] + or [page:Texture], the cloned uniform will refer to a new object reference. +

    +

    [method:Object merge]( [param:Array uniforms] )

    +

    + uniforms -- An array of objects containing uniform definitions.

    + Merges the given uniform definitions into a single object. Since the method + internally uses [page:.clone](), it performs a deep-copy when producing the + merged uniform definitions.

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/webgl/WebGLProgram.html b/docs/api/zh/renderers/webgl/WebGLProgram.html index 1d74cecc5cd6e1..6b3b734efd0217 100644 --- a/docs/api/zh/renderers/webgl/WebGLProgram.html +++ b/docs/api/zh/renderers/webgl/WebGLProgram.html @@ -42,7 +42,7 @@

    顶点着色器(无条件的):

    attribute vec2 uv;

    - 注意,可以通过以下方式计算顶点着色器中顶点的位置: + 注意,可以通过以下方式计算顶点着色器中顶点的位置: gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); @@ -132,16 +132,18 @@

    方法

    [method:Object getUniforms]()

    - 返回所有活动态的变量(uniform)位置的name-value映射 + 返回所有活动态的变量(uniform)位置的name-value映射

    [method:Object getAttributes]()

    - 返回所有活动态的顶点属性位置的name-value映射 + 返回所有活动态的顶点属性位置的name-value映射

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/webgl/WebGLShader.html b/docs/api/zh/renderers/webgl/WebGLShader.html index 181ea83bdb797a..8b0647f1d583d3 100644 --- a/docs/api/zh/renderers/webgl/WebGLShader.html +++ b/docs/api/zh/renderers/webgl/WebGLShader.html @@ -12,7 +12,7 @@

    [name]

    编译顶点或片元着色器的更底层的函数

    -

    示例

    +

    代码示例

    var gl = renderer.getContext(); @@ -38,13 +38,15 @@

    [page:WebGLShader objects]([page:WebGLContext gl], [page:WebGLEnum type], [p source -- 着色器源码

    - 此函数将编译一个独立的着色器,不会将它和一个完整的[page:WebGLProgram]链接起来。 + 此函数将编译一个独立的着色器,不会将它和一个完整的[page:WebGLProgram]链接起来。 说明: 这是一个函数,因此不应该使用新的操作符。

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/renderers/webgl/WebGLState.html b/docs/api/zh/renderers/webgl/WebGLState.html index b6e2ef1acebd1f..efb1bad0a85e4f 100644 --- a/docs/api/zh/renderers/webgl/WebGLState.html +++ b/docs/api/zh/renderers/webgl/WebGLState.html @@ -17,12 +17,12 @@

    方法

    [method:null enable]( [param:integer id], [param:boolean boolean] )

    - 未完成 + TODO

    [method:null disable]( [param:integer id], [param:boolean boolean] )

    - 未完成 + TODO

    [method:null setDepthTest]( [param:boolean depthTest] )

    @@ -55,6 +55,8 @@

    [method:null setBlending]( [param:number blending], [param:number blendEquat

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/scenes/Fog.html b/docs/api/zh/scenes/Fog.html index d9a52a36ea2692..3964d1570c5ece 100644 --- a/docs/api/zh/scenes/Fog.html +++ b/docs/api/zh/scenes/Fog.html @@ -46,6 +46,8 @@

    [method:Fog toJSON]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/scenes/FogExp2.html b/docs/api/zh/scenes/FogExp2.html index 2d0abac35cc6c1..e307097d9e0d36 100644 --- a/docs/api/zh/scenes/FogExp2.html +++ b/docs/api/zh/scenes/FogExp2.html @@ -10,9 +10,7 @@

    雾-指数([name])

    -

    - 这个类中的参数定义了指数雾。也就是说,雾的密度是随着距离指数增大的。

    - +

    该类所包含的参数定义了指数雾,它可以在相机附近提供清晰的视野,且距离相机越远,雾的浓度随着指数增长越快。

    构造器

    @@ -42,6 +40,8 @@

    [method:FogExp2 toJSON]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/scenes/Scene.html b/docs/api/zh/scenes/Scene.html index 8408d374ca942c..436b75264272c2 100644 --- a/docs/api/zh/scenes/Scene.html +++ b/docs/api/zh/scenes/Scene.html @@ -26,6 +26,24 @@

    [name]()

    属性

    +

    [property:boolean autoUpdate]

    +

    + 默认值为true,若设置了这个值,则渲染器会检查每一帧是否需要更新场景及其中物体的矩阵。 + 当设为false时,你必须亲自手动维护场景中的矩阵。 +

    + +

    [property:Object background]

    +

    + 若不为空,在渲染场景的时候将设置背景,且背景总是首先被渲染的。 + 可以设置一个用于的“clear”的[page:Color](颜色)、一个覆盖canvas的[page:Texture](纹理),或是一个[page:CubeTexture]。默认值为null。 +

    + +

    [property:Texture environment]

    +

    + If not null, this texture is set as the environment map for all physical materials in the scene. + However, it's not possible to overwrite an existing texture assigned to [page:MeshStandardMaterial.envmap]. Default is null. +

    +

    [property:Fog fog]

    一个[page:Fog fog]实例定义了影响场景中的每个物体的雾的类型。默认值为null。 @@ -35,33 +53,23 @@

    [property:Material overrideMaterial]

    如果不为空,它将强制场景中的每个物体使用这里的材质来渲染。默认值为null。

    -

    [property:boolean autoUpdate]

    -

    - 默认值为true,若设置了这个值,则渲染器会检查每一帧是否需要更新场景及其中物体的矩阵。 - 当设为false时,你必须亲自手动维护场景中的矩阵。 -

    +

    方法

    -

    [property:Object background]

    +

    [method:null dispose]()

    - 若不为空,在渲染场景的时候将设置背景,且背景总是首先被渲染的。 - 可以设置一个用于的“clear”的[page:Color](颜色)、一个覆盖canvas的[page:Texture](纹理),或是一个[page:CubeTexture]。默认值为null。 + 清除[page:WebGLRenderer]内部所缓存的场景相关的数据。

    -

    方法

    -

    [method:JSON toJSON]

    meta -- 包含有元数据的对象,例如场景中的的纹理或图片。 将scene对象转换为 three.js [link:https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 JSON Object/Scene format](three.js JSON 物体/场景格式)。

    -

    [method:null dispose]()

    -

    - 清除[page:WebGLRenderer]内部所缓存的场景相关的数据。 -

    -

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/CanvasTexture.html b/docs/api/zh/textures/CanvasTexture.html index 8d3407659e50be..42375eda6bf023 100644 --- a/docs/api/zh/textures/CanvasTexture.html +++ b/docs/api/zh/textures/CanvasTexture.html @@ -39,11 +39,11 @@

    [name]( [param:HTMLElement canvas], [param:Constant mapping], [param:Constan [page:Constant minFilter] -- 当一个纹素覆盖小于一个像素时,贴图将如何采样。 其默认值为[page:Textures THREE.LinearMipmapLinearFilter]。请参阅[page:Textures minification filter constants](缩小滤镜常量)来了解其它选项。
    - [page:Constant format] -- 在纹理贴图中使用的格式。 - 请参阅[page:Textures format constants](格式常量)来了解各个选项。
    + [page:Constant format] -- 在纹理贴图中使用的格式。 + 请参阅[page:Textures format constants](格式常量)来了解各个选项。
    - [page:Constant type] -- 默认值是[page:Textures THREE.UnsignedByteType]. - 请参阅[page:Textures type constants](类型常量)来了解其他选项。
    + [page:Constant type] -- 默认值是[page:Textures THREE.UnsignedByteType]. + 请参阅[page:Textures type constants](类型常量)来了解其他选项。
    [page:Number anisotropy] -- 沿着轴,通过具有最高纹素密度的像素的样本数。 默认情况下,这个值为1。设置一个较高的值将会产生比基本的mipmap更清晰的效果,代价是需要使用更多纹理样本。 @@ -55,7 +55,7 @@

    属性

    共有方法请参见其基类[page:Texture Texture]。 -

    +

    [property:boolean needsUpdate]

    @@ -65,13 +65,15 @@

    [property:boolean needsUpdate]

    方法

    -

    +

    共有方法请参见其基类[page:Texture Texture]。 -

    +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/CompressedTexture.html b/docs/api/zh/textures/CompressedTexture.html index 83e3750bfa6794..2c122a5dfd7884 100644 --- a/docs/api/zh/textures/CompressedTexture.html +++ b/docs/api/zh/textures/CompressedTexture.html @@ -83,6 +83,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/CubeTexture.html b/docs/api/zh/textures/CubeTexture.html index 28519d56e74f8b..95cf8f5b24ae7c 100644 --- a/docs/api/zh/textures/CubeTexture.html +++ b/docs/api/zh/textures/CubeTexture.html @@ -9,17 +9,17 @@ [page:Texture] → - +

    立方纹理([name])

    创建一个由6张图片所组成的纹理对象。

    -

    示例

    +

    代码示例

    var loader = new THREE.CubeTextureLoader(); loader.setPath( 'textures/cube/pisa/' ); - + var textureCube = loader.load( [ 'px.png', 'nx.png', 'py.png', 'ny.png', @@ -33,7 +33,7 @@

    构造函数

    [name]( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy )

    - +

    CubeTexture(立方贴图)的功能以及用法几乎和[page:Texture]是相同的。区别在于,CubeTexture中的图像是6个单独的图像所组成的数组, 纹理映射选项为[page:Textures THREE.CubeReflectionMapping](默认值)或[page:Textures THREE.CubeRefractionMapping]。 @@ -45,12 +45,14 @@

    属性

    请参阅[page:Texture]页面。

    方法

    - +

    请参阅[page:Texture]页面。

    - +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/DataTexture.html b/docs/api/zh/textures/DataTexture.html index e20530b3023af2..61c95a217d64d5 100644 --- a/docs/api/zh/textures/DataTexture.html +++ b/docs/api/zh/textures/DataTexture.html @@ -32,7 +32,7 @@

    [name]( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, In order to use the types THREE.FloatType and THREE.HalfFloatType, the WebGL implementation must support the respective extensions OES_texture_float and OES_texture_half_float. In order to use THREE.LinearFilter for component-wise, bilinear interpolation of the texels based on these types, the WebGL extensions OES_texture_float_linear or OES_texture_half_float_linear must also be present.

    -

    Example

    +

    代码示例

    // create a buffer with color data @@ -57,7 +57,6 @@

    Example

    // used the buffer to create a [name] var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat ); - texture.needsUpdate = true

    Properties

    @@ -72,6 +71,8 @@

    Methods

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/DataTexture3D.html b/docs/api/zh/textures/DataTexture3D.html index 489c78d5fa6346..a9ce839cc488ac 100644 --- a/docs/api/zh/textures/DataTexture3D.html +++ b/docs/api/zh/textures/DataTexture3D.html @@ -27,10 +27,12 @@

    [name]( [param:TypedArray data], [param:Number width], [param:Number height] [page:Number depth] -- 纹理的深度。

    -

    示例

    +

    例子

    -
    [example:webgl2_materials_texture3d WebGL2 / materials / texture3d]
    -
    [example:webgl2_materials_texture3d_volume WebGL2 / materials / texture3d / volume]
    +

    + [example:webgl2_materials_texture3d WebGL2 / materials / texture3d]
    + [example:webgl2_materials_texture2darray WebGL2 / materials / texture2darray] +

    属性

    @@ -46,6 +48,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/DepthTexture.html b/docs/api/zh/textures/DepthTexture.html index d7b15d12369f6f..b1ac17489ddc08 100644 --- a/docs/api/zh/textures/DepthTexture.html +++ b/docs/api/zh/textures/DepthTexture.html @@ -16,9 +16,10 @@

    深度纹理([name])

    创建一个作为深度纹理贴图来使用的纹理。需要支持[link:https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/ WEBGL_depth_texture]扩展。

    -

    示例

    - - [example:webgl_depth_texture depth / texture] +

    例子

    +

    + [example:webgl_depth_texture depth / texture] +

    构造函数

    [name]( [param:Number width], [param:Number height], [param:Constant type], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Number anisotropy], [param:Constant format] )

    @@ -29,7 +30,7 @@

    [name]( [param:Number width], [param:Number height], [param:Constant type], [page:Number height] -- 纹理的高度。
    [page:Constant type] -- 默认值是[page:Textures THREE.UnsignedShortType]。 - 请参阅[page:Textures type constants](类型常量)来了解其他选项。
    + 请参阅[page:Textures type constants](类型常量)来了解其他选项。
    [page:Constant mapping] -- 请参阅[page:Textures mapping constants](映射模式常量)来了解其他选项。
    @@ -107,6 +108,8 @@

    方法

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/Texture.html b/docs/api/zh/textures/Texture.html index 2742cacefda989..cf9d229058e3bd 100644 --- a/docs/api/zh/textures/Texture.html +++ b/docs/api/zh/textures/Texture.html @@ -17,7 +17,7 @@

    构造函数

    [name]( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding )

    -

    源代码

    +

    代码示例

    // load a texture, set wrap mode to repeat @@ -54,13 +54,6 @@

    [property:Image image]

    并在视频播放时不断地更新这个纹理贴图。——[page:VideoTexture VideoTexture] 类会对此自动进行处理。

    -

    [property:Boolean isTexture]

    -

    - 用于测试这个类或者派生类是否为Texture,默认为*true*。

    - - 你不应当对这个属性进行改变,因为它在内部使用,以用于优化。 -

    -

    [property:array mipmaps]

    用户所给定的mipmap数组(可选)。 @@ -267,6 +260,8 @@

    [method:Vector2 transformUv]( [param:Vector2 uv] )

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/api/zh/textures/VideoTexture.html b/docs/api/zh/textures/VideoTexture.html index ae1c5d4895d0a4..f11e6409a87fa3 100644 --- a/docs/api/zh/textures/VideoTexture.html +++ b/docs/api/zh/textures/VideoTexture.html @@ -18,9 +18,7 @@

    视频纹理([name])

    它和其基类[page:Texture Texture]几乎是相同的,除了它总是将[page:Texture.needsUpdate needsUpdate]设置为*true*,以便使得贴图能够在视频播放时进行更新。自动创建[page:Texture.mipmaps mipmaps]也会被禁用。

    -

    示例

    - -

    [example:webgl_materials_video materials / video ]

    +

    代码示例

    //assuming you have created a HTML video element with id="video" @@ -30,8 +28,11 @@

    示例

    texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.format = THREE.RGBFormat; -
    +
    + +

    例子

    +

    [example:webgl_materials_video materials / video ]

    构造函数

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS], [param:Constant wrapT], [param:Constant magFilter], [param:Constant minFilter], [param:Constant format], [param:Constant type], [param:Number anisotropy] )

    @@ -53,11 +54,11 @@

    [name]( [param:Video video], [param:Constant mapping], [param:Constant wrapS [page:Constant minFilter] -- 当一个纹素覆盖小于一个像素时,贴图将如何采样。 其默认值为[page:Textures THREE.LinearMipmapLinearFilter]。请参阅[page:Textures minification filter constants](缩小滤镜常量)来了解其它选项。
    - [page:Constant format] -- 在纹理贴图中使用的格式。 - 请参阅[page:Textures format constants](格式常量)来了解各个选项。
    + [page:Constant format] -- 在纹理贴图中使用的格式。 + 请参阅[page:Textures format constants](格式常量)来了解各个选项。
    - [page:Constant type] -- 默认值是[page:Textures THREE.UnsignedByteType]. - 请参阅[page:Textures type constants](类型常量)来了解其他选项。
    + [page:Constant type] -- 默认值是[page:Textures THREE.UnsignedByteType]. + 请参阅[page:Textures type constants](类型常量)来了解其他选项。
    [page:Number anisotropy] -- 沿着轴,通过具有最高纹素密度的像素的采样数。 默认情况下,这个值为1。设置一个较高的值将会比基本的mipmap产生更清晰的效果,代价是需要使用更多纹理样本。 @@ -69,7 +70,7 @@

    属性

    共有属性请参见其基类[page:Texture Texture]。 -

    +

    [property:boolean needsUpdate]

    @@ -78,11 +79,11 @@

    [property:boolean needsUpdate]

    方法

    -

    +

    共有方法请参见其基类[page:Texture Texture]。 -

    +

    -

    [method:null update]()

    +

    [method:null update]()

    在每一次新的一帧可用时,这个方法将被自动调用, 并将[property:boolean needsUpdate]设置为*true*。 @@ -91,6 +92,8 @@

    [method:null update]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    diff --git a/docs/examples/en/animations/CCDIKSolver.html b/docs/examples/en/animations/CCDIKSolver.html index 8cc96b82839097..3912b172cbf8c6 100644 --- a/docs/examples/en/animations/CCDIKSolver.html +++ b/docs/examples/en/animations/CCDIKSolver.html @@ -15,13 +15,13 @@

    [name]

    [name] is designed to work with [page:SkinnedMesh] loaded by [page:MMDLoader] but also can be used for generic [page:SkinnedMesh].

    -

    Example

    +

    Code Example

    var ikSolver; // Load MMD resources and instantiate CCDIKSolver - new THREE.MMDLoader().load( + new MMDLoader().load( 'models/mmd/miku.pmd', function ( mesh ) { @@ -40,12 +40,13 @@

    Example

    }
    - [example:webgl_loader_mmd]
    - [example:webgl_loader_mmd_pose]
    - [example:webgl_loader_mmd_audio]
    +

    Examples

    -
    -
    +

    + [example:webgl_loader_mmd]
    + [example:webgl_loader_mmd_pose]
    + [example:webgl_loader_mmd_audio] +

    Constructor

    @@ -97,6 +98,8 @@

    [method:CCDIKSolver update]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/animation/CCDIKSolver.js examples/js/animation/CCDIKSolver.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/CCDIKSolver.js examples/jsm/animation/CCDIKSolver.js] +

    diff --git a/docs/examples/en/animations/MMDAnimationHelper.html b/docs/examples/en/animations/MMDAnimationHelper.html index ae6e804db0a291..48dba14603564d 100644 --- a/docs/examples/en/animations/MMDAnimationHelper.html +++ b/docs/examples/en/animations/MMDAnimationHelper.html @@ -15,14 +15,14 @@

    [name]

    It uses [page:CCDIKSolver] and [page:MMDPhysics] inside.

    -

    Example

    +

    Code Example

    // Instantiate a helper - var helper = new THREE.MMDAnimationHelper(); + var helper = new MMDAnimationHelper(); // Load MMD resources and add to helper - new THREE.MMDLoader().loadWithAnimation( + new MMDLoader().loadWithAnimation( 'models/mmd/miku.pmd', 'models/mmd/dance.vmd', function ( mmd ) { @@ -62,12 +62,13 @@

    Example

    }
    - [example:webgl_loader_mmd]
    - [example:webgl_loader_mmd_pose]
    - [example:webgl_loader_mmd_audio]
    +

    Examples

    -
    -
    +

    + [example:webgl_loader_mmd]
    + [example:webgl_loader_mmd_pose]
    + [example:webgl_loader_mmd_audio] +

    Constructor

    @@ -164,6 +165,8 @@

    [method:MMDAnimationHelper update]( [param:Nummber delta] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/animation/MMDAnimationHelper.js examples/js/animation/MMDAnimationHelper.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDAnimationHelper.js examples/jsm/animation/MMDAnimationHelper.js] +

    diff --git a/docs/examples/en/animations/MMDPhysics.html b/docs/examples/en/animations/MMDPhysics.html index 1117b41954ab2b..c46151702bef9f 100644 --- a/docs/examples/en/animations/MMDPhysics.html +++ b/docs/examples/en/animations/MMDPhysics.html @@ -14,17 +14,17 @@

    [name]

    [name] calculates Physics for model loaded by [page:MMDLoader] with ammo.js (Bullet-based JavaScript Physics engine).

    -

    Example

    +

    Code Example

    var physics; // Load MMD resources and instantiate MMDPhysics - new THREE.MMDLoader().load( + new MMDLoader().load( 'models/mmd/miku.pmd', function ( mesh ) { - physics = new THREE.MMDPhysics( mesh ) + physics = new MMDPhysics( mesh ) scene.add( mesh ); } @@ -40,11 +40,12 @@

    Example

    }
    - [example:webgl_loader_mmd]
    - [example:webgl_loader_mmd_audio]
    +

    Examples

    -
    -
    +

    + [example:webgl_loader_mmd]
    + [example:webgl_loader_mmd_audio] +

    Constructor

    @@ -107,6 +108,8 @@

    [method:CCDIKSolver warmup]( [param:Integer cycles] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/animation/MMDPhysics.js examples/js/animation/MMDPhysics.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDPhysics.js examples/jsm/animation/MMDPhysics.js] +

    diff --git a/docs/examples/en/controls/DeviceOrientationControls.html b/docs/examples/en/controls/DeviceOrientationControls.html new file mode 100644 index 00000000000000..2fa54a1aa8c756 --- /dev/null +++ b/docs/examples/en/controls/DeviceOrientationControls.html @@ -0,0 +1,89 @@ + + + + + + + + + + + +

    [name]

    + +

    + Can be used to orient the camera based on the mobile device's orientation. +

    + +

    Examples

    + +

    [example:misc_controls_deviceorientation misc / controls / deviceorientation ]

    + +

    Constructor

    + +

    [name]( [param:Camera object] )

    +

    +

    + [page:Camera object]: The camera to be controlled. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Properties

    + +

    [property:Number alphaOffset]

    +

    + The alpha offset in radians. Default is *0*. +

    + +

    [property:Object deviceOrientation]

    +

    + The current *deviceorientation* event object. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:Camera object]

    +

    + The camera to be controlled. +

    + +

    [property:Number screenOrientation]

    +

    + The orientation in degrees (in 90-degree increments) of the viewport relative to the device's natural orientation. Default is *0*. +

    + +

    Methods

    + +

    [method:null connect] ()

    +

    + Adds the event listeners of the controls and enables it. +

    + +

    [method:null disconnect] ()

    +

    + Removes the event listeners of the controls and disables it. +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null update] ()

    +

    + Updates the controls. Usually called in the animation loop. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DeviceOrientationControls.js examples/jsm/controls/DeviceOrientationControls.js] +

    + + diff --git a/docs/examples/en/controls/DragControls.html b/docs/examples/en/controls/DragControls.html new file mode 100644 index 00000000000000..2782a47419d250 --- /dev/null +++ b/docs/examples/en/controls/DragControls.html @@ -0,0 +1,131 @@ + + + + + + + + + + + [page:EventDispatcher] → + +

    [name]

    + +

    + This class can be used to provide a drag'n'drop interaction. +

    + +

    Code Example

    + + + var controls = new DragControls( objects, camera, renderer.domElement ); + + // add event listener to highlight dragged objects + + controls.addEventListener( 'dragstart', function ( event ) { + + event.object.material.emissive.set( 0xaaaaaa ); + + } ); + + controls.addEventListener( 'dragend', function ( event ) { + + event.object.material.emissive.set( 0x000000 ); + + } ); + + +

    Examples

    + +

    [example:misc_controls_drag misc / controls / drag ]

    + +

    Constructor

    + +

    [name]( [param:Array objects], [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Array objects]: An array of draggable 3D objects. +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    dragstart

    +

    + Fires when the user starts to drag a 3D object. +

    + +

    drag

    +

    + Fires when the user drags a 3D object. +

    + +

    dragend

    +

    + Fires when the user has finished dragging a 3D object. +

    + +

    hoveron

    +

    + Fires when the pointer is moved onto a 3D object, or onto one of its children. +

    + +

    hoveroff

    +

    + Fires when the pointer is moved out of a 3D object. +

    + +

    Properties

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:Boolean transformGroup]

    +

    + This option only works if the [page:DragControls.objects] array contains a single draggable group object. + If set to *true*, [name] does not transform individual objects but the entire group. Default is *false*. +

    + +

    Methods

    + +

    See the base [page:EventDispatcher] class for common methods.

    + +

    [method:null activate] ()

    +

    + Adds the event listeners of the controls. +

    + +

    [method:null deactivate] ()

    +

    + Removes the event listeners of the controls. +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:Array getObjects] ()

    +

    + Returns the array of draggable objects. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DragControls.js examples/jsm/controls/DragControls.js] +

    + + diff --git a/docs/examples/en/controls/FirstPersonControls.html b/docs/examples/en/controls/FirstPersonControls.html new file mode 100644 index 00000000000000..3f89a334da52bd --- /dev/null +++ b/docs/examples/en/controls/FirstPersonControls.html @@ -0,0 +1,165 @@ + + + + + + + + + + + +

    [name]

    + +

    + This class is an alternative implementation of [page:FlyControls]. +

    + +

    Examples

    + +

    [example:webgl_geometry_terrain webgl / geometry / terrain ]

    + +

    Constructor

    + +

    [name]( [param:Camera object], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera object]: The camera to be controlled. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Properties

    + +

    [property:Boolean activeLook]

    +

    + Whether or not it's possible to look around. Default is *true*. +

    + +

    [property:Boolean autoForward]

    +

    + Whether or not the camera is automatically moved forward. Default is *false*. +

    + +

    [property:Boolean constrainVertical]

    +

    + Whether or not looking around is vertically constrained by [[page:.verticalMin], [page:.verticalMax]]. Default is *false*. +

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. Default is *true*. +

    + +

    [property:Number heightCoef]

    +

    + Determines how much faster the camera moves when it's y-component is near [page:.heightMax]. Default is *1*. +

    + +

    [property:Number heightMax]

    +

    + Upper camera height limit used for movement speed adjusment. Default is *1*. +

    + +

    [property:Number heightMin]

    +

    + Lower camera height limit used for movement speed adjusment. Default is *0*. +

    + +

    [property:Boolean heightSpeed]

    +

    + Whether or not the camera's height influences the forward movement speed. Default is *false*. + Use the properties [page:.heightCoef], [page:.heightMin] and [page:.heightMax] for configuration. +

    + +

    [property:Boolean lookVertical]

    +

    + Whether or not it's possible to vertically look around. Default is *true*. +

    + +

    [property:Number lookSpeed]

    +

    + The look around speed. Default is *0.005*. +

    + +

    [property:Boolean mouseDragOn]

    +

    + Whether or not the mouse is pressed down. Read-only property. +

    + +

    [property:Number movementSpeed]

    +

    + The movement speed. Default is *1*. +

    + +

    [property:Camera object]

    +

    + The camera to be controlled. +

    + +

    [property:Number verticalMax]

    +

    + How far you can vertically look around, upper limit. Range is 0 to Math.PI radians. Default is *Math.PI*. +

    + +

    [property:Number verticalMin]

    +

    + How far you can vertically look around, lower limit. Range is 0 to Math.PI radians. Default is *0*. +

    + +

    Methods

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null handleResize] ()

    +

    + Should be called if the application window is resized. +

    + +

    [method:FirstPersonControls lookAt]( [param:Vector3 vector] )
    + [method:FirstPersonControls lookAt]( [param:Float x], [param:Float y], [param:Float z] )

    +

    +

    +

    + vector - A vector representing the target position. +

    +

    + Optionally, the x, y, z components of the world space position. +

    +

    +

    + Ensures the controls orient the camera towards the defined target position. +

    +

    + +

    [method:null update] ( [param:Number delta] )

    +

    +

    + [page:Number delta]: Time delta value. +

    +

    + Updates the controls. Usually called in the animation loop. +

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/FirstPersonControls.js examples/jsm/controls/FirstPersonControls.js] +

    + + diff --git a/docs/examples/en/controls/FlyControls.html b/docs/examples/en/controls/FlyControls.html new file mode 100644 index 00000000000000..d4a979c5420e3f --- /dev/null +++ b/docs/examples/en/controls/FlyControls.html @@ -0,0 +1,94 @@ + + + + + + + + + + + +

    [name]

    + +

    + [name] enables a navigation similar to fly modes in DCC tools like Blender. You can arbitrarily transform the camera in + 3D space without any limitations (e.g. focus on a specific target). +

    + +

    Examples

    + +

    [example:misc_controls_fly misc / controls / fly ]

    + +

    Constructor

    + +

    [name]( [param:Camera object], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera object]: The camera to be controlled. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Properties

    + +

    [property:Boolean autoForward]

    +

    + If set to *true*, the camera automatically moves forward (and does not stop) when initially translated. Default is *false*. +

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Boolean dragToLook]

    +

    + If set to *true*, you can only look around by performing a drag interaction. Default is *false*. +

    + +

    [property:Number movementSpeed]

    +

    + The movement speed. Default is *1*. +

    + +

    [property:Camera object]

    +

    + The camera to be controlled. +

    + +

    [property:Number rollSpeed]

    +

    + The rotation speed. Default is *0.005*. +

    + +

    Methods

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null update] ( [param:Number delta] )

    +

    +

    + [page:Number delta]: Time delta value. +

    +

    + Updates the controls. Usually called in the animation loop. +

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/FlyControls.js examples/jsm/controls/FlyControls.js] +

    + + diff --git a/docs/examples/en/controls/OrbitControls.html b/docs/examples/en/controls/OrbitControls.html index 5c55164400bbb0..0f9b1de1b3c06b 100644 --- a/docs/examples/en/controls/OrbitControls.html +++ b/docs/examples/en/controls/OrbitControls.html @@ -18,46 +18,46 @@

    [name]

    - -

    Example

    - -

    [example:misc_controls_orbit misc / controls / orbit ]

    +

    Code Example

    -var renderer = new THREE.WebGLRenderer(); -renderer.setSize( window.innerWidth, window.innerHeight ); -document.body.appendChild( renderer.domElement ); + var renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); -var scene = new THREE.Scene(); + var scene = new THREE.Scene(); -var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ); + var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ); -var controls = new THREE.OrbitControls( camera, renderer.domElement ); + var controls = new OrbitControls( camera, renderer.domElement ); -//controls.update() must be called after any manual changes to the camera's transform -camera.position.set( 0, 20, 100 ); -controls.update(); + //controls.update() must be called after any manual changes to the camera's transform + camera.position.set( 0, 20, 100 ); + controls.update(); -function animate() { + function animate() { - requestAnimationFrame( animate ); + requestAnimationFrame( animate ); - // required if controls.enableDamping or controls.autoRotate are set to true - controls.update(); + // required if controls.enableDamping or controls.autoRotate are set to true + controls.update(); - renderer.render( scene, camera ); + renderer.render( scene, camera ); -} + } +

    Examples

    + +

    [example:misc_controls_orbit misc / controls / orbit ]

    +

    Constructor

    [name]( [param:Camera object], [param:HTMLDOMElement domElement] )

    [page:Camera object]: (required) The camera to be controlled. The camera must not be a child of another object, unless that object is the scene itself.

    - [page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document, - however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here. + [page:HTMLDOMElement domElement]: The HTML element used for event listeners.

    @@ -86,7 +86,7 @@

    [property:HTMLDOMElement domElement]

    The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will - not set up new event listeners. Default is the whole document. + not set up new event listeners.

    [property:Boolean enabled]

    @@ -292,6 +292,8 @@

    [method:Boolean update] ()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js examples/js/controls/OrbitControls.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/OrbitControls.js examples/jsm/controls/OrbitControls.js] +

    diff --git a/docs/examples/en/controls/PointerLockControls.html b/docs/examples/en/controls/PointerLockControls.html new file mode 100644 index 00000000000000..b0d1203675cf35 --- /dev/null +++ b/docs/examples/en/controls/PointerLockControls.html @@ -0,0 +1,150 @@ + + + + + + + + + + + [page:EventDispatcher] → + +

    [name]

    + +

    + The implementation of this class is based on the [link:https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API Pointer Lock API]. + [name] is a perfect choice for first person 3D games. +

    + +

    Code Example

    + + + var controls = new PointerLockControls( camera, document.body ); + + // add event listener to show/hide a UI (e.g. the game's menu) + + controls.addEventListener( 'lock', function () { + + menu.style.display = 'none'; + + } ); + + controls.addEventListener( 'unlock', function () { + + menu.style.display = 'block'; + + } ); + + +

    Examples

    + +

    [example:misc_controls_pointerlock misc / controls / pointerlock ]

    + +

    Constructor

    + +

    [name]( [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    change

    +

    + Fires when the user moves the mouse. +

    + +

    lock

    +

    + Fires when the pointer lock status is "locked" (in other words: the mouse is captured). +

    + +

    unlock

    +

    + Fires when the pointer lock status is "unlocked" (in other words: the mouse is not captured anymore). +

    + +

    Properties

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + + +

    [property:Boolean isLocked]

    +

    + Whether or not the controls are locked. +

    + +

    Methods

    + +

    See the base [page:EventDispatcher] class for common methods.

    + +

    [method:null connect] ()

    +

    + Adds the event listeners of the controls. +

    + +

    [method:null disconnect] ()

    +

    + Removes the event listeners of the controls. +

    + +

    [method:Vector3 getDirection] ( [param:Vector3 target] )

    +

    +

    + [page:Vector3 target]: The target vector. +

    +

    + Returns the look direction of the camera. +

    +

    + +

    [method:null lock] ()

    +

    + Activates the pointer lock. +

    + +

    [method:null moveForward] ( [param:Number distance] )

    +

    +

    + [page:Number distance]: The signed distance. +

    +

    + Moves the camera forward parallel to the xz-plane. Assumes camera.up is y-up. +

    +

    + +

    [method:null moveRight] ( [param:Number distance] )

    +

    +

    + [page:Number distance]: The signed distance. +

    +

    + Moves the camera sidewards parallel to the xz-plane. +

    +

    + +

    [method:null unlock] ()

    +

    + Exits the pointer lock. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/PointerLockControls.js examples/jsm/controls/PointerLockControls.js] +

    + + diff --git a/docs/examples/en/controls/TrackballControls.html b/docs/examples/en/controls/TrackballControls.html new file mode 100644 index 00000000000000..9830c7732c5e5c --- /dev/null +++ b/docs/examples/en/controls/TrackballControls.html @@ -0,0 +1,207 @@ + + + + + + + + + + + [page:EventDispatcher] → + +

    [name]

    + +

    +

    + [name] is similar to [page:OrbitControls]. However, it does not maintain a constant camera [page:Object3D.up up] vector. + That means if the camera orbits over the “north” and “south” poles, it does not flip to stay "right side up". +

    +

    + +

    Examples

    + +

    [example:misc_controls_trackball misc / controls / trackball ]

    + +

    Constructor

    + +

    [name]( [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    change

    +

    + Fires when the camera has been transformed by the controls. +

    + +

    start

    +

    + Fires when an interaction (e.g. touch) was initiated. +

    + +

    end

    +

    + Fires when an interaction has finished. +

    + +

    Properties

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Number dynamicDampingFactor]

    +

    + Defines the intensity of damping. Only considered if [page:.staticMoving staticMoving] is set to *false*. Default is *0.2*. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:Array keys]

    +

    + This array holds keycodes for controlling interactions. +

      +
    • When the first defined key is pressed, all mouse interactions (left, middle, right) performs orbiting.
    • +
    • When the second defined key is pressed, all mouse interactions (left, middle, right) performs zooming.
    • +
    • When the third defined key is pressed, all mouse interactions (left, middle, right) performs panning.
    • +
    + Default is *65, 83, 68* which represents A, S, D. +

    + +

    [property:Number maxDistance]

    +

    + How far you can zoom in. Default is *Infinity*. +

    + +

    [property:Number minDistance]

    +

    + How far you can zoom in. Default is *0*. +

    + +

    + [property:Object mouseButtons]

    +

    + This object contains references to the mouse actions used by the controls. +

      +
    • .LEFT is assinged with *THREE.MOUSE.ROTATE*
    • +
    • .MIDDLE is assinged with *THREE.MOUSE.ZOOM*
    • +
    • .RIGHT is assinged with *THREE.MOUSE.PAN*
    • +
    +

    + +

    [property:Boolean noPan]

    +

    + Whether or not panning is disabled. Default is *false*. +

    + +

    [property:Boolean noRotate]

    +

    + Whether or not rotation is disabled. Default is *false*. +

    + +

    [property:Boolean noZoom]

    +

    + Whether or not zooming is disabled. Default is *false*. +

    + +

    [property:Camera object]

    +

    + The camera being controlled. +

    + +

    [property:Number panSpeed]

    +

    + The zoom speed. Default is *0.3*. +

    + +

    [property:Number rotateSpeed]

    +

    + The rotation speed. Default is *1.0*. +

    + +

    [property:Object screen]

    +

    + Represents the properties of the screen. Automatically set when [page:.handleResize handleResize]() is called. +

      +
    • left: Represents the offset in pixels to the screen's left boundary.
    • +
    • top: Represents the offset in pixels to the screen's top boundary.
    • +
    • width: Represents the screen width in pixels.
    • +
    • height: Represents the screen height in pixels.
    • +
    +

    + +

    [property:Boolean staticMoving]

    +

    + Whether or not damping is disabled. Default is *false*. +

    + +

    [property:Number zoomSpeed]

    +

    + The zoom speed. Default is *1.2*. +

    + +

    Methods

    + +

    [method:null checkDistances] ()

    +

    + Ensures the controls stay in the range [minDistance, maxDistance]. Called by [page:.update update](). +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null handleResize] ()

    +

    + Should be called if the application window is resized. +

    + +

    [method:null panCamera] ()

    +

    + Performs panning if necessary. Called by [page:.update update](). +

    + +

    [method:null reset] ()

    +

    + Resets the controls to its initial state. +

    + +

    [method:null rotateCamera] ()

    +

    + Rotates the camera if necessary. Called by [page:.update update](). +

    + +

    [method:null update] ()

    +

    + Updates the controls. Usually called in the animation loop. +

    + +

    [method:null zoomCamera] ()

    +

    + Performs zooming if necessary. Called by [page:.update update](). +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/TrackballControls.js examples/jsm/controls/TrackballControls.js] +

    + + diff --git a/docs/examples/en/controls/TransformControls.html b/docs/examples/en/controls/TransformControls.html new file mode 100644 index 00000000000000..02a0059af8b4dc --- /dev/null +++ b/docs/examples/en/controls/TransformControls.html @@ -0,0 +1,226 @@ + + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + This class can be used to transform objects in 3D space by adapting a similar interaction model of DCC tools like Blender. + Unlike other controls, it is not intended to transform the scene's camera.

    + + [name] expects that its attached 3D object is part of the scene graph. +

    + +

    Examples

    + +

    [example:misc_controls_transform misc / controls / transform ]

    + +

    Constructor

    + +

    [name]( [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    change

    +

    + Fires if any type of change (object or property change) is performed. Property changes + are separate events you can add event listeners to. The event type is "propertyname-changed". +

    + +

    mouseDown

    +

    + Fires if a pointer (mouse/touch) becomes active. +

    + +

    mouseUp

    +

    + Fires if a pointer (mouse/touch) is no longer active. +

    + +

    objectChange

    +

    + Fires if the controlled 3D object is changed. +

    + +

    Properties

    + +

    See the base [page:Object3D] class for common properties.

    + +

    [property:String axis]

    +

    + The current transformation axis. +

    + +

    [property:Camera camera]

    +

    + The camera of the rendered scene. +

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Boolean dragging]

    +

    + Whether or not dragging is currently performed. Read-only property. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:String mode]

    +

    + The current transformation mode. Possible values are "translate", "rotate" and "scale". Default is *translate*. +

    + +

    [property:Object3D object]

    +

    + The 3D object being controlled. +

    + +

    [property:Number rotationSnap]

    +

    + By default, 3D objects are continously rotated. If you set this property to a numeric value (radians), you can define in which + steps the 3D object should be rotated. Deault is *null*. +

    + +

    [property:Boolean showX]

    +

    + Whether or not the x-axis helper should be visible. Default is *true*. +

    + +

    [property:Boolean showY]

    +

    + Whether or not the y-axis helper should be visible. Default is *true*. +

    + +

    [property:Boolean showZ]

    +

    + Whether or not the z-axis helper should be visible. Default is *true*. +

    + +

    [property:Number size]

    +

    + The size of the helper UI (axes/planes). Default is *1*. +

    + +

    [property:String space]

    +

    + Defines in which coordinate space transformations should be performed. Possible values are "world" and "local". Default is *world*. +

    + +

    [property:Number translationSnap]

    +

    + By default, 3D objects are continously translated. If you set this property to a numeric value (world units), you can define in which + steps the 3D object should be translated. Deault is *null*. +

    + +

    Methods

    + +

    See the base [page:Object3D] class for common methods.

    + +

    [method:TransformControls attach] ( [param:Object3D object] )

    +

    +

    + [page:Object3D object]: The 3D object that should be transformed. +

    +

    + Sets the 3D object that should be transformed and ensures the controls UI is visible. +

    +

    + +

    [method:TransformControls detach] ()

    +

    + Removes the current 3D object from the controls and makes the helper UI is invisible. +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:String getMode] ()

    +

    + Returns the transformation mode. +

    + +

    [method:null setMode] ( [param:String mode] )

    +

    +

    + [page:String mode]: The transformation mode. +

    +

    + Sets the transformation mode. +

    +

    + +

    [method:null setRotationSnap] ( [param:Number rotationSnap] )

    +

    +

    + [page:Number rotationSnap]: The rotation snap. +

    +

    + Sets the rotation snap. +

    +

    + +

    [method:null setSize] ( [param:Number size] )

    +

    +

    + [page:Number size]: The size of the helper UI. +

    +

    + Sets the size of the helper UI. +

    +

    + +

    [method:null setSpace] ( [param:String space] )

    +

    +

    + [page:String space]: The coordinate space in which transformations are applied. +

    +

    + Sets the coordinate space in which transformations are applied. +

    +

    + +

    [method:null setTranslationSnap] ( [param:Number translationSnap] )

    +

    +

    + [page:Number translationSnap]: The translation snap. +

    +

    + Sets the translation snap. +

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/TransformControls.js examples/jsm/controls/TransformControls.js] +

    + + diff --git a/docs/examples/en/exporters/ColladaExporter.html b/docs/examples/en/exporters/ColladaExporter.html index f43949e5b8645f..065469e13238a8 100644 --- a/docs/examples/en/exporters/ColladaExporter.html +++ b/docs/examples/en/exporters/ColladaExporter.html @@ -18,11 +18,11 @@

    [name]

    This exporter only supports exporting geometry, materials, textures, and scene hierarchy.

    -

    Example

    +

    Code Example

    // Instantiate an exporter - var exporter = new THREE.ColladaExporter(); + var exporter = new ColladaExporter(); // Parse the input and generate the ply output var data = exporter.parse( scene, null, options ); @@ -76,6 +76,8 @@

    [method:null parse]( [param:Object3D input], [param:Function onCompleted], [

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/ColladaExporter.js examples/js/exporters/ColladaExporter.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/ColladaExporter.js examples/jsm/exporters/ColladaExporter.js] +

    diff --git a/docs/examples/en/exporters/GLTFExporter.html b/docs/examples/en/exporters/GLTFExporter.html index a79124f140a22a..70b42cff3b4c04 100644 --- a/docs/examples/en/exporters/GLTFExporter.html +++ b/docs/examples/en/exporters/GLTFExporter.html @@ -34,11 +34,11 @@

    Extensions

  • KHR_texture_transform
  • -

    Example

    +

    Code Example

    // Instantiate a exporter - var exporter = new THREE.GLTFExporter(); + var exporter = new GLTFExporter(); // Parse the input and generate the glTF output exporter.parse( scene, function ( gltf ) { @@ -47,7 +47,11 @@

    Example

    }, options );
    - [example:misc_exporter_gltf] +

    Examples

    + +

    + [example:misc_exporter_gltf] +

    Constructor

    @@ -94,6 +98,7 @@

    [method:null parse]( [param:Object3D input], [param:Function onCompleted], [
  • truncateDrawRange - bool. Export just the attributes within the drawRange, if defined, instead of exporting the whole array. Default is true.
  • binary - bool. Export in binary (.glb) format, returning an ArrayBuffer. Default is false.
  • embedImages - bool. Export with images embedded into the glTF asset. Default is true.
  • +
  • maxTextureSize - int. Restricts the image maximum size (both width and height) to the given value. This option works only if embedImages is true. Default is Infinity.
  • animations - Array<[page:AnimationClip AnimationClip]>. List of animations to be included in the export.
  • forceIndices - bool. Generate indices for non-index geometry and export with them. Default is false.
  • forcePowerOfTwoTextures - bool. Export with images resized to POT size. This option works only if embedImages is true. Default is false.
  • @@ -106,6 +111,8 @@

    [method:null parse]( [param:Object3D input], [param:Function onCompleted], [

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/GLTFExporter.js examples/js/exporters/GLTFExporter.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/GLTFExporter.js examples/jsm/exporters/GLTFExporter.js] +

    diff --git a/docs/examples/en/exporters/PLYExporter.html b/docs/examples/en/exporters/PLYExporter.html index 6b4672b1c9bc90..c0b4b0a0c7ca67 100644 --- a/docs/examples/en/exporters/PLYExporter.html +++ b/docs/examples/en/exporters/PLYExporter.html @@ -19,11 +19,11 @@

    [name]

    uv coordinates. No textures or texture references are saved.

    -

    Example

    +

    Code Example

    // Instantiate an exporter - var exporter = new THREE.PLYExporter(); + var exporter = new PLYExporter(); // Parse the input and generate the ply output var data = exporter.parse( scene, options ); @@ -59,6 +59,8 @@

    [method:null parse]( [param:Object3D input], [param:Function onDone], [param

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/PLYExporter.js examples/js/exporters/PLYExporter.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/PLYExporter.js examples/jsm/exporters/PLYExporter.js] +

    diff --git a/docs/examples/en/geometries/ConvexBufferGeometry.html b/docs/examples/en/geometries/ConvexBufferGeometry.html index dc33ecf1773765..e37c236334a243 100644 --- a/docs/examples/en/geometries/ConvexBufferGeometry.html +++ b/docs/examples/en/geometries/ConvexBufferGeometry.html @@ -16,32 +16,18 @@

    [name]

    [name] can be used to generate a convex hull for a given array of 3D points. The average time complexity for this task is considered to be O(nlog(n)).

    - - -

    Example

    - -

    [example:webgl_geometry_convex geometry / convex ]

    - - var geometry = new THREE.ConvexBufferGeometry( points ); + var geometry = new ConvexBufferGeometry( points ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); +

    Examples

    + +

    [example:webgl_geometry_convex geometry / convex ]

    +

    Constructor

    [name]( [param:Array points] )

    @@ -52,6 +38,8 @@

    [name]( [param:Array points] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/geometries/ConvexGeometry.js examples/js/geometries/ConvexGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/ConvexGeometry.js examples/jsm/geometries/ConvexGeometry.js] +

    diff --git a/docs/examples/en/geometries/ConvexGeometry.html b/docs/examples/en/geometries/ConvexGeometry.html index 1ff026b3b0d4bb..402414e83a1eb6 100644 --- a/docs/examples/en/geometries/ConvexGeometry.html +++ b/docs/examples/en/geometries/ConvexGeometry.html @@ -15,32 +15,18 @@

    [name]

    [name] can be used to generate a convex hull for a given array of 3D points. The average time complexity for this task is considered to be O(nlog(n)).

    - - -

    Example

    - -

    [example:webgl_geometry_convex geometry / convex ]

    - - var geometry = new THREE.ConvexGeometry( points ); + var geometry = new ConvexGeometry( points ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); +

    Examples

    + +

    [example:webgl_geometry_convex geometry / convex ]

    +

    Constructor

    [name]( [param:Array points] )

    @@ -51,6 +37,8 @@

    [name]( [param:Array points] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/geometries/ConvexGeometry.js examples/js/geometries/ConvexGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/ConvexGeometry.js examples/jsm/geometries/ConvexGeometry.js] +

    diff --git a/docs/examples/en/geometries/DecalGeometry.html b/docs/examples/en/geometries/DecalGeometry.html index 3dae0c950f2ffe..9a7f33f6dd75cb 100644 --- a/docs/examples/en/geometries/DecalGeometry.html +++ b/docs/examples/en/geometries/DecalGeometry.html @@ -14,32 +14,19 @@

    [name]

    [name] can be used to create a decal mesh that serves different kinds of purposes e.g. adding unique details to models, performing dynamic visual environmental changes or covering seams.

    - - -

    Example

    - -

    [example:webgl_decals decals ]

    - - var geometry = new THREE.DecalGeometry( mesh, position, orientation, size ); + + var geometry = new DecalGeometry( mesh, position, orientation, size ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); +

    Examples

    + +

    [example:webgl_decals WebGL / decals]

    +

    Constructor

    [name]( [param:Mesh mesh], [param:Vector3 position], [param:Euler orientation], [param:Vector3 size] )

    @@ -52,6 +39,8 @@

    [name]( [param:Mesh mesh], [param:Vector3 position], [param:Euler orientatio

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/geometries/DecalGeometry.js examples/js/geometries/DecalGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/DecalGeometry.js examples/jsm/geometries/DecalGeometry.js] +

    diff --git a/docs/api/en/helpers/FaceNormalsHelper.html b/docs/examples/en/helpers/FaceNormalsHelper.html similarity index 87% rename from docs/api/en/helpers/FaceNormalsHelper.html rename to docs/examples/en/helpers/FaceNormalsHelper.html index 5022ec2d0b4271..288b0f03e0aae1 100644 --- a/docs/api/en/helpers/FaceNormalsHelper.html +++ b/docs/examples/en/helpers/FaceNormalsHelper.html @@ -21,22 +21,23 @@

    [name]

    For [page:BufferGeometry] use a [page:VertexNormalsHelper] instead.

    - -

    Example

    - -
    [example:webgl_helpers WebGL / helpers]
    +

    Code Example

    geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); box = new THREE.Mesh( geometry, material ); - helper = new THREE.FaceNormalsHelper( box, 2, 0x00ff00, 1 ); + helper = new FaceNormalsHelper( box, 2, 0x00ff00, 1 ); scene.add( box ); scene.add( helper ); +

    Examples

    + +

    [example:webgl_helpers WebGL / helpers]

    +

    Constructor

    @@ -76,6 +77,8 @@

    [method:null update]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/FaceNormalsHelper.js examples/jsm/helpers/FaceNormalsHelper.js] +

    diff --git a/docs/examples/en/helpers/LightProbeHelper.html b/docs/examples/en/helpers/LightProbeHelper.html new file mode 100644 index 00000000000000..e8a4e21d6735f8 --- /dev/null +++ b/docs/examples/en/helpers/LightProbeHelper.html @@ -0,0 +1,61 @@ + + + + + + + + + + + [page:Object3D] → [page:Mesh] → + +

    [name]

    + +

    + Renders a sphere to visualize a light probe in the scene. +

    + +

    Code Example

    + + + var helper = new LightProbeHelper( lightProbe, 1 ); + scene.add( helper ); + + +

    Examples

    + +

    [example:webgl_lightprobe_cubecamera WebGL / lightprobe / cubecamera]

    + +

    Constructor

    + +

    [name]( [param:LightProbe lightProbe], [param:Number size] )

    +

    + [page:LightProbe lightProbe] -- the light probe.
    + [page:Number size] -- size of the helper sphere +

    + + +

    Properties

    +

    See the base [page:Mesh] class for common properties.

    + +

    [property:LightProbe lightProbe]

    +

    The light probe.

    + +

    [property:Number size]

    +

    The size of the helper sphere.

    + +

    Methods

    +

    See the base [page:Mesh] class for common methods.

    + +

    [method:null dispose]()

    +

    Frees internal resources.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/LightProbeHelper.js examples/jsm/helpers/LightProbeHelper.js] +

    + + diff --git a/docs/api/en/helpers/PositionalAudioHelper.html b/docs/examples/en/helpers/PositionalAudioHelper.html similarity index 82% rename from docs/api/en/helpers/PositionalAudioHelper.html rename to docs/examples/en/helpers/PositionalAudioHelper.html index 61b1ff7ce6d5c2..f262c5bb9f3554 100644 --- a/docs/api/en/helpers/PositionalAudioHelper.html +++ b/docs/examples/en/helpers/PositionalAudioHelper.html @@ -14,19 +14,18 @@

    [name]

    This helper displays the directional cone of a [page:PositionalAudio].

    -

    Example

    - -
    [example:webaudio_orientation webaudio / orientation ]
    -

    Code Example

    -var positionalAudio = new THREE.PositionalAudio( listener ); -positionalAudio.setDirectionalCone( 180, 230, 0.1 ); + var positionalAudio = new THREE.PositionalAudio( listener ); + positionalAudio.setDirectionalCone( 180, 230, 0.1 ); -var helper = new PositionalAudioHelper( positionalAudio ); -positionalAudio.add( helper ); + var helper = new PositionalAudioHelper( positionalAudio ); + positionalAudio.add( helper ); +

    Examples

    + +
    [example:webaudio_orientation webaudio / orientation ]

    Constructor

    @@ -68,6 +67,8 @@

    [method:null update]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/PositionalAudioHelper.js examples/jsm/helpers/PositionalAudioHelper.js] +

    diff --git a/docs/api/en/helpers/RectAreaLightHelper.html b/docs/examples/en/helpers/RectAreaLightHelper.html similarity index 79% rename from docs/api/en/helpers/RectAreaLightHelper.html rename to docs/examples/en/helpers/RectAreaLightHelper.html index 39e77e8bad3949..3c9f15d6f2af70 100644 --- a/docs/api/en/helpers/RectAreaLightHelper.html +++ b/docs/examples/en/helpers/RectAreaLightHelper.html @@ -16,14 +16,12 @@

    [name]

    Creates a visual aid for a [page:RectAreaLight].

    -

    Example

    +

    Code Example

    -var light = new THREE.RectAreaLight( 0xffffbb, 1.0, 5, 5 ); - -var helper = new THREE.RectAreaLightHelper( light ); - -light.add( helper ); // helper must be added as a child of the light + var light = new THREE.RectAreaLight( 0xffffbb, 1.0, 5, 5 ); + var helper = new RectAreaLightHelper( light ); + light.add( helper ); // helper must be added as a child of the light @@ -62,6 +60,8 @@

    [method:null update]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/RectAreaLightHelper.js examples/jsm/helpers/RectAreaLightHelper.js] +

    diff --git a/docs/api/en/helpers/VertexNormalsHelper.html b/docs/examples/en/helpers/VertexNormalsHelper.html similarity index 84% rename from docs/api/en/helpers/VertexNormalsHelper.html rename to docs/examples/en/helpers/VertexNormalsHelper.html index 76c962abe50e65..834dddc41551a0 100644 --- a/docs/api/en/helpers/VertexNormalsHelper.html +++ b/docs/examples/en/helpers/VertexNormalsHelper.html @@ -20,21 +20,23 @@

    [name]

    Unlike [page:FaceNormalsHelper], this works with [page:BufferGeometry].

    -

    Example

    - - [example:webgl_helpers WebGL / helpers] +

    Code Example

    - var geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 ); + var geometry = new THREE.BoxBufferGeometry( 10, 10, 10, 2, 2, 2 ); var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); var box = new THREE.Mesh( geometry, material ); - var helper = new THREE.VertexNormalsHelper( box, 2, 0x00ff00, 1 ); + var helper = new VertexNormalsHelper( box, 2, 0x00ff00, 1 ); scene.add( box ); scene.add( helper ); +

    Examples

    +

    + [example:webgl_helpers WebGL / helpers] +

    Constructor

    @@ -74,6 +76,8 @@

    [method:null update]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/VertexNormalsHelper.js examples/jsm/helpers/VertexNormalsHelper.js] +

    diff --git a/docs/examples/en/helpers/VertexTangentsHelper.html b/docs/examples/en/helpers/VertexTangentsHelper.html new file mode 100644 index 00000000000000..b63aa2b23fe36d --- /dev/null +++ b/docs/examples/en/helpers/VertexTangentsHelper.html @@ -0,0 +1,82 @@ + + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    + Renders arrows to visualize an object's vertex tangent vectors. + Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or + have been calculated using [page:BufferGeometryUtils.computeTangents computeTangents].

    + + This helper supports [page:BufferGeometry] only. +

    + +

    Code Example

    + + var geometry = new THREE.BoxBufferGeometry( 10, 10, 10, 2, 2, 2 ); + var material = new THREE.MeshNormalMaterial(); + var box = new THREE.Mesh( geometry, material ); + + var helper = new VertexTangentsHelper( box, 1, 0x00ffff, 1 ); + + scene.add( box ); + scene.add( helper ); + + +

    Examples

    +

    + [example:webgl_helpers WebGL / helpers] +

    + +

    Constructor

    + + +

    [name]( [param:Object3D object], [param:Number size], [param:Hex color], [param:Number linewidth] )

    +

    + [page:Object3D object] -- object for which to render vertex tangents.
    + [page:Number size] -- (optional) length of the arrows. Default is *1*.
    + [page:Hex color] -- hex color of the arrows. Default is 0x00ffff.
    + [page:Number linewidth] -- (optional) width of the arrow lines. Default is *1*. (Setting lineWidth is currently not supported.) +

    + + +

    Properties

    +

    See the base [page:LineSegments] class for common properties.

    + +

    [property:object matrixAutoUpdate]

    +

    + See [page:Object3D.matrixAutoUpdate]. Set to *false* here as the helper is using the + objects's [page:Object3D.matrixWorld matrixWorld]. +

    + +

    [property:Object3D object]

    +

    The object for which the vertex tangents are being visualized.

    + +

    [property:Number size]

    +

    Length of the arrows. Default is *1*.

    + + +

    Methods

    +

    See the base [page:LineSegments] class for common methods.

    + + +

    [method:null update]()

    +

    Updates the vertex tangents preview based on the object's world transform.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/VertexTangentsHelper.js examples/jsm/helpers/VertexTangentsHelper.js] +

    + + diff --git a/docs/examples/en/loaders/BabylonLoader.html b/docs/examples/en/loaders/BabylonLoader.html deleted file mode 100644 index a023ad0bc35968..00000000000000 --- a/docs/examples/en/loaders/BabylonLoader.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - -

    [name]

    - -

    A loader for loading a .babylon resource.
    - The .babylon file format used by - Babylon.js. -

    - -

    Example

    - - - // instantiate a loader - var loader = new THREE.BabylonLoader(); - - // load a Babylon resource - loader.load( - // resource URL - 'models/babylon/skull.babylon', - // called when resource is loaded - function ( object ) { - - scene.add( object ); - - }, - // called when loading is in progress - function ( xhr ) { - - console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' ); - - }, - // called when loading has errors - function ( xhr ) { - - console.log( 'An error happened' ); - - } - ); - - - [example:webgl_loader_babylon] - -

    Constructor

    - -

    [name]( [param:LoadingManager manager] )

    -

    - [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager]. -

    -

    - Creates a new [name]. -

    - -

    Properties

    - - -

    Methods

    - -

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    -

    - [page:String url] — A string containing the path/URL of the .babylon file.
    - [page:function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.
    - [page:function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.
    - [page:function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.
    -

    -

    - Begin loading from url and call onLoad with the parsed response content. -

    - -

    [method:Object3D parse]( [param:Object json] )

    -

    - [page:Object json] — The JSON structure to parse. -

    -

    - Parse a JSON structure and return an [page:Object3D object] or a [page:Scene scene].
    - Found objects are converted to [page:Mesh] with a [page:BufferGeometry] and a default [page:MeshPhongMaterial].
    - Lights are parsed accordingly. -

    - -

    [method:BabylonLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    - -

    Source

    - - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/BabylonLoader.js examples/js/loaders/BabylonLoader.js] - - diff --git a/docs/examples/en/loaders/BasisTextureLoader.html b/docs/examples/en/loaders/BasisTextureLoader.html index 433ca3b2c14674..d0f013a538911d 100644 --- a/docs/examples/en/loaders/BasisTextureLoader.html +++ b/docs/examples/en/loaders/BasisTextureLoader.html @@ -9,6 +9,7 @@ [page:Loader] → +

    [name]

    @@ -24,15 +25,15 @@

    [name]

    This loader parallelizes the transcoding process across a configurable number of web workers, before transferring the transcoded compressed texture back to the main thread. The required WASM transcoder and JS wrapper are available from the - [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/basis examples/js/libs/basis] + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/basis examples/jsm/libs/basis] directory.

    -

    Example

    +

    Code Example

    - var basisLoader = new THREE.BasisTextureLoader(); - basisLoader.setTranscoderPath( 'examples/js/libs/basis/' ); + var basisLoader = new BasisTextureLoader(); + basisLoader.setTranscoderPath( 'examples/jsm/libs/basis/' ); basisLoader.detectSupport( renderer ); basisLoader.load( 'diffuse.basis', function ( texture ) { @@ -49,7 +50,11 @@

    Example

    } );
    - [example:webgl_loader_texture_basis] +

    Examples

    + +

    + [example:webgl_loader_texture_basis] +

    Browser compatibility

    @@ -57,8 +62,8 @@

    Browser compatibility

    BasisTextureLoader transcodes input textures in '.basis' format to an appropriate compressed texture format for the target device, where possible. This allows the same source texture to be served across - desktop, Android, and iOS devices, and transcoded into DXT, ETC1, or - PVRTC1. Other output formats may be supported in the future. + desktop, Android, and iOS devices, and transcoded into ASTC, DXT, ETC1, + or PVRTC1. Other output formats may be supported in the future.

    Transcoding to PVRTC1 (for iOS) requires square power-of-two textures. @@ -81,7 +86,11 @@

    [name]( [param:LoadingManager manager] )

    Creates a new [name].

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    +

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -103,21 +112,13 @@

    [method:this detectSupport]( [param:WebGLRenderer renderer] )

    the output format for the transcoder. Must be called before loading a texture.

    -

    [method:this setCrossOrigin]( [param:String crossOrigin] )

    -

    - [page:String crossOrigin] — Options are '', 'anonymous', or 'use-credentials'. Default is 'anonymous'. -

    -

    - Sets options for CORS requests. -

    -

    [method:this setTranscoderPath]( [param:String path] )

    [page:String path] — Path to folder containing the WASM transcoder and JS wrapper.

    The WASM transcoder and JS wrapper are available from the - [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/basis examples/js/libs/basis] + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/basis examples/jsm/libs/basis] directory.

    @@ -136,6 +137,8 @@

    [method:this dispose]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/BasisTextureLoader.js examples/js/loaders/BasisTextureLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/BasisTextureLoader.js examples/jsm/loaders/BasisTextureLoader.js] +

    diff --git a/docs/examples/en/loaders/DRACOLoader.html b/docs/examples/en/loaders/DRACOLoader.html index a1ff9af73f94dd..d2faa710476526 100644 --- a/docs/examples/en/loaders/DRACOLoader.html +++ b/docs/examples/en/loaders/DRACOLoader.html @@ -27,17 +27,17 @@

    [name]

    using Draco with glTF, an instance of DRACOLoader will be used internally by [page:GLTFLoader].

    -

    Example

    +

    Code Example

    // Instantiate a loader - var loader = new THREE.DRACOLoader(); + var loader = new DRACOLoader(); // Specify path to a folder containing WASM/JS decoding libraries. - THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' ); + loader.setDecoderPath( '/examples/jsm/libs/draco/' ); // Optional: Pre-fetch Draco WASM/JS module. - THREE.DRACOLoader.getDecoderModule(); + loader.preload(); // Load a Draco geometry loader.load( @@ -66,7 +66,11 @@

    Example

    );
    - [example:webgl_loader_draco] +

    Examples

    + +

    + [example:webgl_loader_draco] +

    Browser compatibility

    @@ -90,56 +94,62 @@

    [name]( [param:LoadingManager manager] )

    Creates a new [name].

    -

    Static Methods

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    -

    [method:null setDecoderPath]( [param:String value] )

    -

    - [page:String value] — Path to folder containing the JS and WASM decoder libraries. -

    +

    Methods

    +

    See the base [page:Loader] class for common methods.

    -

    [method:null setDecoderConfig]( [param:Object config] )

    +

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    - [page:String config.type] - (Optional) "js" or "wasm".
    + [page:String url] — A string containing the path/URL of the .drc file.
    + [page:Function onLoad] — A function to be called after the loading is successfully completed.
    + [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    + [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.

    - Provides configuration for the decoder libraries. Configuration cannot be changed - after loading the decoders. + Begin loading from url and call the onLoad function with the decompressed geometry.

    -

    [method:Promise getDecoderModule]()

    +

    [method:this setDecoderPath]( [param:String value] )

    - Requests the decoder libraries, if not already loaded. + [page:String value] — Path to folder containing the JS and WASM decoder libraries.

    -

    [method:null releaseDecoderModule]()

    +

    [method:this setDecoderConfig]( [param:Object config] )

    - Disposes of the decoder library and deallocates memory. The decoder - [link:https://github.com/google/draco/issues/349 cannot be reloaded afterward]. + [page:String config.type] - (Optional) "js" or "wasm".
    +

    +

    + Provides configuration for the decoder libraries. Configuration cannot be changed + after decoding begins.

    -

    Methods

    - -

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    [method:this setWorkerLimit]( [param:Number workerLimit] )

    - [page:String url] — A string containing the path/URL of the .drc file.
    - [page:Function onLoad] — A function to be called after the loading is successfully completed.
    - [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    - [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    + [page:Number workerLimit] - Maximum number of workers to be allocated. Default is 4.

    - Begin loading from url and call the onLoad function with the decompressed geometry. + Sets the maximum number of [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers Web Workers] + to be used during decoding. A lower limit may be preferable if workers are also for other tasks + in the application.

    -

    [method:DRACOLoader setPath]( [param:String path] )

    +

    [method:this preload]()

    - [page:String path] — Base path. + Requests the decoder libraries, if not already loaded.

    + +

    [method:this dispose]()

    - Set the base path for the .drc file. + Disposes of the decoder resources and deallocates memory. The decoder + [link:https://github.com/google/draco/issues/349 cannot be reloaded afterward].

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/DRACOLoader.js examples/js/loaders/DRACOLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/DRACOLoader.js examples/jsm/loaders/DRACOLoader.js] +

    diff --git a/docs/examples/en/loaders/GLTFLoader.html b/docs/examples/en/loaders/GLTFLoader.html index f0251f461d8f69..a581f0a499783c 100644 --- a/docs/examples/en/loaders/GLTFLoader.html +++ b/docs/examples/en/loaders/GLTFLoader.html @@ -9,6 +9,7 @@ [page:Loader] → +

    [name]

    A loader for glTF 2.0 resources.

    @@ -31,6 +32,7 @@

    Extensions

  • KHR_draco_mesh_compression
  • KHR_materials_pbrSpecularGlossiness
  • KHR_materials_unlit
  • +
  • KHR_mesh_quantization
  • KHR_lights_punctual1
  • KHR_texture_transform2
  • MSFT_texture_dds
  • @@ -49,18 +51,16 @@

    Extensions

    #[link:https://github.com/mrdoob/three.js/issues/12788 12788].

    -

    Example

    +

    Code Example

    // Instantiate a loader - var loader = new THREE.GLTFLoader(); + var loader = new GLTFLoader(); // Optional: Provide a DRACOLoader instance to decode compressed mesh data - THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' ); - loader.setDRACOLoader( new THREE.DRACOLoader() ); - - // Optional: Pre-fetch Draco WASM/JS module, to save time while parsing. - THREE.DRACOLoader.getDecoderModule(); + var dracoLoader = new DRACOLoader(); + dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' ); + loader.setDRACOLoader( dracoLoader ); // Load a glTF resource loader.load( @@ -72,8 +72,8 @@

    Example

    scene.add( gltf.scene ); gltf.animations; // Array<THREE.AnimationClip> - gltf.scene; // THREE.Scene - gltf.scenes; // Array<THREE.Scene> + gltf.scene; // THREE.Group + gltf.scenes; // Array<THREE.Group> gltf.cameras; // Array<THREE.Camera> gltf.asset; // Object @@ -93,7 +93,11 @@

    Example

    );
    - [example:webgl_loader_gltf] +

    Examples

    + +

    + [example:webgl_loader_gltf] +

    Browser compatibility

    @@ -111,8 +115,7 @@

    Textures

    in linear colorspace, always configure [page:WebGLRenderer] as follows when using glTF:

    - renderer.gammaOutput = true; - renderer.gammaFactor = 2.2; + renderer.outputEncoding = THREE.sRGBEncoding;

    GLTFLoader will automatically configure textures referenced from a .gltf or .glb file correctly, with the @@ -163,9 +166,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -178,33 +182,12 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and call the callback function with the parsed response content.

    -

    [method:GLTFLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the .gltf/.glb file. -

    - -

    [method:GLTFLoader setResourcePath]( [param:String path] )

    -

    - [page:String path] — Base path for loading additional resources e.g. textures and .bin data. -

    -

    - Set the base path for additional resources. -

    - -

    [method:null setCrossOrigin]( [param:String value] )

    -

    - [page:String value] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. -

    -

    [method:null setDRACOLoader]( [param:DRACOLoader dracoLoader] )

    [page:DRACOLoader dracoLoader] — Instance of THREE.DRACOLoader, to be used for decoding assets compressed with the KHR_draco_mesh_compression extension.

    - Refer to this [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/draco#readme readme] for the details of Draco and its decoder. + Refer to this [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/draco#readme readme] for the details of Draco and its decoder.

    [method:null setDDSLoader]( [param:DDSLoader ddsLoader] )

    @@ -220,11 +203,13 @@

    [method:null parse]( [param:ArrayBuffer data], [param:String path], [param:F [page:Function onError] — (optional) A function to be called if an error occurs during parsing. The function receives error as an argument.

    - Parse a glTF-based ArrayBuffer or JSON String and fire [page:Function onLoad] callback when complete. The argument to [page:Function onLoad] will be an [page:object] that contains loaded parts: .[page:Scene scene], .[page:Array scenes], .[page:Array cameras], .[page:Array animations], and .[page:Object asset]. + Parse a glTF-based ArrayBuffer or JSON String and fire [page:Function onLoad] callback when complete. The argument to [page:Function onLoad] will be an [page:object] that contains loaded parts: .[page:Group scene], .[page:Array scenes], .[page:Array cameras], .[page:Array animations], and .[page:Object asset].

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/GLTFLoader.js examples/js/loaders/GLTFLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/GLTFLoader.js examples/jsm/loaders/GLTFLoader.js] +

    diff --git a/docs/examples/en/loaders/LoaderSupport.html b/docs/examples/en/loaders/LoaderSupport.html deleted file mode 100644 index 3624ef036816e1..00000000000000 --- a/docs/examples/en/loaders/LoaderSupport.html +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - -

    [name]

    - -

    Supporting classes for file loaders and web worker based loaders.

    - -

    Sub-Classes

    - [page:LoaderSupport.Builder]
    - [page:LoaderSupport.LoadedMeshUserOverride]
    - [page:LoaderSupport.WorkerSupport]
    - [page:LoaderSupport.WorkerRunnerRefImpl]
    - [page:LoaderSupport.WorkerDirector]
    - [page:LoaderSupport.ResourceDescriptor]
    - [page:LoaderSupport.PrepData]
    - [page:LoaderSupport.Callbacks]
    - [page:LoaderSupport.Validator]
    - - -

    Example

    - - [example:webgl_loader_obj2_meshspray] - Example using [page:LoaderSupport.LoaderWorkerDirector] and [page:LoaderSupport.LoaderWorkerSupport].
    - -

    Classes

    -
    - -

    Builder

    -

    Constructor

    - -

    Builder()

    -

    - Builds one or many [page:Mesh] from one raw set of Arraybuffers, materialGroup descriptions and further parameters. - Supports vertex, vertexColor, normal, uv and index buffers. -

    - - -

    Methods

    - -

    [method:null setLogging] ( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:null init] ()

    -

    - Initializes the Builder (currently only default material initialisation). -

    - - -

    [method:null setMaterials] ( Array of [param:Material materials] )

    -

    - Array of [page:Material materials] - Array of [page:Material Materials] -

    -

    - Set materials loaded by any supplier of an Array of [page:Material Materials]. -

    - - -

    [method:Array processPayload] ( Object payload )

    -

    - [page:Object payload] - Raw Mesh or Material descriptions. -

    -

    - Delegates processing of the payload (mesh building or material update) to the corresponding functions (BW-compatibility). -

    - - -

    [method:Array buildMeshes] ( Object meshPayload )

    -

    - [page:Object meshPayload] - Raw mesh description (buffers, params, materials) used to build one to many meshes. -

    -

    - Builds one or multiple meshes from the data described in the payload (buffers, params, material info). -

    - - -

    [method:null updateMaterials] ( Object materialPayload )

    -

    - [page:Object materialPayload] - Material update instructions -

    -

    - Updates the materials with contained material objects (sync) or from alteration instructions (async). -

    - - -

    [method:Object getMaterialsJSON] ()

    -

    - Returns the mapping object of material name and corresponding jsonified material. -

    - - -

    [method:Object getMaterials] ()

    -

    - Returns the mapping object of material name and corresponding material. -

    -
    -
    - - -

    LoadedMeshUserOverride

    -

    Constructor

    - -

    LoadedMeshUserOverride( [param:Boolean disregardMesh], [param:BufferGeometry bufferGeometry] )

    -

    - [page:Boolean disregardMesh] - Tell implementation to completely disregard this mesh
    - [page:Boolean alteredMesh] - Tell implementation that mesh(es) have been altered or added -

    -

    - Object to return by callback onMeshAlter. Used to disregard a certain mesh or to return one to many meshes. -

    - - -

    Methods

    - -

    [method:null addMesh] ( [param:Mesh mesh] )

    -

    - [page:Mesh mesh] - Mesh -

    -

    - Add a mesh created within callback. -

    - - -

    [method:boolean isDisregardMesh] ()

    -

    - Answers if mesh shall be disregarded completely. -

    - - -

    [method:boolean providesAlteredMeshes] ()

    -

    - Answers if new mesh(es) were created. -

    -
    -
    - - -

    WorkerSupport

    -

    Constructor

    - -

    WorkerSupport()

    -

    - This class provides means to transform existing parser code into a web worker. - It defines a simple communication protocol which allows to configure the worker and receive raw mesh data during execution. -

    - - -

    Methods

    - -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:null setForceWorkerDataCopy]( [param:Boolean forceWorkerDataCopy] )

    -

    - [page:Boolean forceWorkerDataCopy] True or false. -

    -

    - Forces all ArrayBuffers to be transferred to worker to be copied. -

    - - -

    [method:null validate] ( [param:Function functionCodeBuilder], Array of [param:String libLocations], [param:String libPath], [param:LoaderSupport.WorkerRunnerRefImpl runnerImpl] )

    -

    - [page:Function functionCodeBuilder] - Function that is invoked with funcBuildObject and funcBuildSingleton that allows stringification of objects and singletons.
    - Array of [page:String libLocations] - URL of libraries that shall be added to worker code relative to libPath.
    - [page:String libPath] - Base path used for loading libraries.
    - [page:LoaderSupport.WorkerRunnerRefImpl runnerImpl] - The default worker parser wrapper implementation (communication and execution). An extended class could be passed here. -

    -

    - Validate the status of worker code and the derived worker. -

    - - -

    [method:null setTerminateRequested] ( [param:Boolean terminateRequested] )

    -

    - [page:Boolean terminateRequested] - True or false. -

    -

    - Request termination of worker once parser is finished. -

    - - -

    [method:null setCallbacks] ( [param:Function builder], [param:Function onLoad] )

    -

    - [page:Function builder] - The builder function. Default is [page:LoaderSupport.Builder].
    - [page:Function onLoad] - The function that is called when parsing is complete. -

    -

    - Specify functions that should be build when new raw mesh data becomes available and when the parser is finished. -

    - - -

    [method:null run] ( [param:Object payload] )

    -

    - [page:Object payload] - Raw mesh description (buffers, params, materials) used to build one to many meshes. -

    -

    - Runs the parser with the provided configuration. -

    -
    -
    - - -

    WorkerRunnerRefImpl

    -

    Constructor

    - -

    WorkerRunnerRefImpl()

    -

    - Default implementation of the WorkerRunner responsible for creation and configuration of the parser within the worker. -

    - - -

    Methods

    - -

    [method:null applyProperties] ( [param:Object parser], [param:Object params] )

    -

    - [page:Object parser] - The parser instance
    - [page:Object params] - The parameter object -

    -

    - Applies values from parameter object via set functions or via direct assignment. -

    - - -

    [method:null run] ( [param:Object payload] )

    -

    - [page:Object payload] - Raw mesh description (buffers, params, materials) used to build one to many meshes. -

    -

    - Configures the Parser implementation according the supplied configuration object. -

    -
    -
    - - -

    WorkerDirector

    -

    Constructor

    - -

    WorkerDirector( [param:String classDef] )

    -

    - [page:String classDef] - Class definition to be used for construction -

    -

    - Orchestrate loading of multiple OBJ files/data from an instruction queue with a configurable amount of workers (1-16).
    - - Workflow:
    - - prepareWorkers
    - - enqueueForRun
    - - processQueue
    - - tearDown -

    - - -

    Methods

    - -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:null setForceWorkerDataCopy]( [param:Boolean forceWorkerDataCopy] )

    -

    - [page:Boolean forceWorkerDataCopy] True or false. -

    -

    - Forces all ArrayBuffers to be transferred to worker to be copied. -

    - - -

    [method:null prepareWorkers]( [param:WWOBJLoader2.Callbacks globalCallbacks], [param:Number maxQueueSize], [param:Number maxWebWorkers] )

    -

    - [page:LoaderSupport.Callbacks globalCallbacks] - Register global callbacks used by all web workers
    - [page:Number maxQueueSize] - Set the maximum size of the instruction queue (1-1024)
    - [page:Number maxWebWorkers] - Set the maximum amount of workers (1-16) -

    -

    - Create or destroy workers according limits. Set the name and register callbacks for dynamically created web workers. -

    - - -

    [method:null enqueueForRun]( [param:LoaderSupport.PrepData runParams] )

    -

    - [page:LoaderSupport.PrepData runParams] -

    -

    - Store run instructions in internal instructionQueue. -

    - - -

    [method:null processQueue]()

    -

    - Process the instructionQueue until it is depleted. -

    - - -

    [method:null tearDown]( [param:Function callbackOnFinishedProcessing] )

    -

    - [page:Function callbackOnFinishedProcessing] - Function called once all workers finished processing. -

    -

    - Terminate all workers. -

    - - -

    [method:null getMaxQueueSize]()

    -

    - Returns the maximum length of the instruction queue. -

    - - -

    [method:null getMaxWebWorkers]()

    -

    - Returns the maximum number of workers. -

    - -

    [method:Boolean isRunning]()

    -

    - Returns if any workers are running. -

    - - -

    [method:null setCrossOrigin]( [param:String crossOrigin] )

    -

    - [page:String crossOrigin] - CORS value -

    -

    - Sets the CORS string to be used. -

    -
    -
    - - -

    ResourceDescriptor

    -

    Constructor

    - -

    ResourceDescriptor( [param:String url], [param:String extension] )

    -

    - [page:String url] - URL to the file
    - [page:String extension] - The file extension (type) -

    -

    - A resource description used by [page:LoaderSupport.PrepData] and others. -

    - -

    Methods

    - -

    [method:null setContent]( [param:Object content )

    -

    - [page:Object content] - The file content as ArrayBuffer or text -

    -

    - Set the content of this resource -

    - - -

    [method:null setResourcePath] ( [param:String resourcePath] )

    -

    - [page:String resourcePath] - URL -

    -

    - Allows to specify resourcePath for dependencies of specified resource. -

    -
    -
    - - -

    PrepData

    -

    Constructor

    - -

    PrepData( [param:String modelName] )

    -

    - [page:String modelName] - Overall name of the model -

    -

    - Configuration instructions to be used by run method. -

    - - -

    Methods

    - -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:Callbacks getCallbacks]()

    -

    - Returns all callbacks as [page:LoaderSupport.Callbacks]. -

    - - -

    [method:null addResource]( [param:LoaderSupport.ResourceDescriptor resource] )

    -

    - [page:LoaderSupport.ResourceDescriptor resource] Adds a [page:LoaderSupport.ResourceDescriptor] -

    -

    - Add a resource description. -

    - - -

    [method:null checkResourceDescriptorFiles] ( [param:LoaderSupport.ResourceDescriptor resources], [param:Object fileDesc] )

    -

    - [page:LoaderSupport.ResourceDescriptor resources] - Array of [page:LoaderSupport.ResourceDescriptor]
    - [page:Object fileDesc] - Object describing which resources are of interest (ext, type (string or UInt8Array) and ignore (boolean)) -

    -

    - Identify files or content of interest from an Array of [page:LoaderSupport.ResourceDescriptor]. - Returns Object with each "ext" and the corresponding [page:LoaderSupport.ResourceDescriptor] -

    - - -

    [method:PrepData clone] ()

    -

    - Clones this object and returns it afterwards. Callbacks and resources are not cloned deep (references!). -

    -
    -
    - - -

    Callbacks

    -

    Constructor

    - -

    Callbacks()

    -

    - Callbacks utilized by loaders and builder. -

    - - -

    Methods

    - -

    [method:null setCallbackOnProgress]( [param:Function callbackOnProgress] )

    -

    - [page:Function callbackOnProgress] - Callback function for described functionality -

    -

    - Register callback function that is invoked by internal function "announceProgress" to print feedback. -

    - -

    [method:null setCallbackOnReportError]( [param:Function callbackOnReportError] )

    -

    - [page:Function callbackOnReportError] - Callback function for described functionality -

    -

    - Register callback function that is invoked when an error is reported. -

    - -

    [method:null setCallbackOnMeshAlter]( [param:Function callbackOnMeshAlter] )

    -

    - [page:Function callbackOnMeshAlter] - Callback function for described functionality -

    -

    - Register callback function that is called every time a mesh was loaded. - Use [page:LoadedMeshUserOverride] for alteration instructions (geometry, material or disregard mesh). -

    - - -

    [method:null setCallbackOnLoad]( [param:Function callbackOnLoad] )

    -

    - [page:Function callbackOnLoad] - Callback function for described functionality -

    -

    - Register callback function that is called once loading of the complete OBJ file is completed. -

    - -

    [method:null setCallbackOnLoadMaterials]( [param:Function callbackOnLoadMaterials] )

    -

    - [page:Function callbackOnLoadMaterials] - Callback function for described functionality -

    -

    - Register callback function that is called when materials have been loaded. -

    -
    -
    - - -

    Validator

    -

    Constructor

    - -

    Validator()

    -

    - Validation functions. -

    - - -

    Methods

    - -

    [method:Boolean isValid]( [param:Object input] )

    -

    - [page:Object input] - Can be anything -

    -

    - If given input is null or undefined, false is returned otherwise true. -

    - - -

    [method:null verifyInput]( [param:Object input], [param:Object defaultValue] )

    -

    - [page:Object input] - Can be anything
    - [page:Object defaultValue] - Can be anything -

    -

    - If given input is null or undefined, the defaultValue is returned otherwise the given input. -

    -
    -
    - -

    Source

    - - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/LoaderSupport.js examples/js/loaders/LoaderSupport.js] - - - diff --git a/docs/examples/en/loaders/MMDLoader.html b/docs/examples/en/loaders/MMDLoader.html index 3287ec82207a68..8d2ae7c19d4915 100644 --- a/docs/examples/en/loaders/MMDLoader.html +++ b/docs/examples/en/loaders/MMDLoader.html @@ -9,6 +9,7 @@ [page:Loader] → +

    [name]

    A loader for MMD resources.

    @@ -17,11 +18,11 @@

    [name]

    If you want raw content of MMD resources, use .loadPMD/PMX/VMD/VPD methods. -

    Example

    +

    Code Example

    // Instantiate a loader - var loader = new THREE.MMDLoader(); + var loader = new MMDLoader(); // Load a MMD model loader.load( @@ -48,12 +49,12 @@

    Example

    );
    +

    Examples

    +

    [example:webgl_loader_mmd]
    [example:webgl_loader_mmd_pose]
    - [example:webgl_loader_mmd_audio]
    - -
    -


    + [example:webgl_loader_mmd_audio] +

    Constructor

    @@ -66,9 +67,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -84,7 +86,7 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func

    [method:null loadAnimation]( [param:String url], [param:Object3D object], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    [page:String url] — A string or an array of string containing the path/URL of the .vmd file(s).If two or more files are specified, they'll be merged.
    - [page:Object3D object] — [page:SkinnedMesh] or [page:Camera]. Clip and its tacks will be fitting to this object.
    + [page:Object3D object] — [page:SkinnedMesh] or [page:Camera]. Clip and its tracks will be fitting to this object.
    [page:Function onLoad] — A function to be called after the loading is successfully completed.
    [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    @@ -105,11 +107,6 @@

    [method:null loadWithAnimation]( [param:String modelUrl], [param:String vmdU Begin loading PMD/PMX model file and VMD motion file(s) from urls and fire the callback function with an [page:Object] containing parsed [page:SkinnedMesh] and [page:AnimationClip] fitting to the [page:SkinnedMesh].

    -

    [method:MMDLoader setCrossOrigin]( [param:String crossOrigin] )

    -

    - [page:String crossOrigin] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. -

    -

    [method:MMDLoader setAnimationPath]( [param:String animationPath] )

    [page:String animationPath] — Base path for loading animation data (VMD/VPD files). @@ -118,24 +115,10 @@

    [method:MMDLoader setAnimationPath]( [param:String animationPath] )

    Set the base path for additional resources like textures.

    -

    [method:MMDLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Sets the base path or URL from which to load files. -

    +

    Source

    -

    [method:MMDLoader setResourcePath]( [param:String resourcePath] )

    - [page:String resourcePath] — Base path for loading additional resources e.g. textures. + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/MMDLoader.js examples/jsm/loaders/MMDLoader.js]

    -

    - Set the base path for additional resources like textures. -

    - -

    Source

    - - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/MMDLoader.js examples/js/loaders/MMDLoader.js] diff --git a/docs/examples/en/loaders/MTLLoader.html b/docs/examples/en/loaders/MTLLoader.html index 82111f6da165e9..72c683ff406339 100644 --- a/docs/examples/en/loaders/MTLLoader.html +++ b/docs/examples/en/loaders/MTLLoader.html @@ -8,10 +8,11 @@ + [page:Loader] →

    [name]

    -

    A loader for loading an .mtl resource, used internaly by [page:OBJLoader].
    +

    A loader for loading an .mtl resource, used internally by [page:OBJLoader].
    The Material Template Library format (MTL) or .MTL File Format is a companion file format to .OBJ that describes surface shading (material) properties of objects within one or more .OBJ files.

    @@ -27,10 +28,10 @@

    [name]( [param:LoadingManager loadingManager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    - +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -43,35 +44,6 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and return the loaded material.

    - -

    [method:MTLLoader setPath]( [param:String path] )

    -

    - [page:String path] — required
    -

    -

    - Set base path for MTL file. -

    - - -

    [method:MTLLoader setResourcePath]( [param:String path] )

    -

    - [page:String path] — required
    -

    -

    - Set base path for additional resources like textures. If set, this path will be used as the base path. -

    - - -

    [method:MTLLoader setCrossOrigin]( [param:String value] )

    -

    - [page:String value] — required
    -

    -

    - If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*. -

    - -

    [method:MTLLoader setMaterialOptions]( [param:Object options] )

    [page:Object options] — required @@ -100,6 +72,8 @@

    [method:MTLLoaderMaterialCreator parse]( [param:String text, param:String pa

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/[name].js examples/js/loaders/[name].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/[name].js examples/jsm/loaders/[name].js] +

    diff --git a/docs/examples/en/loaders/OBJLoader.html b/docs/examples/en/loaders/OBJLoader.html index 1cf6b610beb97e..89408171d48b21 100644 --- a/docs/examples/en/loaders/OBJLoader.html +++ b/docs/examples/en/loaders/OBJLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -18,12 +19,11 @@

    [name]

    vertices, and texture vertices.

    - -

    Example

    +

    Code Example

    // instantiate a loader - var loader = new THREE.OBJLoader(); + var loader = new OBJLoader(); // load a resource loader.load( @@ -50,8 +50,10 @@

    Example

    );
    - [example:webgl_loader_obj] - +

    Examples

    +

    + [example:webgl_loader_obj] +

    Constructor

    @@ -64,9 +66,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -97,13 +100,10 @@

    [method:OBJLoader setMaterials]( [param:MTLLoader.MaterialCreator materials] Sets materials loaded by MTLLoader or any other supplier of a [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator].

    -

    [method:OBJLoader setPath]( [param:String path] )

    -

    - Sets the base path or URL from which to load files. This can be useful to avoid repetition if you are calling [page:OBJLoader.load .load] multiple times on the same directory. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js examples/js/loaders/OBJLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/OBJLoader.js examples/jsm/loaders/OBJLoader.js] +

    diff --git a/docs/examples/en/loaders/OBJLoader2.html b/docs/examples/en/loaders/OBJLoader2.html index 316aaab077d70c..1bf7c8e2b94835 100644 --- a/docs/examples/en/loaders/OBJLoader2.html +++ b/docs/examples/en/loaders/OBJLoader2.html @@ -18,193 +18,190 @@

    [name]

    vertices, and texture vertices.

    -

    Examples

    +

    Code Example

    // instantiate the loader - var loader = new THREE.OBJLoader2(); + let loader = new OBJLoader2(); // function called on successful load - var callbackOnLoad = function ( event ) { - scene.add( event.detail.loaderRootNode ); - }; + function callbackOnLoad ( object3d ) { + scene.add( object3d ); + } // load a resource from provided URL synchronously - loader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null, false ); + loader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null ); - [example:webgl_loader_obj2] - Simple example
    - [example:webgl_loader_obj2_options] - Example for multiple use-cases (parse, load and run with instructions (sync and async)
    - [example:webgl_loader_obj2_run_director] - Advanced example using [page:LoaderSupport.LoaderWorkerDirector] for orchestration of multiple workers. - +

    Examples

    +

    + [example:webgl_loader_obj2] - Simple example
    + [example:webgl_loader_obj2_options] - Example for multiple use-cases (parse and load, sync or in parallel to main (see [page:OBJLoader2Parallel])) +

    Constructor

    -

    [name]( [param:LoadingManager manager], [param:LoaderSupport.ConsoleLogger logger] )

    +

    [name]( [param:LoadingManager manager] )

    [page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
    - [page:LoaderSupport.ConsoleLogger logger] - logger to be used

    - Use [name] to load OBJ data from files or to parse OBJ data from arraybuffer or text. + Creates a new [name]. Use it to load OBJ data from files or to parse OBJ data from arraybuffer or text.

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    + +

    Methods

    +

    See the base [page:Loader] class for common methods.

    +

    [method:Object3D parse]( [param:arraybuffer content]|[param:String content] )

    [[page:arraybuffer content]|[page:String content]] OBJ data as Uint8Array or String

    - Parses OBJ data synchronously from arraybuffer or string and returns the [page:Object3D loaderRoorNode]. + Parses OBJ data synchronously from arraybuffer or string and returns the [page:Object3D baseObject3d].

    -

    [method:Object3D parseAsync]( [param:arraybuffer content], [param:Function onLoad] )

    -

    - [page:arraybuffer content] - OBJ data as Uint8Array
    - [page:Function onLoad] - Called after worker successfully completed loading
    -

    -

    - Parses OBJ content asynchronously from arraybuffer. -

    - - -

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError], [param:Function onMeshAlter], [param:boolean useAsync] )

    +

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError], [param:Function onMeshAlter] )

    [page:String url] - A string containing the path/URL of the file to be loaded.
    [page:Function onLoad] - A function to be called after loading is successfully completed. The function receives loaded [page:Object3D] as an argument.
    [page:Function onProgress] - (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.
    [page:Function onError] - (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.
    [page:Function onMeshAlter] - (optional) A function to be called after a new mesh raw data becomes available for alteration.
    - [page:boolean useAsync] - (optional) If true, uses async loading with worker, if false loads data synchronously.

    Use this convenient method to load a file at the given URL. By default the fileLoader uses an ArrayBuffer.

    -

    [method:null run]( [param:LoaderSupport.PrepData params], [param:LoaderSupport.WorkerSupport workerSupportExternal] )

    +

    [method:OBJLoader2 setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    - [page:LoaderSupport.PrepData params] - prepData All parameters and resources required for execution
    - [page:LoaderSupport.WorkerSupport workerSupportExternal] - Use pre-existing WorkerSupport + [page:Boolean enabled] True or false.
    + [page:Boolean debug] True or false.

    - Run the loader according the provided instructions. + Enable or disable logging in general (except warn and error), plus enable or disable debug logging.

    -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    +

    [method:OBJLoader2 addMaterialPerSmoothingGroup] ( [param:boolean materialPerSmoothingGroup] )

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. + [page:boolean materialPerSmoothingGroup]

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. + Tells whether a material shall be created per smoothing group.

    -

    [method:null setModelName] ( [param:String modelName] )

    +

    [method:OBJLoader2 setUseOAsMesh] ( [param:boolean useOAsMesh] )

    - [page:String modelName] + [page:boolean useOAsMesh]

    - Set the name of the model. + Usually 'o' is meta-information and does not result in creation of new meshes, but mesh creation on occurrence of "o" can be enforced.

    -

    [method:null setPath] ( [param:String path] )

    +

    [method:OBJLoader2 setUseIndices]( [param:Boolean useIndices] )

    - [page:String path] - URL + [page:Boolean useIndices]

    - The URL of the base path. + Instructs loaders to create indexed [page:BufferGeometry].

    -

    [method:null setResourcePath] ( [param:String resourcePath] )

    +

    [method:OBJLoader2 setDisregardNormals]( [param:Boolean disregardNormals] )

    - [page:String resourcePath] - URL + [page:Boolean disregardNormals]

    - Allows to specify resourcePath for dependencies of specified resource. + Tells whether normals should be completely disregarded and regenerated.

    -

    [method:null setStreamMeshesTo] ( [param:Object3D streamMeshesTo] )

    +

    [method:OBJLoader2 setModelName] ( [param:String modelName] )

    +

    + [page:String modelName] +

    - [page:Object3D streamMeshesTo] - Object already attached to scenegraph where new meshes will be attached to + Set the name of the model. +

    + + +

    [method:OBJLoader2 setBaseObject3d] ( [param:Object3d baseObject3d] )

    +

    + [page:Object3D baseObject3d - Object already attached to scenegraph where new meshes will be attached to

    Set the node where the loaded objects will be attached directly.

    -

    [method:null setMaterials] ( Array of [param:Material materials] )

    +

    [method:OBJLoader2 setMaterials] ( [param:Object materials] )

    - Array of [page:Material materials] - Array of [page:Material Materials] + [page:Object materials] - materials Object with named [page:Material Materials]

    - Set materials loaded by MTLLoader or any other supplier of an Array of [page:Material Materials]. + Add materials as associated array.

    -

    [method:null setUseIndices]( [param:Boolean useIndices] )

    +

    [method:OBJLoader2 setCallbackOnLoad] ( [param:Function onLoad] )

    - [page:Boolean useIndices] + [page:Function onLoad]

    - Instructs loaders to create indexed [page:BufferGeometry]. + Register a function that is called when parsing was completed.

    -

    [method:null setDisregardNormals]( [param:Boolean disregardNormals] )

    +

    [method:OBJLoader2 setCallbackOnAssetAvailable] ( [param:Function onAssetAvailable] )

    - [page:Boolean disregardNormals] + [page:Function onAssetAvailable]

    - Tells whether normals should be completely disregarded and regenerated. + Register a function that is called once an asset (mesh/material) becomes available.

    -

    [method:null setMaterialPerSmoothingGroup] ( [param:boolean materialPerSmoothingGroup] )

    +

    [method:OBJLoader2 setCallbackOnProgress] ( [param:Function onProgress] )

    - [page:boolean materialPerSmoothingGroup] + [page:Function onProgress]

    - Tells whether a material shall be created per smoothing group. + Register a function that is used to report overall processing progress.

    -

    [method:null onProgress]( [param:String type], [param:String text], [param:Number numericalValue] )

    +

    [method:OBJLoader2 setCallbackOnError] ( [param:Function onError] )

    - [page:String type] - The type of event
    - [page:String text] - Textual description of the event
    - [page:Number numericalValue] - Numerical value describing the progress + [page:Function onError]

    - Announce feedback which is give to the registered [page:LoaderSupport.Callbacks]. + Register an error handler function that is called if errors occur. It can decide to just log or to throw an exception.

    -

    [method:null loadMtl]( [param:String url], [param:Object content], [param:Function callbackOnLoad], [param:String crossOrigin], [param:Object materialOptions])

    +

    [method:OBJLoader2 setCallbackOnMeshAlter] ( [param:Function onMeshAlter] )

    - [page:String url] - URL to the file
    - [page:Object content] - The file content as arraybuffer or text
    - [page:Function onLoad] - Callback to be called after successful load
    - [page:Function onProgress] - (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.
    - [page:Function onError] - (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.
    - [page:String crossOrigin] - (optional) CORS value
    - [page:Function materialOptions] - (optional) Set material loading options for MTLLoader + [page:Function onMeshAlter]

    - Utility method for loading an mtl file according resource description. Provide url or content. + Register a function that is called once a single mesh is available and it could be altered by the supplied function.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader2.js examples/js/loaders/OBJLoader2.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/OBJLoader2.js examples/jsm/loaders/OBJLoader2.js] +

    diff --git a/docs/examples/en/loaders/OBJLoader2Parallel.html b/docs/examples/en/loaders/OBJLoader2Parallel.html new file mode 100644 index 00000000000000..75f88bfb144f2e --- /dev/null +++ b/docs/examples/en/loaders/OBJLoader2Parallel.html @@ -0,0 +1,111 @@ + + + + + + + + + + + +

    [name]

    + +

    A loader for loading a .obj resource.
    + The OBJ file format is a simple data-format + that represents 3D geometry in a human readable format as, the position of each vertex, the UV position of + each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of + vertices, and texture vertices. +

    + +

    Code Example

    + + + // instantiate the loader + let objLoader2Parallel = new OBJLoader2Parallel(); + + // define where to attach the data + let local = new THREE.Object3D(); + + // function called on successful completion of parsing + function callbackOnLoad( object3d, message ) { + local.add( object3d ); + } + + // load a resource from provided URL in parallel to Main + objLoader2Parallel.load( 'models/obj/walt/WaltHead.obj', callbackOnLoad, null, null, null ); + + +

    Examples

    +

    + [example:webgl_loader_obj2_options] - Example for multiple use-cases (parse and load, sync (see [page:OBJLoader2]) or in parallel to main) +

    + +

    Constructor

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
    +

    +

    + Creates a new [name]. Use it to load OBJ data from files or to parse OBJ data from arraybuffer. + It extends [page:OBJLoader2] with the capability to run the parser in a web worker. +

    + + +

    Properties

    +

    See the base [page:OBJLoader2] class for common properties.

    + + +

    Methods

    +

    See the base [page:OBJLoader2] class for common methods.

    + + +

    [method:Object3D parse]

    +

    See [page:OBJLoader2.parse].
    + The callback [page:OBJLoader2.setCallbackOnLoad OBJLoader2.onLoad] needs to be set to be able to receive the content if used in parallel mode. + Fallback is possible via [page:OBJLoader2Parallel.setExecuteParallel]. +

    + + +

    [method:null load]

    +

    See [page:OBJLoader2.load].

    + + +

    [method:OBJLoader2Parallel setExecuteParallel] ( [param:boolean executeParallel] )

    +

    + [page:boolean executeParallel] - True or False +

    +

    + Execution of parse in parallel via Worker is default, but synchronous [page:OBJLoader2] parsing can be enforced via false here. +

    + + +

    [method:OBJLoader2Parallel setPreferJsmWorker] ( [param:boolean preferJsmWorker] )

    +

    + [page:boolean preferJsmWorker] - True or False +

    +

    + Set whether jsm modules in workers should be used. This requires browser support which is currently only experimental. +

    + + +

    [method:WorkerExecutionSupport getWorkerExecutionSupport] ()

    +

    + Allow to get hold of [page:WorkerExecutionSupport] for configuration purposes. +

    + + +

    [method:CodeBuilderInstructions buildWorkerCode] ()

    +

    + Provide instructions on what is to be contained in the worker. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/OBJLoader2Parallel.js examples/jsm/loaders/OBJLoader2Parallel.js] +

    + + diff --git a/docs/examples/en/loaders/PCDLoader.html b/docs/examples/en/loaders/PCDLoader.html index 31b11c46607d1a..dcb82090afadd0 100644 --- a/docs/examples/en/loaders/PCDLoader.html +++ b/docs/examples/en/loaders/PCDLoader.html @@ -8,20 +8,21 @@ + [page:Loader] →

    [name]

    A loader for loading a .pcd resource.
    Point Cloud Data is a file format for Point Cloud Library.
    - Loader support ascii and binary. Compressed binary files are not supported. + Loader support ascii and (compressed) binary.

    -

    Example

    +

    Code Example

    // instantiate a loader - var loader = new THREE.PCDLoader(); + var loader = new PCDLoader(); // load a resource loader.load( @@ -48,8 +49,10 @@

    Example

    );
    - [example:webgl_loader_pcd] - +

    Examples

    +

    + [example:webgl_loader_pcd] +

    Constructor

    @@ -62,6 +65,7 @@

    [name]( [param:LoadingManager manager] )

    Properties

    +

    See the base [page:Loader] class for common properties.

    [page:Boolean littleEndian]

    @@ -69,6 +73,7 @@

    [page:Boolean littleEndian]

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -93,16 +98,10 @@

    [method:Object3D parse]( [param:Arraybuffer data],[param:String url] )

    The object is converted to [page:Points] with a [page:BufferGeometry] and a [page:PointsMaterial].

    -

    [method:PCDLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PCDLoader.js examples/js/loaders/PCDLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PCDLoader.js examples/jsm/loaders/PCDLoader.js] +

    diff --git a/docs/examples/en/loaders/PDBLoader.html b/docs/examples/en/loaders/PDBLoader.html index 09c2cd9e6780ae..15ede81599290f 100644 --- a/docs/examples/en/loaders/PDBLoader.html +++ b/docs/examples/en/loaders/PDBLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -15,11 +16,11 @@

    [name]

    The Protein Data Bank file format is a textual file describing the three-dimensional structures of molecules.

    -

    Example

    +

    Code Example

    // instantiate a loader - var loader = new THREE.PDBLoader(); + var loader = new PDBLoader(); // load a PDB resource loader.load( @@ -50,8 +51,10 @@

    Example

    );
    - [example:webgl_loader_pdb] - +

    Examples

    +

    + [example:webgl_loader_pdb] +

    Constructor

    @@ -64,9 +67,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -87,16 +91,10 @@

    [method:Object parse]( [param:String text] )

    Parse a pdb text and return a JSON structure.

    -

    [method:PDBLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PDBLoader.js examples/js/loaders/PDBLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PDBLoader.js examples/jsm/loaders/PDBLoader.js] +

    diff --git a/docs/examples/en/loaders/PRWMLoader.html b/docs/examples/en/loaders/PRWMLoader.html index ae7da8413ca01b..6b81c547087308 100644 --- a/docs/examples/en/loaders/PRWMLoader.html +++ b/docs/examples/en/loaders/PRWMLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -19,11 +20,11 @@

    [name]

    on this here.

    -

    Example

    +

    Code Example

    // instantiate a loader - var loader = new THREE.PRWMLoader(); + var loader = new PRWMLoader(); // load a resource loader.load( @@ -51,8 +52,10 @@

    Example

    );
    - [example:webgl_loader_prwm] - +

    Examples

    +

    + [example:webgl_loader_prwm] +

    Constructor

    @@ -65,9 +68,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -94,22 +98,10 @@

    PRWMLoader.isBigEndianPlatform( )

    Return true if the endianness of the platform is Big Endian, false otherwise.

    -

    [method:PRWMLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PRWMLoader.js examples/js/loaders/PRWMLoader.js] - -

    Additional notes

    -

    - This loader is additionally available on npm as three-prwm-loader. + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PRWMLoader.js examples/jsm/loaders/PRWMLoader.js]

    diff --git a/docs/examples/en/loaders/SVGLoader.html b/docs/examples/en/loaders/SVGLoader.html index caca171e47b5bc..13bdf20fe1f2d2 100644 --- a/docs/examples/en/loaders/SVGLoader.html +++ b/docs/examples/en/loaders/SVGLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -15,11 +16,11 @@

    [name]

    Scalable Vector Graphics is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.

    -

    Example

    +

    Code Example

    // instantiate a loader - var loader = new THREE.SVGLoader(); + var loader = new SVGLoader(); // load a SVG resource loader.load( @@ -72,7 +73,10 @@

    Example

    );
    - [example:webgl_loader_svg] +

    Examples

    +

    + [example:webgl_loader_svg] +

    Constructor

    @@ -85,9 +89,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -100,16 +105,10 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and call onLoad with the response content.

    -

    [method:SVGLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/SVGLoader.js examples/js/loaders/SVGLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/SVGLoader.js examples/jsm/loaders/SVGLoader.js] +

    diff --git a/docs/examples/en/loaders/TGALoader.html b/docs/examples/en/loaders/TGALoader.html index 2c75666ede263a..4401a6e58c7044 100644 --- a/docs/examples/en/loaders/TGALoader.html +++ b/docs/examples/en/loaders/TGALoader.html @@ -8,17 +8,19 @@ + [page:Loader] → +

    [name]

    A loader for loading a .tga resource.
    TGA is a raster graphics, image file format.

    -

    Example

    +

    Code Example

    // instantiate a loader - var loader = new THREE.TGALoader(); + var loader = new TGALoader(); // load a resource var texture = loader.load( @@ -50,7 +52,10 @@

    Example

    } );
    - [example:webgl_materials_texture_tga] +

    Examples

    +

    + [example:webgl_loader_texture_tga] +

    Constructor

    @@ -62,8 +67,11 @@

    [name]( [param:LoadingManager manager] )

    Creates a new [name].

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:DataTexture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -76,16 +84,10 @@

    [method:DataTexture load]( [param:String url], [param:Function onLoad], [par Begin loading from url and pass the loaded [page:DataTexture texture] to onLoad. The [page:DataTexture texture] is also directly returned for immediate use (but may not be fully loaded).

    -

    [method:TGALoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/TGALoader.js examples/js/loaders/TGALoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/TGALoader.js examples/jsm/loaders/TGALoader.js] +

    diff --git a/docs/examples/en/Lut.html b/docs/examples/en/math/Lut.html similarity index 91% rename from docs/examples/en/Lut.html rename to docs/examples/en/math/Lut.html index c4bdc641f5aeea..d0a06900affe8b 100644 --- a/docs/examples/en/Lut.html +++ b/docs/examples/en/math/Lut.html @@ -2,7 +2,7 @@ - + @@ -14,12 +14,12 @@

    [name]

    Represents a lookup table for colormaps. It is used to determine the color values from a range of data values.

    +

    Code Example

    -

    Example

    - var lut = new THREE.Lut( "rainbow", 512 ); - var data = [0, 10.1, 4.2, 3.4, 63, 28]; - lut.setMax(63); - color = lut.getColor(10); + + var lut = new Lut( 'rainbow', 512 ); + var color = lut.getColor( 0.5 ); +

    Constructor

    @@ -138,6 +138,8 @@

    [method:Lut getColor]( value ) [param:Lut this]

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/[path].js examples/js/math/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/[path].js examples/jsm/math/[path].js] +

    diff --git a/docs/examples/en/math/MeshSurfaceSampler.html b/docs/examples/en/math/MeshSurfaceSampler.html new file mode 100644 index 00000000000000..ee4ccd9d620671 --- /dev/null +++ b/docs/examples/en/math/MeshSurfaceSampler.html @@ -0,0 +1,86 @@ + + + + + + + + + + +

    [name]

    + +

    Utility class for sampling weighted random points on the surface of a mesh.

    + +

    Weighted sampling is useful for effects like heavier foliage growth in certain areas of terrain, or concentrated particle emissions from specific parts of a mesh. Vertex weights may be written programmatically, or painted by hand as vertex colors in 3D tools like Blender.

    + +

    Code Example

    + + + // Create a sampler for a Mesh surface. + var sampler = new MeshSurfaceSampler( surfaceMesh ) + .setWeightAttribute( 'color' ) + .build(); + + var sampleMesh = new THREE.InstancedMesh( sampleGeometry, sampleMaterial, 100 ); + + var _position = new THREE.Vector3(); + var _normal = new THREE.Vector3(); + var _matrix = new THREE.Matrix4(); + + // Sample randomly from the surface, creating an instance of the sample + // geometry at each sample point. + for ( var i = 0; i < 100; i ++ ) { + + sampler.sample( _position, _normal ); + + _matrix.makeTranslation( _position.x, _position.y, _position.z ); + + mesh.setMatrixAt( i, _matrix ); + + } + + mesh.instanceMatrix.needsUpdate = true; + + scene.add( mesh ); + + +

    Examples

    +

    + [example:webgl_instancing_scatter] +

    + +

    Constructor

    + +

    [name]( [param:Mesh mesh] )

    +

    + [page:Mesh mesh] — Surface mesh from which to sample. +

    +

    + Creates a new [name]. If the input geometry is indexed, a non-indexed copy is made. After construction, the sampler is not able to return samples until [page:MeshSurfaceSampler.build build] is called. +

    + +

    Methods

    + +

    [method:this setWeightAttribute]( [param:String name] )

    +

    + Specifies a vertex attribute to be used as a weight when sampling from the surface. Faces with higher weights are more likely to be sampled, and those with weights of zero will not be sampled at all. For vector attributes, only .x is used in sampling. +

    +

    If no weight attribute is selected, sampling is randomly distributed by area.

    + +

    [method:this build]()

    +

    + Processes the input geometry and prepares to return samples. Any configuration of the geometry or sampler must occur before this method is called. Time complexity is O(n) for a surface with n faces. +

    + +

    [method:this sample]( [param:Vector3 targetPosition], [param:Vector3 targetNormal] )

    +

    + Selects a random point on the surface of the input geometry, returning the position and normal vector at that point. Time complexity is O(log n) for a surface with n faces.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/MeshSurfaceSampler.js examples/jsm/math/MeshSurfaceSampler.js] +

    + + diff --git a/docs/examples/en/math/convexhull/ConvexHull.html b/docs/examples/en/math/convexhull/ConvexHull.html index f301ec2712949f..09ef56195a57ac 100644 --- a/docs/examples/en/math/convexhull/ConvexHull.html +++ b/docs/examples/en/math/convexhull/ConvexHull.html @@ -20,6 +20,7 @@

    Constructor

    [name]()

    + Creates a new instance of [name].

    Properties

    @@ -57,28 +58,35 @@

    [property:Array vertices]

    Methods

    [method:HalfEdge addAdjoiningFace]( [param:VertexNode eyeVertex], [param:HalfEdge horizonEdge] )

    - [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    - [page:HalfEdge horizonEdge] - A single edge of the horizon.

    +

    + [page:VertexNode eyeVertex] - The vertex that is added to the hull.
    + [page:HalfEdge horizonEdge] - A single edge of the horizon.

    -

    Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order. - All the half edges are created in CCW order thus the face is always pointing outside the hull

    + Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order. + All the half edges are created in CCW order thus the face is always pointing outside the hull +

    [method:ConvexHull addNewFaces]( [param:VertexNode eyeVertex], [param:HalfEdge horizonEdge] )

    - [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    - [page:HalfEdge horizon] - An array of half-edges that form the horizon.

    +

    + [page:VertexNode eyeVertex] - The vertex that is added to the hull.
    + [page:HalfEdge horizon] - An array of half-edges that form the horizon.

    -

    Adds 'horizon.length' faces to the hull, each face will be linked with the horizon opposite face and the face on the left/right.

    + Adds 'horizon.length' faces to the hull, each face will be linked with the horizon opposite face and the face on the left/right. +

    [method:ConvexHull addVertexToFace]( [param:VertexNode vertex], [param:Face face] )

    - [page:VertexNodeNode vertex] - The vertex to add.

    - [page:Face face] - The target face.

    +

    + [page:VertexNodeNode vertex] - The vertex to add.
    + [page:Face face] - The target face.

    -

    Adds a vertex to the 'assigned' list of vertices and assigns it to the given face.

    + Adds a vertex to the 'assigned' list of vertices and assigns it to the given face. +

    [method:ConvexHull addVertexToHull]( [param:VertexNode eyeVertex] )

    - [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    +

    + [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    -

    Adds a vertex to the hull with the following algorithm + Adds a vertex to the hull with the following algorithm

    • Compute the 'horizon' which is a chain of half edges. For an edge to belong to this group it must be the edge connecting a face that can see 'eyeVertex' and a face which cannot see 'eyeVertex'.
    • All the faces that can see 'eyeVertex' have its visible vertices removed from the assigned vertex list.
    • @@ -100,27 +108,32 @@

      [method:Object computeExtremes]()

      Computes the extremes values (min/max vectors) which will be used to compute the inital hull.

      [method:ConvexHull computeHorizon]( [param:Vector3 eyePoint], [param:HalfEdge crossEdge], [param:Face face], [param:Array horizon] )

      - [page:Vector3 eyePoint] - The 3D-coordinates of a point.

      - [page:HalfEdge crossEdge] - The edge used to jump to the current face.

      - [page:Face face] - The current face being tested.

      - [page:Array horizon] - The edges that form part of the horizon in CCW order.

      +

      + [page:Vector3 eyePoint] - The 3D-coordinates of a point.
      + [page:HalfEdge crossEdge] - The edge used to jump to the current face.
      + [page:Face face] - The current face being tested.
      + [page:Array horizon] - The edges that form part of the horizon in CCW order.

      -

      Computes a chain of half edges in CCW order called the 'horizon'. For an edge to be part of the horizon it must join a face that can see 'eyePoint' and a face that cannot see 'eyePoint'.

      + Computes a chain of half edges in CCW order called the 'horizon'. For an edge to be part of the horizon it must join a face that can see 'eyePoint' and a face that cannot see 'eyePoint'. +

      [method:ConvexHull computeInitialHull]()

      Computes the initial simplex assigning to its faces all the points that are candidates to form part of the hull.

      [method:ConvexHull containsPoint]( [param:Vector3 point] )

      - [page:Vector3 point] - A point in 3D space.

      +

      + [page:Vector3 point] - A point in 3D space.

      -

      Returns *true* if the given point is inside this convex hull.

      + Returns *true* if the given point is inside this convex hull. +

      [method:ConvexHull deleteFaceVertices]( [param:Face face], [param:Face absorbingFace] )

      - [page:Face face] - The given face.

      - [page:Face absorbingFace] - An optional face that tries to absorb the vertices of the first face.

      +

      + [page:Face face] - The given face.
      + [page:Face absorbingFace] - An optional face that tries to absorb the vertices of the first face.

      -

      Removes all the visible vertices that 'face' is able to see. + Removes all the visible vertices that 'face' is able to see.

      • If 'absorbingFace' doesn't exist, then all the removed vertices will be added to the 'unassigned' vertex list.
      • If 'absorbingFace' exists, then this method will assign all the vertices of 'face' that can see 'absorbingFace'.
      • @@ -129,15 +142,19 @@

        [method:ConvexHull deleteFaceVertices]( [param:Face face], [param:Face absor

        [method:Vector3 intersectRay]( [param:Ray ray], [param:Vector3 target] )

        - [page:Ray ray] - The given ray.

        - [page:Vector3 target] - The target vector representing the intersection point.

        +

        + [page:Ray ray] - The given ray.
        + [page:Vector3 target] - The target vector representing the intersection point.

        -

        Performs a ray intersection test with this convext hull. If no intersection is found, *null* is returned.

        + Performs a ray intersection test with this convext hull. If no intersection is found, *null* is returned. +

        [method:Boolean intersectsRay]( [param:Ray ray] )

        - [page:Ray ray] - The given ray.

        +

        + [page:Ray ray] - The given ray.

        -

        Returns *true* if the given ray intersects with this convex hull.

        + Returns *true* if the given ray intersects with this convex hull. +

        [method:ConvexHull makeEmpty]()

        @@ -158,34 +175,45 @@

        [method:ConvexHull reindexFaces]()

        Removes inactive (e.g. deleted) faces from the internal face list.

        [method:VertexNode removeAllVerticesFromFace]( [param:Face face] )

        - [page:Face face] - The given face.

        +

        + [page:Face face] - The given face.

        -

        Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertext list.

        + Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertext list. +

        [method:ConvexHull removeVertexFromFace]( [param:VertexNode vertex], [param:Face face] )

        - [page:VertexNode vertex] - The vertex to remove.

        - [page:Face face] - The target face.

        +

        + [page:VertexNode vertex] - The vertex to remove.
        + [page:Face face] - The target face.

        -

        Removes a vertex from the 'assigned' list of vertices and from the given face. It also makes sure that the link from 'face' to the first vertex it sees in 'assigned' is linked correctly after the removal.

        + Removes a vertex from the 'assigned' list of vertices and from the given face. It also makes sure that the link from 'face' to the first vertex it sees in 'assigned' is linked correctly after the removal. +

        [method:ConvexHull resolveUnassignedPoints]( [param:Array newFaces] )

        - [page:Face newFaces] - An array of new faces.

        +

        + [page:Face newFaces] - An array of new faces.

        -

        Reassigns as many vertices as possible from the unassigned list to the new faces.

        + Reassigns as many vertices as possible from the unassigned list to the new faces. +

        [method:ConvexHull setFromObject]( [param:Object3D object] )

        - [page:Object3D object] - [page:Object3D] to compute the convex hull of.

        +

        + [page:Object3D object] - [page:Object3D] to compute the convex hull of.

        -

        Computes the convex hull of an [page:Object3D] (including its children), - accounting for the world transforms of both the object and its childrens.

        + Computes the convex hull of an [page:Object3D] (including its children),accounting for the world transforms of both the object and its childrens. +

        [method:ConvexHull setFromPoints]( [param:Array points] )

        - [page:Array points] - Array of [page:Vector3 Vector3s] that the resulting convex hull will contain.

        +

        + [page:Array points] - Array of [page:Vector3 Vector3s] that the resulting convex hull will contain.

        -

        Computes to convex hull for the given array of points.

        + Computes to convex hull for the given array of points. +

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/ConvexHull.js] +

        diff --git a/docs/examples/en/math/convexhull/Face.html b/docs/examples/en/math/convexhull/Face.html index 265abcfc3257c5..f1797665aeaaba 100644 --- a/docs/examples/en/math/convexhull/Face.html +++ b/docs/examples/en/math/convexhull/Face.html @@ -20,6 +20,7 @@

        Constructor

        [name]()

        + Creates a new instance of [name].

        Properties

        @@ -62,28 +63,36 @@

        [property:HalfEdge edge]

        Methods

        [method:Face create]( [param:VertexNode a], [param:VertexNode b], [param:VertexNode c] )

        - [page:VertexNode a] - First vertex of the face.

        - [page:VertexNode b] - Second vertex of the face.

        - [page:VertexNode c] - Third vertex of the face.

        +

        + [page:VertexNode a] - First vertex of the face.
        + [page:VertexNode b] - Second vertex of the face.
        + [page:VertexNode c] - Third vertex of the face.

        -

        Creates a face.

        + Creates a face. +

        [method:HalfEdge getEdge]( [param:Integer i] )

        - [page:Integer i] - The index of the edge.

        +

        + [page:Integer i] - The index of the edge.

        -

        Returns an edge by the given index.

        + Returns an edge by the given index. +

        [method:Face compute] ()

        Computes all properties of the face.

        [method:Float distanceToPoint]( [param:Vector3 point] )

        - [page:Vector3 point] - Any point in 3D space.

        +

        + [page:Vector3 point] - Any point in 3D space.

        -

        Returns the signed distance from a given point to the plane representation of this face.

        + Returns the signed distance from a given point to the plane representation of this face. +

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/en/math/convexhull/HalfEdge.html b/docs/examples/en/math/convexhull/HalfEdge.html index c8de2778faaee8..2834cf81fbdf57 100644 --- a/docs/examples/en/math/convexhull/HalfEdge.html +++ b/docs/examples/en/math/convexhull/HalfEdge.html @@ -20,8 +20,10 @@

        Constructor

        [name]( [param:VertexNode vertex], [param:Face face] )

        - [page:VertexNode vertex] - [page:VertexNode] A reference to its destination vertex.

        - [page:Face face] - [page:Face] A reference to its face.
        + [page:VertexNode vertex] - [page:VertexNode] A reference to its destination vertex.
        + [page:Face face] - [page:Face] A reference to its face.

        + + Creates a new instance of [name].

        Properties

        @@ -68,12 +70,16 @@

        [method:Float lengthSquared]()

        (straight-line length) of the edge.

        [method:HalfEdge setTwin]( [param:HalfEdge edge] )

        - [page:HalfEdge edge] - Any half-edge.

        +

        + [page:HalfEdge edge] - Any half-edge.

        -

        Sets the twin edge of this half-edge. It also ensures that the twin reference of the given half-edge is correctly set.

        + Sets the twin edge of this half-edge. It also ensures that the twin reference of the given half-edge is correctly set. +

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/en/math/convexhull/VertexList.html b/docs/examples/en/math/convexhull/VertexList.html index aa7ac965e16160..fa050a83a91cd4 100644 --- a/docs/examples/en/math/convexhull/VertexList.html +++ b/docs/examples/en/math/convexhull/VertexList.html @@ -20,6 +20,7 @@

        Constructor

        [name]()

        + Creates a new instance of [name].

        Properties

        @@ -47,38 +48,48 @@

        [method:VertexList clear]()

        [method:VertexList insertBefore]( [param:Vertex target], [param:Vertex vertex] )

        - [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.

        - [page:Vertex vertex] - The vertex to insert.

        -

        + [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.
        + [page:Vertex vertex] - The vertex to insert.

        -

        Inserts a vertex before a target vertex.

        + Inserts a vertex before a target vertex. +

        [method:VertexList insertAfter]( [param:Vertex target], [param:Vertex vertex] )

        - [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.

        - [page:Vertex vertex] - The vertex to insert.

        +

        + [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.
        + [page:Vertex vertex] - The vertex to insert.

        -

        Inserts a vertex after a target vertex.

        + Inserts a vertex after a target vertex. +

        [method:VertexList append]( [param:Vertex vertex] )

        - [page:Vertex vertex] - The vertex to append.

        +

        + [page:Vertex vertex] - The vertex to append.

        -

        Appends a vertex to the end of the linked list.

        + Appends a vertex to the end of the linked list. +

        [method:VertexList appendChain]( [param:Vertex vertex] )

        - [page:Vertex vertex] - The head vertex of a chain of vertices.

        +

        + [page:Vertex vertex] - The head vertex of a chain of vertices.

        -

        Appends a chain of vertices where the given vertex is the head.

        + Appends a chain of vertices where the given vertex is the head. +

        [method:VertexList remove]( [param:Vertex vertex] )

        - [page:Vertex vertex] - The vertex to remove.

        +

        + [page:Vertex vertex] - The vertex to remove.

        -

        Removes a vertex from the linked list.

        + Removes a vertex from the linked list. +

        [method:VertexList removeSubList]( [param:Vertex a], [param:Vertex b] )

        - [page:Vertex a] - The head of the sublist.

        - [page:Vertex b] - The tail of the sublist.

        +

        + [page:Vertex a] - The head of the sublist.
        + [page:Vertex b] - The tail of the sublist.

        -

        Removes a sublist of vertices from the linked list.

        + Removes a sublist of vertices from the linked list. +

        [method:Boolean isEmpty]()

        @@ -86,6 +97,8 @@

        [method:Boolean isEmpty]()

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/en/math/convexhull/VertexNode.html b/docs/examples/en/math/convexhull/VertexNode.html index 8c139829a31b01..e963c28835b0ef 100644 --- a/docs/examples/en/math/convexhull/VertexNode.html +++ b/docs/examples/en/math/convexhull/VertexNode.html @@ -21,6 +21,8 @@

        Constructor

        [name]( [param:Vector3 point] )

        [page:Vector3 point] - [page:Vector3] A point (x, y, z) in 3D space.

        + + Creates a new instance of [name].

        Properties

        @@ -47,6 +49,8 @@

        [property:Face face]

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/en/objects/Lensflare.html b/docs/examples/en/objects/Lensflare.html index d9ba42c25f19fc..5ceb56ee533eff 100644 --- a/docs/examples/en/objects/Lensflare.html +++ b/docs/examples/en/objects/Lensflare.html @@ -13,32 +13,33 @@

        [name]

        - Creates a simulated lens flare that tracks a light.

        + Creates a simulated lens flare that tracks a light.

        -

        Example

        +

        Code Example

        -

        - [example:webgl_lensflares lensflares] + + var light = new THREE.PointLight( 0xffffff, 1.5, 2000 ); - -var light = new THREE.PointLight( 0xffffff, 1.5, 2000 ); + var textureLoader = new THREE.TextureLoader(); -var textureLoader = new THREE.TextureLoader(); + var textureFlare0 = textureLoader.load( "textures/lensflare/lensflare0.png" ); + var textureFlare1 = textureLoader.load( "textures/lensflare/lensflare2.png" ); + var textureFlare2 = textureLoader.load( "textures/lensflare/lensflare3.png" ); -var textureFlare0 = textureLoader.load( "textures/lensflare/lensflare0.png" ); -var textureFlare1 = textureLoader.load( "textures/lensflare/lensflare2.png" ); -var textureFlare2 = textureLoader.load( "textures/lensflare/lensflare3.png" ); + var lensflare = new Lensflare(); -var lensflare = new THREE.Lensflare(); + lensflare.addElement( new LensflareElement( textureFlare0, 512, 0 ) ); + lensflare.addElement( new LensflareElement( textureFlare1, 512, 0 ) ); + lensflare.addElement( new LensflareElement( textureFlare2, 60, 0.6 ) ); -lensflare.addElement( new THREE.LensflareElement( textureFlare0, 512, 0 ) ); -lensflare.addElement( new THREE.LensflareElement( textureFlare1, 512, 0 ) ); -lensflare.addElement( new THREE.LensflareElement( textureFlare2, 60, 0.6 ) ); + light.add( lensflare ); + -light.add( lensflare ); - +

        Examples

        +

        + [example:webgl_lensflares WebGL / lensflares]

        Constructor

        @@ -55,16 +56,11 @@

        LensflareElement( [param:Texture texture], [param:Float size], [param:Float

        Properties

        See the base [page:Mesh] class for common properties.

        -

        [property:Boolean isLensflare]

        -

        - Used to check whether this or derived classes are lensflares. Default is *true*.

        - - You should not change this, as it used internally for optimisation. -

        -

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/objects/Lensflare.js examples/js/objects/Lensflare.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Lensflare.js examples/jsm/objects/Lensflare.js] +

        diff --git a/docs/examples/en/postprocessing/EffectComposer.html b/docs/examples/en/postprocessing/EffectComposer.html index 4a8209b51f030f..8e6ebc8927a661 100644 --- a/docs/examples/en/postprocessing/EffectComposer.html +++ b/docs/examples/en/postprocessing/EffectComposer.html @@ -56,7 +56,7 @@

        [name]( [param:WebGLRenderer renderer], [param:WebGLRenderTarget renderTarge

        Properties

        -

        [property:Boolean passes]

        +

        [property:Array passes]

        An array representing the (ordered) chain of post-processing passes.

        @@ -150,6 +150,8 @@

        [method:void swapBuffers]()

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/postprocessing/EffectComposer.js examples/js/postprocessing/EffectComposer.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/postprocessing/EffectComposer.js examples/jsm/postprocessing/EffectComposer.js] +

        diff --git a/docs/examples/en/renderers/CSS2DRenderer.html b/docs/examples/en/renderers/CSS2DRenderer.html index 7cf3252b988abf..42ae2eeb9e6ab3 100644 --- a/docs/examples/en/renderers/CSS2DRenderer.html +++ b/docs/examples/en/renderers/CSS2DRenderer.html @@ -14,22 +14,6 @@

        [name]

        The renderer is very useful if you want to combine HTML based labels with 3D objects. Here too, the respective DOM elements are wrapped into an instance of *CSS2DObject* and added to the scene graph.

        - -

        Examples

        @@ -60,6 +44,8 @@

        [method:null setSize]([param:Number width], [param:Number height])

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CSS2DRenderer.js examples/js/renderers/CSS2DRenderer.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/CSS2DRenderer.js examples/jsm/renderers/CSS2DRenderer.js] +

        diff --git a/docs/examples/en/renderers/CSS3DRenderer.html b/docs/examples/en/renderers/CSS3DRenderer.html index 9e904461a982b7..8f94854c4a368d 100644 --- a/docs/examples/en/renderers/CSS3DRenderer.html +++ b/docs/examples/en/renderers/CSS3DRenderer.html @@ -23,22 +23,6 @@

        [name]

        So [name] is just focused on ordinary DOM elements. These elements are wrapped into special objects (*CSS3DObject* or *CSS3DSprite*) and then added to the scene graph.

        - -

        Examples

        @@ -72,6 +56,8 @@

        [method:null setSize]([param:Number width], [param:Number height])

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CSS3DRenderer.js examples/js/renderers/CSS3DRenderer.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/CSS3DRenderer.js examples/jsm/renderers/CSS3DRenderer.js] +

        diff --git a/docs/examples/en/renderers/SVGRenderer.html b/docs/examples/en/renderers/SVGRenderer.html index 8c8209157ebbf3..48743fef686d0a 100644 --- a/docs/examples/en/renderers/SVGRenderer.html +++ b/docs/examples/en/renderers/SVGRenderer.html @@ -34,22 +34,6 @@

        [name]

    - -

    Examples

    @@ -102,6 +86,8 @@

    [method:null setSize]( [param:Number width], [param:Number height] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/SVGRenderer.js examples/js/renderers/SVGRenderer.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/SVGRenderer.js examples/jsm/renderers/SVGRenderer.js] +

    diff --git a/docs/examples/en/utils/BufferGeometryUtils.html b/docs/examples/en/utils/BufferGeometryUtils.html index 5772efeaebcef9..595e9cf194abc0 100644 --- a/docs/examples/en/utils/BufferGeometryUtils.html +++ b/docs/examples/en/utils/BufferGeometryUtils.html @@ -1,80 +1,92 @@ - - - - - - - - -

    [name]

    + + + + + + + + +

    [name]

    -

    - A class containing utility functions for [page:BufferGeometry BufferGeometry] instances.

    -

    +

    + A class containing utility functions for [page:BufferGeometry BufferGeometry] instances. +

    -

    Methods

    +

    Methods

    -

    [method:null computeTangents]( [param:BufferGeometry geometry] )

    -

    - geometry -- A [page:BufferGeometry BufferGeometry] instance, which must have index, position, normal, and uv attributes.

    +

    [method:null computeTangents]( [param:BufferGeometry geometry] )

    +

    + geometry -- A [page:BufferGeometry BufferGeometry] instance, which must have index, position, normal, and uv attributes.

    - Calculates and adds tangent attribute to a geometry.

    + Calculates and adds tangent attribute to a geometry. -

    +

    -

    [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

    -

    - geometries -- Array of [page:BufferGeometry BufferGeometry] instances.
    - useGroups -- Whether groups should be generated for the merged geometry or not.

    +

    [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

    +

    + geometries -- Array of [page:BufferGeometry BufferGeometry] instances.
    + useGroups -- Whether groups should be generated for the merged geometry or not.

    - Merges a set of geometries into a single instance. All geometries must have compatible attributes. - If merge does not succeed, the method returns null.

    + Merges a set of geometries into a single instance. All geometries must have compatible attributes. + If merge does not succeed, the method returns null. -

    +

    -

    [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

    -

    - attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

    +

    [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

    +

    + attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

    - Merges a set of attributes into a single instance. All attributes must have compatible properties - and types, and [page:InterleavedBufferAttribute InterleavedBufferAttributes] are not supported. If merge does not succeed, the method - returns null. + Merges a set of attributes into a single instance. All attributes must have compatible properties + and types, and [page:InterleavedBufferAttribute InterleavedBufferAttributes] are not supported. If merge does not succeed, the method + returns null. -

    +

    -

    [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )

    -

    - attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

    +

    [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )

    +

    + attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

    - Interleaves a set of attributes and returns a new array of corresponding attributes that share - a single InterleavedBuffer instance. All attributes must have compatible types. If merge does not - succeed, the method returns null. + Interleaves a set of attributes and returns a new array of corresponding attributes that share + a single InterleavedBuffer instance. All attributes must have compatible types. If merge does not + succeed, the method returns null. -

    +

    -

    [method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )

    -

    - geometry -- Instance of [page:BufferGeometry BufferGeometry] to estimate the memory use of.

    +

    [method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )

    +

    + geometry -- Instance of [page:BufferGeometry BufferGeometry] to estimate the memory use of.

    - Returns the amount of bytes used by all attributes to represent the geometry. + Returns the amount of bytes used by all attributes to represent the geometry. -

    +

    -

    [method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [param:Number tolerance] )

    -

    - geometry -- Instance of [page:BufferGeometry BufferGeometry] to merge the vertices of.
    - tolerance -- The maximum allowable difference between vertex attributes to merge. Defaults to 1e-4.

    +

    [method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [param:Number tolerance] )

    +

    + geometry -- Instance of [page:BufferGeometry BufferGeometry] to merge the vertices of.
    + tolerance -- The maximum allowable difference between vertex attributes to merge. Defaults to 1e-4.

    - Returns a new [page:BufferGeometry BufferGeometry] with vertices for which all similar vertex attributes - (within tolerance) are merged. + Returns a new [page:BufferGeometry BufferGeometry] with vertices for which all similar vertex attributes + (within tolerance) are merged. -

    +

    -

    Source

    +

    [method:BufferGeometry toTrianglesDrawMode]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )

    +

    + geometry -- Instance of [page:BufferGeometry BufferGeometry].
    + drawMode -- The draw mode of the given geometry.

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/BufferGeometryUtils.js examples/js/utils/BufferGeometryUtils.js] - + Returns a new indexed [page:BufferGeometry BufferGeometry] based on the [page:DrawModes THREE.TrianglesDrawMode] draw mode. This mode + corresponds to the *gl.TRIANGLES* WebGL primitive. + +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/BufferGeometryUtils.js examples/jsm/utils/BufferGeometryUtils.js] +

    + diff --git a/docs/examples/en/utils/SceneUtils.html b/docs/examples/en/utils/SceneUtils.html index 37e74b5c1a3726..3538519c923747 100644 --- a/docs/examples/en/utils/SceneUtils.html +++ b/docs/examples/en/utils/SceneUtils.html @@ -15,6 +15,13 @@

    [name]

    Methods

    +

    [method:Group createMultiMaterialObject]( [param:InstancedMesh instancedMesh] )

    +

    + instancedMesh -- The instanced mesh. +

    +

    + Creates a new group object that contains a new mesh for each instance of the given instanced mesh. +

    [method:Group createMultiMaterialObject]( [param:Geometry geometry], [param:Array materials] )

    @@ -28,6 +35,8 @@

    [method:Group createMultiMaterialObject]( [param:Geometry geometry], [param:

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/SceneUtils.js examples/js/utils/SceneUtils.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/SceneUtils.js examples/jsm/utils/SceneUtils.js] +

    diff --git a/docs/examples/en/utils/SkeletonUtils.html b/docs/examples/en/utils/SkeletonUtils.html index 5e272e6fcb9792..f9adec5a1e2835 100644 --- a/docs/examples/en/utils/SkeletonUtils.html +++ b/docs/examples/en/utils/SkeletonUtils.html @@ -55,6 +55,8 @@

    [method:AnimationClip retargetClip]( [param:SkeletonHelper target], [param:S

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/SkeletonUtils.js examples/js/utils/SkeletonUtils.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/SkeletonUtils.js examples/jsm/utils/SkeletonUtils.js] +

    diff --git a/docs/examples/zh/animations/CCDIKSolver.html b/docs/examples/zh/animations/CCDIKSolver.html index 8cc96b82839097..16a88296b2acd1 100644 --- a/docs/examples/zh/animations/CCDIKSolver.html +++ b/docs/examples/zh/animations/CCDIKSolver.html @@ -15,13 +15,13 @@

    [name]

    [name] is designed to work with [page:SkinnedMesh] loaded by [page:MMDLoader] but also can be used for generic [page:SkinnedMesh].

    -

    Example

    +

    代码示例

    var ikSolver; // Load MMD resources and instantiate CCDIKSolver - new THREE.MMDLoader().load( + new MMDLoader().load( 'models/mmd/miku.pmd', function ( mesh ) { @@ -40,12 +40,13 @@

    Example

    }
    - [example:webgl_loader_mmd]
    - [example:webgl_loader_mmd_pose]
    - [example:webgl_loader_mmd_audio]
    +

    例子

    -
    -
    +

    + [example:webgl_loader_mmd]
    + [example:webgl_loader_mmd_pose]
    + [example:webgl_loader_mmd_audio] +

    Constructor

    @@ -97,6 +98,8 @@

    [method:CCDIKSolver update]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/animation/CCDIKSolver.js examples/js/animation/CCDIKSolver.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/CCDIKSolver.js examples/jsm/animation/CCDIKSolver.js] +

    diff --git a/docs/examples/zh/animations/MMDAnimationHelper.html b/docs/examples/zh/animations/MMDAnimationHelper.html index ae6e804db0a291..534741eb1bcfb9 100644 --- a/docs/examples/zh/animations/MMDAnimationHelper.html +++ b/docs/examples/zh/animations/MMDAnimationHelper.html @@ -15,14 +15,14 @@

    [name]

    It uses [page:CCDIKSolver] and [page:MMDPhysics] inside.

    -

    Example

    +

    代码示例

    // Instantiate a helper - var helper = new THREE.MMDAnimationHelper(); + var helper = new MMDAnimationHelper(); // Load MMD resources and add to helper - new THREE.MMDLoader().loadWithAnimation( + new MMDLoader().loadWithAnimation( 'models/mmd/miku.pmd', 'models/mmd/dance.vmd', function ( mmd ) { @@ -62,12 +62,13 @@

    Example

    }
    - [example:webgl_loader_mmd]
    - [example:webgl_loader_mmd_pose]
    - [example:webgl_loader_mmd_audio]
    +

    例子

    -
    -
    +

    + [example:webgl_loader_mmd]
    + [example:webgl_loader_mmd_pose]
    + [example:webgl_loader_mmd_audio] +

    Constructor

    @@ -164,6 +165,8 @@

    [method:MMDAnimationHelper update]( [param:Nummber delta] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/animation/MMDAnimationHelper.js examples/js/animation/MMDAnimationHelper.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDAnimationHelper.js examples/jsm/animation/MMDAnimationHelper.js] +

    diff --git a/docs/examples/zh/animations/MMDPhysics.html b/docs/examples/zh/animations/MMDPhysics.html index 1117b41954ab2b..1f959ef8fc4a53 100644 --- a/docs/examples/zh/animations/MMDPhysics.html +++ b/docs/examples/zh/animations/MMDPhysics.html @@ -14,17 +14,17 @@

    [name]

    [name] calculates Physics for model loaded by [page:MMDLoader] with ammo.js (Bullet-based JavaScript Physics engine).

    -

    Example

    +

    代码示例

    var physics; // Load MMD resources and instantiate MMDPhysics - new THREE.MMDLoader().load( + new MMDLoader().load( 'models/mmd/miku.pmd', function ( mesh ) { - physics = new THREE.MMDPhysics( mesh ) + physics = new MMDPhysics( mesh ) scene.add( mesh ); } @@ -40,11 +40,12 @@

    Example

    }
    - [example:webgl_loader_mmd]
    - [example:webgl_loader_mmd_audio]
    +

    例子

    -
    -
    +

    + [example:webgl_loader_mmd]
    + [example:webgl_loader_mmd_audio] +

    Constructor

    @@ -107,6 +108,8 @@

    [method:CCDIKSolver warmup]( [param:Integer cycles] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/animation/MMDPhysics.js examples/js/animation/MMDPhysics.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/animation/MMDPhysics.js examples/jsm/animation/MMDPhysics.js] +

    diff --git a/docs/examples/zh/controls/DeviceOrientationControls.html b/docs/examples/zh/controls/DeviceOrientationControls.html new file mode 100644 index 00000000000000..0362ab1f995d17 --- /dev/null +++ b/docs/examples/zh/controls/DeviceOrientationControls.html @@ -0,0 +1,89 @@ + + + + + + + + + + + +

    [name]

    + +

    + Can be used to orient the camera based on the mobile device's orientation. +

    + +

    例子

    + +

    [example:misc_controls_deviceorientation misc / controls / deviceorientation ]

    + +

    Constructor

    + +

    [name]( [param:Camera object] )

    +

    +

    + [page:Camera object]: The camera to be controlled. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Properties

    + +

    [property:Number alphaOffset]

    +

    + The alpha offset in radians. Default is *0*. +

    + +

    [property:Object deviceOrientation]

    +

    + The current *deviceorientation* event object. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:Camera object]

    +

    + The camera to be controlled. +

    + +

    [property:Number screenOrientation]

    +

    + The orientation in degrees (in 90-degree increments) of the viewport relative to the device's natural orientation. Default is *0*. +

    + +

    Methods

    + +

    [method:null connect] ()

    +

    + Adds the event listeners of the controls and enables it. +

    + +

    [method:null disconnect] ()

    +

    + Removes the event listeners of the controls and disables it. +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null update] ()

    +

    + Updates the controls. Usually called in the animation loop. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DeviceOrientationControls.js examples/jsm/controls/DeviceOrientationControls.js] +

    + + diff --git a/docs/examples/zh/controls/DragControls.html b/docs/examples/zh/controls/DragControls.html new file mode 100644 index 00000000000000..70ce9fa9be7a95 --- /dev/null +++ b/docs/examples/zh/controls/DragControls.html @@ -0,0 +1,131 @@ + + + + + + + + + + + [page:EventDispatcher] → + +

    [name]

    + +

    + This class can be used to provide a drag'n'drop interaction. +

    + +

    代码示例

    + + + var controls = new DragControls( objects, camera, renderer.domElement ); + + // add event listener to highlight dragged objects + + controls.addEventListener( 'dragstart', function ( event ) { + + event.object.material.emissive.set( 0xaaaaaa ); + + } ); + + controls.addEventListener( 'dragend', function ( event ) { + + event.object.material.emissive.set( 0x000000 ); + + } ); + + +

    例子

    + +

    [example:misc_controls_drag misc / controls / drag ]

    + +

    Constructor

    + +

    [name]( [param:Array objects], [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Array objects]: An array of draggable 3D objects. +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    dragstart

    +

    + Fires when the user starts to drag a 3D object. +

    + +

    drag

    +

    + Fires when the user drags a 3D object. +

    + +

    dragend

    +

    + Fires when the user has finished dragging a 3D object. +

    + +

    hoveron

    +

    + Fires when the pointer is moved onto a 3D object, or onto one of its children. +

    + +

    hoveroff

    +

    + Fires when the pointer is moved out of a 3D object. +

    + +

    Properties

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:Boolean transformGroup]

    +

    + This option only works if the [page:DragControls.objects] array contains a single draggable group object. + If set to *true*, [name] does not transform individual objects but the entire group. Default is *false*. +

    + +

    Methods

    + +

    See the base [page:EventDispatcher] class for common methods.

    + +

    [method:null activate] ()

    +

    + Adds the event listeners of the controls. +

    + +

    [method:null deactivate] ()

    +

    + Removes the event listeners of the controls. +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:Array getObjects] ()

    +

    + Returns the array of draggable objects. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/DragControls.js examples/jsm/controls/DragControls.js] +

    + + diff --git a/docs/examples/zh/controls/FirstPersonControls.html b/docs/examples/zh/controls/FirstPersonControls.html new file mode 100644 index 00000000000000..017b81b0ec95d8 --- /dev/null +++ b/docs/examples/zh/controls/FirstPersonControls.html @@ -0,0 +1,165 @@ + + + + + + + + + + + +

    [name]

    + +

    + This class is an alternative implementation of [page:FlyControls]. +

    + +

    例子

    + +

    [example:webgl_geometry_terrain webgl / geometry / terrain ]

    + +

    Constructor

    + +

    [name]( [param:Camera object], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera object]: The camera to be controlled. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Properties

    + +

    [property:Boolean activeLook]

    +

    + Whether or not it's possible to look around. Default is *true*. +

    + +

    [property:Boolean autoForward]

    +

    + Whether or not the camera is automatically moved forward. Default is *false*. +

    + +

    [property:Boolean constrainVertical]

    +

    + Whether or not looking around is vertically constrained by [[page:.verticalMin], [page:.verticalMax]]. Default is *false*. +

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. Default is *true*. +

    + +

    [property:Number heightCoef]

    +

    + Determines how much faster the camera moves when it's y-component is near [page:.heightMax]. Default is *1*. +

    + +

    [property:Number heightMax]

    +

    + Upper camera height limit used for movement speed adjusment. Default is *1*. +

    + +

    [property:Number heightMin]

    +

    + Lower camera height limit used for movement speed adjusment. Default is *0*. +

    + +

    [property:Boolean heightSpeed]

    +

    + Whether or not the camera's height influences the forward movement speed. Default is *false*. + Use the properties [page:.heightCoef], [page:.heightMin] and [page:.heightMax] for configuration. +

    + +

    [property:Boolean lookVertical]

    +

    + Whether or not it's possible to vertically look around. Default is *true*. +

    + +

    [property:Number lookSpeed]

    +

    + The look around speed. Default is *0.005*. +

    + +

    [property:Boolean mouseDragOn]

    +

    + Whether or not the mouse is pressed down. Read-only property. +

    + +

    [property:Number movementSpeed]

    +

    + The movement speed. Default is *1*. +

    + +

    [property:Camera object]

    +

    + The camera to be controlled. +

    + +

    [property:Number verticalMax]

    +

    + How far you can vertically look around, upper limit. Range is 0 to Math.PI radians. Default is *Math.PI*. +

    + +

    [property:Number verticalMin]

    +

    + How far you can vertically look around, lower limit. Range is 0 to Math.PI radians. Default is *0*. +

    + +

    Methods

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null handleResize] ()

    +

    + Should be called if the application window is resized. +

    + +

    [method:FirstPersonControls lookAt]( [param:Vector3 vector] )
    + [method:FirstPersonControls lookAt]( [param:Float x], [param:Float y], [param:Float z] )

    +

    +

    +

    + vector - A vector representing the target position. +

    +

    + Optionally, the x, y, z components of the world space position. +

    +

    +

    + Ensures the controls orient the camera towards the defined target position. +

    +

    + +

    [method:null update] ( [param:Number delta] )

    +

    +

    + [page:Number delta]: Time delta value. +

    +

    + Updates the controls. Usually called in the animation loop. +

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/FirstPersonControls.js examples/jsm/controls/FirstPersonControls.js] +

    + + diff --git a/docs/examples/zh/controls/FlyControls.html b/docs/examples/zh/controls/FlyControls.html new file mode 100644 index 00000000000000..b0c09081759c6c --- /dev/null +++ b/docs/examples/zh/controls/FlyControls.html @@ -0,0 +1,94 @@ + + + + + + + + + + + +

    [name]

    + +

    + [name] enables a navigation similar to fly modes in DCC tools like Blender. You can arbitrarily transform the camera in + 3D space without any limitations (e.g. focus on a specific target). +

    + +

    例子

    + +

    [example:misc_controls_fly misc / controls / fly ]

    + +

    Constructor

    + +

    [name]( [param:Camera object], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera object]: The camera to be controlled. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Properties

    + +

    [property:Boolean autoForward]

    +

    + If set to *true*, the camera automatically moves forward (and does not stop) when initially translated. Default is *false*. +

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Boolean dragToLook]

    +

    + If set to *true*, you can only look around by performing a drag interaction. Default is *false*. +

    + +

    [property:Number movementSpeed]

    +

    + The movement speed. Default is *1*. +

    + +

    [property:Camera object]

    +

    + The camera to be controlled. +

    + +

    [property:Number rollSpeed]

    +

    + The rotation speed. Default is *0.005*. +

    + +

    Methods

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null update] ( [param:Number delta] )

    +

    +

    + [page:Number delta]: Time delta value. +

    +

    + Updates the controls. Usually called in the animation loop. +

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/FlyControls.js examples/jsm/controls/FlyControls.js] +

    + + diff --git a/docs/examples/zh/controls/OrbitControls.html b/docs/examples/zh/controls/OrbitControls.html index d9802445f67425..42dfc11e00f9c2 100644 --- a/docs/examples/zh/controls/OrbitControls.html +++ b/docs/examples/zh/controls/OrbitControls.html @@ -8,56 +8,56 @@ -

    [name]

    +

    轨道控制器([name])

    - Orbit controls allow the camera to orbit around a target.
    + Orbit controls(轨道控制器)可以使得相机围绕目标进行轨道运动。
    - To use this, as with all files in the /examples directory, you will have to - include the file seperately in your HTML. + 要使用这一功能,就像在/examples(示例)目录中的所有文件一样, + 您必须在HTML中包含这个文件。

    - -

    Example

    - -

    [example:misc_controls_orbit misc / controls / orbit ]

    +

    代码示例

    -var renderer = new THREE.WebGLRenderer(); -renderer.setSize( window.innerWidth, window.innerHeight ); -document.body.appendChild( renderer.domElement ); + var renderer = new THREE.WebGLRenderer(); + renderer.setSize( window.innerWidth, window.innerHeight ); + document.body.appendChild( renderer.domElement ); -var scene = new THREE.Scene(); + var scene = new THREE.Scene(); -var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ); + var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 ); -var controls = new THREE.OrbitControls( camera, renderer.domElement ); + var controls = new OrbitControls( camera, renderer.domElement ); -//controls.update() must be called after any manual changes to the camera's transform -camera.position.set( 0, 20, 100 ); -controls.update(); + //controls.update() must be called after any manual changes to the camera's transform + camera.position.set( 0, 20, 100 ); + controls.update(); -function animate() { + function animate() { - requestAnimationFrame( animate ); + requestAnimationFrame( animate ); - // required if controls.enableDamping or controls.autoRotate are set to true - controls.update(); + // required if controls.enableDamping or controls.autoRotate are set to true + controls.update(); - renderer.render( scene, camera ); + renderer.render( scene, camera ); -} + } +

    例子

    + +

    [example:misc_controls_orbit misc / controls / orbit ]

    +

    Constructor

    [name]( [param:Camera object], [param:HTMLDOMElement domElement] )

    - [page:Camera object]: (required) The camera to be controlled. The camera must not be a child of another object, unless that object is the scene itself.

    + [page:Camera object]: (必须)将要被控制的相机。该相机不允许是其他任何对象的子级,除非该对象是场景自身。

    - [page:HTMLDOMElement domElement]: (optional) The HTML element used for event listeners. By default this is the whole document, - however if you only want the controls to work over a specific element (e.g. the canvas) you can specify that here. + [page:HTMLDOMElement domElement]: The HTML element used for event listeners.

    @@ -65,72 +65,71 @@

    Properties

    [property:Boolean autoRotate]

    - Set to true to automatically rotate around the target.
    Note that if this is enabled, you must call [page:.update] - () in your animation loop. + 将其设为true,以自动围绕目标旋转。
    + 请注意,如果它被启用,你必须在你的动画循环里调用[page:.update]()。

    [property:Float autoRotateSpeed]

    - How fast to rotate around the target if [property:Boolean autoRotate] is true. Default is 2.0, which equates to 30 seconds - per rotation at 60fps.
    Note that if [property:Boolean autoRotate] is enabled, you must call [page:.update] - () in your animation loop. + 当[property:Boolean autoRotate]为true时,围绕目标旋转的速度将有多快,默认值为2.0,相当于在60fps时每旋转一次需要30秒。
    + 请注意,如果[property:Boolean autoRotate]被启用,你必须在你的动画循环里调用[page:.update]()。

    [property:Float dampingFactor]

    - The damping inertia used if [property:Boolean enableDamping] is set to true.
    Note that for this to work, you must - call [page:.update] () in your animation loop. + 当[property:Boolean enableDamping]设置为true的时候,阻尼惯性有多大。
    + 请注意,要使得这一值生效,你必须在你的动画循环里调用[page:.update]()。

    [property:HTMLDOMElement domElement]

    - The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will - not set up new event listeners. Default is the whole document. + 用于监听鼠标事件或触摸事件的HTMLDOMElement(DOM元素)。该值必须在构造函数中进行传入; + 在此更改它将不会设置新的事件监听器

    [property:Boolean enabled]

    - Whether or not the controls are enabled. + 控制器是否被启用。

    [property:Boolean enableDamping]

    - Set to true to enable damping (inertia), which can be used to give a sense of weight to the controls. Default is false.
    - Note that if this is enabled, you must call [page:.update] () in your animation loop. + 将其设置为true以启用阻尼(惯性),这将给控制器带来重量感。默认值为false。
    + 请注意,如果该值被启用,你将必须在你的动画循环里调用[page:.update]()。

    [property:Boolean enableKeys]

    - Enable or disable the use of keyboard controls. + 启用或禁用键盘控制。

    [property:Boolean enablePan]

    - Enable or disable camera panning. Default is true. + 启用或禁用摄像机平移,默认为true。

    [property:Boolean enableRotate]

    - Enable or disable horizontal and vertical rotation of the camera. Default is true.
    - Note that it is possible to disable a single axis by setting the min and max of the - [page:.minPolarAngle polar angle] or [page:.minAzimuthAngle azimuth angle] to the same value, - which will cause the vertical or horizontal rotation to be fixed at that value. + 启用或禁用摄像机水平或垂直旋转。默认值为true。
    + 请注意,可以通过将[page:.minPolarAngle polar angle]或者[page:.minAzimuthAngle azimuth angle] + 的min和max设置为相同的值来禁用单个轴, + 这将使得水平旋转或垂直旋转固定为所设置的值。

    [property:Boolean enableZoom]

    - Enable or disable zooming (dollying) of the camera. + 启用或禁用摄像机的缩放。

    [property:Float keyPanSpeed]

    - How fast to pan the camera when the keyboard is used. Default is 7.0 pixels per keypress. + 当使用键盘按键的时候,相机平移的速度有多快。默认值为每次按下按键时平移7像素。

    [property:Object keys]

    - This object contains references to the keycodes for controlling camera panning. Default is the 4 arrow keys. + 这一对象包含了用于控制相机平移的按键代码的引用。默认值为4个箭头(方向)键。 controls.keys = { LEFT: 37, //left arrow @@ -138,109 +137,120 @@

    [property:Object keys]

    RIGHT: 39, // right arrow BOTTOM: 40 // down arrow } - See [link:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode this page] for a full - list of keycodes. +
    请参阅[link:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode this page]来查看所有按键的代码列表。

    [property:Float maxAzimuthAngle]

    - How far you can orbit horizontally, upper limit. Range is - Math.PI to Math.PI ( or Infinity for no limit ) and default is - Infinity; + 你能够水平旋转的角度的上限,范围是-Math.PI到Math.PI(或Infinity无限制), + 其默认值为Infinity。

    [property:Float maxDistance]

    - How far you can dolly out ( [page:PerspectiveCamera] only ). Default is Infinity. + 你能够将相机向外移动多少(仅适用于[page:PerspectiveCamera]),其默认值为Infinity。

    [property:Float maxPolarAngle]

    - How far you can orbit vertically, upper limit. Range is 0 to Math.PI radians, and default is Math.PI. + 你能够垂直旋转的角度的上限,范围是0到Math.PI,其默认值为Math.PI。

    [property:Float maxZoom]

    - How far you can zoom out ( [page:OrthographicCamera] only ). Default is Infinity. + 你能够将相机缩小多少( 仅适用于[page:OrthographicCamera] only ),其默认值为Infinity。

    [property:Float minAzimuthAngle]

    - How far you can orbit horizontally, lower limit. Range is - Math.PI to Math.PI ( or - Infinity for no limit ) and default - is - Infinity; + 你能够水平旋转的角度的下限,范围是-Math.PI到Math.PI(或-Infinity无限制), + 其默认值为-Infinity。

    [property:Float minDistance]

    - How far you can dolly in ( [page:PerspectiveCamera] only ). Default is 0. + 你能够将相机向内移动多少(仅适用于[page:PerspectiveCamera]),其默认值为0。

    [property:Float minPolarAngle]

    - How far you can orbit vertically, lower limit. Range is 0 to Math.PI radians, and default is 0. + 你能够垂直旋转的角度的下限,范围是0到Math.PI,其默认值为0。

    [property:Float minZoom]

    - How far you can zoom in ( [page:OrthographicCamera] only ). Default is 0. + 你能够将相机放大多少( 仅适用于[page:OrthographicCamera] ),其默认值为0。

    [property:Object mouseButtons]

    - This object contains references to the mouse buttons used for the controls. + 这一对象包含了对用于控制的鼠标按钮的引用。 controls.mouseButtons = { - LEFT: THREE.MOUSE.LEFT, - MIDDLE: THREE.MOUSE.MIDDLE, - RIGHT: THREE.MOUSE.RIGHT + LEFT: THREE.MOUSE.ROTATE, + MIDDLE: THREE.MOUSE.DOLLY, + RIGHT: THREE.MOUSE.PAN }

    [property:Camera object]

    - The camera being controlled. + 正被控制的摄像机。

    [property:Float panSpeed]

    - Speed of panning. Default is 1. + 位移的速度,其默认值为1。

    [property:Vector3 position0]

    - Used internally by the [method:saveState] and [method:reset] methods. + 由[method:saveState]和[method:reset]方法在内部使用。

    [property:Float rotateSpeed]

    - Speed of rotation. Default is 1. + 旋转的速度,其默认值为1.

    [property:Boolean screenSpacePanning]

    - Defines how the camera's position is translated when panning. If true, the camera pans in screen space. - Otherwise, the camera pans in the plane orthogonal to the camera's up direction. Default is false. + 定义当平移的时候摄像机的位置将如何移动。如果为true,摄像机将在屏幕空间内平移。 + 否则,摄像机将在与摄像机向上方向垂直的平面中平移。其默认值为false。

    [property:Vector3 target0]

    - Used internally by the [method:saveState] and [method:reset] methods. + 由[method:saveState]和[method:reset]方法在内部使用。

    [property:Vector3 target]

    - The focus point of the controls, the [page:.object] orbits around this. It can be updated manually at any point to change - the focus of the controls. + 控制器的焦点,[page:.object]的轨道围绕它运行。 + 它可以在任何时候被手动更新,以更改控制器的焦点。 +

    + +

    [property:Object touches]

    +

    + This object contains references to the touch actions used by the controls. + +controls.touches = { + ONE: THREE.TOUCH.ROTATE, + TWO: THREE.TOUCH.DOLLY_PAN +} +

    [property:Float zoom0]

    - Used internally by the [method:saveState] and [method:reset] methods. + 由[method:saveState]和[method:reset]方法在内部使用。

    [property:Float zoomSpeed]

    + 摄像机缩放的速度,其默认值为1。 Speed of zooming / dollying. Default is 1.

    @@ -250,37 +260,39 @@

    Methods

    [method:null dispose] ()

    - Remove all the event listeners. + 移除所有的事件监听。

    [method:radians getAzimuthalAngle] ()

    - Get the current horizontal rotation, in radians. + 获得当前的水平旋转,单位为弧度。

    [method:radians getPolarAngle] ()

    - Get the current vertical rotation, in radians. + 获得当前的垂直旋转,单位为弧度。

    [method:null reset] ()

    - Reset the controls to their state from either the last time the [page:.saveState] was called, or the initial state. + 将控制器重置为上次调用[page:.saveState]时的状态,或者初始状态。

    [method:null saveState] ()

    - Save the current state of the controls. This can later be recovered with [page:.reset]. + 保存当前控制器的状态。这一状态可在之后由[page:.reset]所恢复。

    [method:Boolean update] ()

    - Update the controls. Must be called after any manual changes to the camera's transform, - or in the update loop if [page:.autoRotate] or [page:.enableDamping] are set. + 更新控制器。必须在摄像机的变换发生任何手动改变后调用, + 或如果[page:.autoRotate]或[page:.enableDamping]被设置时,在update循环里调用。

    -

    Source

    +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js examples/js/controls/OrbitControls.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/OrbitControls.js examples/jsm/controls/OrbitControls.js] +

    diff --git a/docs/examples/zh/controls/PointerLockControls.html b/docs/examples/zh/controls/PointerLockControls.html new file mode 100644 index 00000000000000..e8f02c1ba16f71 --- /dev/null +++ b/docs/examples/zh/controls/PointerLockControls.html @@ -0,0 +1,150 @@ + + + + + + + + + + + [page:EventDispatcher] → + +

    [name]

    + +

    + The implementation of this class is based on the [link:https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API Pointer Lock API]. + [name] is a perfect choice for first person 3D games. +

    + +

    代码示例

    + + + var controls = new PointerLockControls( camera, document.body ); + + // add event listener to show/hide a UI (e.g. the game's menu) + + controls.addEventListener( 'lock', function () { + + menu.style.display = 'none'; + + } ); + + controls.addEventListener( 'unlock', function () { + + menu.style.display = 'block'; + + } ); + + +

    例子

    + +

    [example:misc_controls_pointerlock misc / controls / pointerlock ]

    + +

    Constructor

    + +

    [name]( [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    change

    +

    + Fires when the user moves the mouse. +

    + +

    lock

    +

    + Fires when the pointer lock status is "locked" (in other words: the mouse is captured). +

    + +

    unlock

    +

    + Fires when the pointer lock status is "unlocked" (in other words: the mouse is not captured anymore). +

    + +

    Properties

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + + +

    [property:Boolean isLocked]

    +

    + Whether or not the controls are locked. +

    + +

    Methods

    + +

    See the base [page:EventDispatcher] class for common methods.

    + +

    [method:null connect] ()

    +

    + Adds the event listeners of the controls. +

    + +

    [method:null disconnect] ()

    +

    + Removes the event listeners of the controls. +

    + +

    [method:Vector3 getDirection] ( [param:Vector3 target] )

    +

    +

    + [page:Vector3 target]: The target vector. +

    +

    + Returns the look direction of the camera. +

    +

    + +

    [method:null lock] ()

    +

    + Activates the pointer lock. +

    + +

    [method:null moveForward] ( [param:Number distance] )

    +

    +

    + [page:Number distance]: The signed distance. +

    +

    + Moves the camera forward parallel to the xz-plane. Assumes camera.up is y-up. +

    +

    + +

    [method:null moveRight] ( [param:Number distance] )

    +

    +

    + [page:Number distance]: The signed distance. +

    +

    + Moves the camera sidewards parallel to the xz-plane. +

    +

    + +

    [method:null unlock] ()

    +

    + Exits the pointer lock. +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/PointerLockControls.js examples/jsm/controls/PointerLockControls.js] +

    + + diff --git a/docs/examples/zh/controls/TrackballControls.html b/docs/examples/zh/controls/TrackballControls.html new file mode 100644 index 00000000000000..de7551fd75550c --- /dev/null +++ b/docs/examples/zh/controls/TrackballControls.html @@ -0,0 +1,207 @@ + + + + + + + + + + + [page:EventDispatcher] → + +

    [name]

    + +

    +

    + [name] is similar to [page:OrbitControls]. However, it does not maintain a constant camera [page:Object3D.up up] vector. + That means if the camera orbits over the “north” and “south” poles, it does not flip to stay "right side up". +

    +

    + +

    例子

    + +

    [example:misc_controls_trackball misc / controls / trackball ]

    + +

    Constructor

    + +

    [name]( [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    change

    +

    + Fires when the camera has been transformed by the controls. +

    + +

    start

    +

    + Fires when an interaction (e.g. touch) was initiated. +

    + +

    end

    +

    + Fires when an interaction has finished. +

    + +

    Properties

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Number dynamicDampingFactor]

    +

    + Defines the intensity of damping. Only considered if [page:.staticMoving staticMoving] is set to *false*. Default is *0.2*. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:Array keys]

    +

    + This array holds keycodes for controlling interactions. +

      +
    • When the first defined key is pressed, all mouse interactions (left, middle, right) performs orbiting.
    • +
    • When the second defined key is pressed, all mouse interactions (left, middle, right) performs zooming.
    • +
    • When the third defined key is pressed, all mouse interactions (left, middle, right) performs panning.
    • +
    + Default is *65, 83, 68* which represents A, S, D. +

    + +

    [property:Number maxDistance]

    +

    + How far you can zoom in. Default is *Infinity*. +

    + +

    [property:Number minDistance]

    +

    + How far you can zoom in. Default is *0*. +

    + +

    + [property:Object mouseButtons]

    +

    + This object contains references to the mouse actions used by the controls. +

      +
    • .LEFT is assinged with *THREE.MOUSE.ROTATE*
    • +
    • .MIDDLE is assinged with *THREE.MOUSE.ZOOM*
    • +
    • .RIGHT is assinged with *THREE.MOUSE.PAN*
    • +
    +

    + +

    [property:Boolean noPan]

    +

    + Whether or not panning is disabled. Default is *false*. +

    + +

    [property:Boolean noRotate]

    +

    + Whether or not rotation is disabled. Default is *false*. +

    + +

    [property:Boolean noZoom]

    +

    + Whether or not zooming is disabled. Default is *false*. +

    + +

    [property:Camera object]

    +

    + The camera being controlled. +

    + +

    [property:Number panSpeed]

    +

    + The zoom speed. Default is *0.3*. +

    + +

    [property:Number rotateSpeed]

    +

    + The rotation speed. Default is *1.0*. +

    + +

    [property:Object screen]

    +

    + Represents the properties of the screen. Automatically set when [page:.handleResize handleResize]() is called. +

      +
    • left: Represents the offset in pixels to the screen's left boundary.
    • +
    • top: Represents the offset in pixels to the screen's top boundary.
    • +
    • width: Represents the screen width in pixels.
    • +
    • height: Represents the screen height in pixels.
    • +
    +

    + +

    [property:Boolean staticMoving]

    +

    + Whether or not damping is disabled. Default is *false*. +

    + +

    [property:Number zoomSpeed]

    +

    + The zoom speed. Default is *1.2*. +

    + +

    Methods

    + +

    [method:null checkDistances] ()

    +

    + Ensures the controls stay in the range [minDistance, maxDistance]. Called by [page:.update update](). +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:null handleResize] ()

    +

    + Should be called if the application window is resized. +

    + +

    [method:null panCamera] ()

    +

    + Performs panning if necessary. Called by [page:.update update](). +

    + +

    [method:null reset] ()

    +

    + Resets the controls to its initial state. +

    + +

    [method:null rotateCamera] ()

    +

    + Rotates the camera if necessary. Called by [page:.update update](). +

    + +

    [method:null update] ()

    +

    + Updates the controls. Usually called in the animation loop. +

    + +

    [method:null zoomCamera] ()

    +

    + Performs zooming if necessary. Called by [page:.update update](). +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/TrackballControls.js examples/jsm/controls/TrackballControls.js] +

    + + diff --git a/docs/examples/zh/controls/TransformControls.html b/docs/examples/zh/controls/TransformControls.html new file mode 100644 index 00000000000000..1020ab23c7a507 --- /dev/null +++ b/docs/examples/zh/controls/TransformControls.html @@ -0,0 +1,226 @@ + + + + + + + + + + + [page:Object3D] → + +

    [name]

    + +

    + This class can be used to transform objects in 3D space by adapting a similar interaction model of DCC tools like Blender. + Unlike other controls, it is not intended to transform the scene's camera.

    + + [name] expects that its attached 3D object is part of the scene graph. +

    + +

    例子

    + +

    [example:misc_controls_transform misc / controls / transform ]

    + +

    Constructor

    + +

    [name]( [param:Camera camera], [param:HTMLDOMElement domElement] )

    +

    +

    + [page:Camera camera]: The camera of the rendered scene. +

    +

    + [page:HTMLDOMElement domElement]: The HTML element used for event listeners. +

    +

    + Creates a new instance of [name]. +

    +

    + +

    Events

    + +

    change

    +

    + Fires if any type of change (object or property change) is performed. Property changes + are separate events you can add event listeners to. The event type is "propertyname-changed". +

    + +

    mouseDown

    +

    + Fires if a pointer (mouse/touch) becomes active. +

    + +

    mouseUp

    +

    + Fires if a pointer (mouse/touch) is no longer active. +

    + +

    objectChange

    +

    + Fires if the controlled 3D object is changed. +

    + +

    Properties

    + +

    See the base [page:Object3D] class for common properties.

    + +

    [property:String axis]

    +

    + The current transformation axis. +

    + +

    [property:Camera camera]

    +

    + The camera of the rendered scene. +

    + +

    [property:HTMLDOMElement domElement]

    +

    + The HTMLDOMElement used to listen for mouse / touch events. This must be passed in the constructor; changing it here will + not set up new event listeners. +

    + +

    [property:Boolean dragging]

    +

    + Whether or not dragging is currently performed. Read-only property. +

    + +

    [property:Boolean enabled]

    +

    + Whether or not the controls are enabled. +

    + +

    [property:String mode]

    +

    + The current transformation mode. Possible values are "translate", "rotate" and "scale". Default is *translate*. +

    + +

    [property:Object3D object]

    +

    + The 3D object being controlled. +

    + +

    [property:Number rotationSnap]

    +

    + By default, 3D objects are continously rotated. If you set this property to a numeric value (radians), you can define in which + steps the 3D object should be rotated. Deault is *null*. +

    + +

    [property:Boolean showX]

    +

    + Whether or not the x-axis helper should be visible. Default is *true*. +

    + +

    [property:Boolean showY]

    +

    + Whether or not the y-axis helper should be visible. Default is *true*. +

    + +

    [property:Boolean showZ]

    +

    + Whether or not the z-axis helper should be visible. Default is *true*. +

    + +

    [property:Number size]

    +

    + The size of the helper UI (axes/planes). Default is *1*. +

    + +

    [property:String space]

    +

    + Defines in which coordinate space transformations should be performed. Possible values are "world" and "local". Default is *world*. +

    + +

    [property:Number translationSnap]

    +

    + By default, 3D objects are continously translated. If you set this property to a numeric value (world units), you can define in which + steps the 3D object should be translated. Deault is *null*. +

    + +

    Methods

    + +

    See the base [page:Object3D] class for common methods.

    + +

    [method:TransformControls attach] ( [param:Object3D object] )

    +

    +

    + [page:Object3D object]: The 3D object that should be transformed. +

    +

    + Sets the 3D object that should be transformed and ensures the controls UI is visible. +

    +

    + +

    [method:TransformControls detach] ()

    +

    + Removes the current 3D object from the controls and makes the helper UI is invisible. +

    + +

    [method:null dispose] ()

    +

    + Should be called if the controls is no longer required. +

    + +

    [method:String getMode] ()

    +

    + Returns the transformation mode. +

    + +

    [method:null setMode] ( [param:String mode] )

    +

    +

    + [page:String mode]: The transformation mode. +

    +

    + Sets the transformation mode. +

    +

    + +

    [method:null setRotationSnap] ( [param:Number rotationSnap] )

    +

    +

    + [page:Number rotationSnap]: The rotation snap. +

    +

    + Sets the rotation snap. +

    +

    + +

    [method:null setSize] ( [param:Number size] )

    +

    +

    + [page:Number size]: The size of the helper UI. +

    +

    + Sets the size of the helper UI. +

    +

    + +

    [method:null setSpace] ( [param:String space] )

    +

    +

    + [page:String space]: The coordinate space in which transformations are applied. +

    +

    + Sets the coordinate space in which transformations are applied. +

    +

    + +

    [method:null setTranslationSnap] ( [param:Number translationSnap] )

    +

    +

    + [page:Number translationSnap]: The translation snap. +

    +

    + Sets the translation snap. +

    +

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/TransformControls.js examples/jsm/controls/TransformControls.js] +

    + + diff --git a/docs/examples/zh/exporters/ColladaExporter.html b/docs/examples/zh/exporters/ColladaExporter.html index f43949e5b8645f..3e1b5822c848b5 100644 --- a/docs/examples/zh/exporters/ColladaExporter.html +++ b/docs/examples/zh/exporters/ColladaExporter.html @@ -18,11 +18,11 @@

    [name]

    This exporter only supports exporting geometry, materials, textures, and scene hierarchy.

    -

    Example

    +

    代码示例

    // Instantiate an exporter - var exporter = new THREE.ColladaExporter(); + var exporter = new ColladaExporter(); // Parse the input and generate the ply output var data = exporter.parse( scene, null, options ); @@ -76,6 +76,8 @@

    [method:null parse]( [param:Object3D input], [param:Function onCompleted], [

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/ColladaExporter.js examples/js/exporters/ColladaExporter.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/ColladaExporter.js examples/jsm/exporters/ColladaExporter.js] +

    diff --git a/docs/examples/zh/exporters/GLTFExporter.html b/docs/examples/zh/exporters/GLTFExporter.html index a79124f140a22a..f23f54554f5df9 100644 --- a/docs/examples/zh/exporters/GLTFExporter.html +++ b/docs/examples/zh/exporters/GLTFExporter.html @@ -34,11 +34,11 @@

    Extensions

  • KHR_texture_transform
  • -

    Example

    +

    代码示例

    // Instantiate a exporter - var exporter = new THREE.GLTFExporter(); + var exporter = new GLTFExporter(); // Parse the input and generate the glTF output exporter.parse( scene, function ( gltf ) { @@ -47,7 +47,11 @@

    Example

    }, options );
    - [example:misc_exporter_gltf] +

    例子

    + +

    + [example:misc_exporter_gltf] +

    Constructor

    @@ -94,6 +98,7 @@

    [method:null parse]( [param:Object3D input], [param:Function onCompleted], [
  • truncateDrawRange - bool. Export just the attributes within the drawRange, if defined, instead of exporting the whole array. Default is true.
  • binary - bool. Export in binary (.glb) format, returning an ArrayBuffer. Default is false.
  • embedImages - bool. Export with images embedded into the glTF asset. Default is true.
  • +
  • maxTextureSize - int. Restricts the image maximum size (both width and height) to the given value. This option works only if embedImages is true. Default is Infinity.
  • animations - Array<[page:AnimationClip AnimationClip]>. List of animations to be included in the export.
  • forceIndices - bool. Generate indices for non-index geometry and export with them. Default is false.
  • forcePowerOfTwoTextures - bool. Export with images resized to POT size. This option works only if embedImages is true. Default is false.
  • @@ -106,6 +111,8 @@

    [method:null parse]( [param:Object3D input], [param:Function onCompleted], [

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/GLTFExporter.js examples/js/exporters/GLTFExporter.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/GLTFExporter.js examples/jsm/exporters/GLTFExporter.js] +

    diff --git a/docs/examples/zh/exporters/PLYExporter.html b/docs/examples/zh/exporters/PLYExporter.html index 6b4672b1c9bc90..945ce75484b983 100644 --- a/docs/examples/zh/exporters/PLYExporter.html +++ b/docs/examples/zh/exporters/PLYExporter.html @@ -19,11 +19,11 @@

    [name]

    uv coordinates. No textures or texture references are saved.

    -

    Example

    +

    代码示例

    // Instantiate an exporter - var exporter = new THREE.PLYExporter(); + var exporter = new PLYExporter(); // Parse the input and generate the ply output var data = exporter.parse( scene, options ); @@ -59,6 +59,8 @@

    [method:null parse]( [param:Object3D input], [param:Function onDone], [param

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/PLYExporter.js examples/js/exporters/PLYExporter.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/exporters/PLYExporter.js examples/jsm/exporters/PLYExporter.js] +

    diff --git a/docs/examples/zh/geometries/ConvexBufferGeometry.html b/docs/examples/zh/geometries/ConvexBufferGeometry.html index dc33ecf1773765..abe7ec9f43dfdf 100644 --- a/docs/examples/zh/geometries/ConvexBufferGeometry.html +++ b/docs/examples/zh/geometries/ConvexBufferGeometry.html @@ -16,32 +16,18 @@

    [name]

    [name] can be used to generate a convex hull for a given array of 3D points. The average time complexity for this task is considered to be O(nlog(n)).

    - - -

    Example

    - -

    [example:webgl_geometry_convex geometry / convex ]

    - - var geometry = new THREE.ConvexBufferGeometry( points ); + var geometry = new ConvexBufferGeometry( points ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); +

    例子

    + +

    [example:webgl_geometry_convex geometry / convex ]

    +

    Constructor

    [name]( [param:Array points] )

    @@ -52,6 +38,8 @@

    [name]( [param:Array points] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/geometries/ConvexGeometry.js examples/js/geometries/ConvexGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/ConvexGeometry.js examples/jsm/geometries/ConvexGeometry.js] +

    diff --git a/docs/examples/zh/geometries/ConvexGeometry.html b/docs/examples/zh/geometries/ConvexGeometry.html index 1ff026b3b0d4bb..83ebfe787e952a 100644 --- a/docs/examples/zh/geometries/ConvexGeometry.html +++ b/docs/examples/zh/geometries/ConvexGeometry.html @@ -15,32 +15,18 @@

    [name]

    [name] can be used to generate a convex hull for a given array of 3D points. The average time complexity for this task is considered to be O(nlog(n)).

    - - -

    Example

    - -

    [example:webgl_geometry_convex geometry / convex ]

    - - var geometry = new THREE.ConvexGeometry( points ); + var geometry = new ConvexGeometry( points ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); +

    例子

    + +

    [example:webgl_geometry_convex geometry / convex ]

    +

    Constructor

    [name]( [param:Array points] )

    @@ -51,6 +37,8 @@

    [name]( [param:Array points] )

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/geometries/ConvexGeometry.js examples/js/geometries/ConvexGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/ConvexGeometry.js examples/jsm/geometries/ConvexGeometry.js] +

    diff --git a/docs/examples/zh/geometries/DecalGeometry.html b/docs/examples/zh/geometries/DecalGeometry.html index 3dae0c950f2ffe..82118c84e154c9 100644 --- a/docs/examples/zh/geometries/DecalGeometry.html +++ b/docs/examples/zh/geometries/DecalGeometry.html @@ -14,32 +14,19 @@

    [name]

    [name] can be used to create a decal mesh that serves different kinds of purposes e.g. adding unique details to models, performing dynamic visual environmental changes or covering seams.

    - - -

    Example

    - -

    [example:webgl_decals decals ]

    - - var geometry = new THREE.DecalGeometry( mesh, position, orientation, size ); + + var geometry = new DecalGeometry( mesh, position, orientation, size ); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); +

    例子

    + +

    [example:webgl_decals WebGL / decals]

    +

    Constructor

    [name]( [param:Mesh mesh], [param:Vector3 position], [param:Euler orientation], [param:Vector3 size] )

    @@ -52,6 +39,8 @@

    [name]( [param:Mesh mesh], [param:Vector3 position], [param:Euler orientatio

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/geometries/DecalGeometry.js examples/js/geometries/DecalGeometry.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/geometries/DecalGeometry.js examples/jsm/geometries/DecalGeometry.js] +

    diff --git a/docs/api/zh/helpers/FaceNormalsHelper.html b/docs/examples/zh/helpers/FaceNormalsHelper.html similarity index 88% rename from docs/api/zh/helpers/FaceNormalsHelper.html rename to docs/examples/zh/helpers/FaceNormalsHelper.html index 5c42854f9ebabb..25b0320417b163 100644 --- a/docs/api/zh/helpers/FaceNormalsHelper.html +++ b/docs/examples/zh/helpers/FaceNormalsHelper.html @@ -14,29 +14,30 @@

    [name]

    渲染箭头辅助对象 [page:ArrowHelper arrows] 来模拟面 [page:Face3 face] 的法线. - 需要所有面 [page:Face3 faces] 都指定了法线 或 + 需要所有面 [page:Face3 faces] 都指定了法线 或 通过 [page:Geometry.computeFaceNormals computeFaceNormals] 方法计算面的法线.

    注意:仅几何体为 [page:Geometry] 类型的对象能正常运行. 对于 [page:BufferGeometry] 类型几何体的对象请使用 [page:VertexNormalsHelper] 代替.

    - -

    例子

    - -
    [example:webgl_helpers WebGL / helpers]
    +

    代码示例

    geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 ); material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); box = new THREE.Mesh( geometry, material ); - helper = new THREE.FaceNormalsHelper( box, 2, 0x00ff00, 1 ); + helper = new FaceNormalsHelper( box, 2, 0x00ff00, 1 ); scene.add( box ); scene.add( helper ); +

    例子

    + +
    [example:webgl_helpers WebGL / helpers]
    +

    构造函数

    @@ -76,6 +77,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/FaceNormalsHelper.js examples/jsm/helpers/FaceNormalsHelper.js] +

    diff --git a/docs/examples/zh/helpers/LightProbeHelper.html b/docs/examples/zh/helpers/LightProbeHelper.html new file mode 100644 index 00000000000000..fdc321046f7e57 --- /dev/null +++ b/docs/examples/zh/helpers/LightProbeHelper.html @@ -0,0 +1,62 @@ + + + + + + + + + + + [page:Object3D] → [page:Mesh] → + +

    [name]

    + +

    + Renders a sphere to visualize a light probe in the scene. +

    + +

    代码示例

    + + + var helper = new LightProbeHelper( lightProbe, 1 ); + scene.add( helper ); + + +

    例子

    + +

    [example:webgl_lightprobe_cubecamera WebGL / lightprobe / cubecamera]

    + +

    Constructor

    + + +

    [name]( [param:LightProbe lightProbe], [param:Number size] )

    +

    + [page:LightProbe lightProbe] -- the light probe.
    + [page:Number size] -- size of the helper sphere +

    + + +

    Properties

    +

    See the base [page:Mesh] class for common properties.

    + +

    [property:LightProbe lightProbe]

    +

    The light probe.

    + +

    [property:Number size]

    +

    The size of the helper sphere.

    + +

    Methods

    +

    See the base [page:Mesh] class for common methods.

    + +

    [method:null dispose]()

    +

    Frees internal resources.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/LightProbeHelper.js examples/jsm/helpers/LightProbeHelper.js] +

    + + diff --git a/docs/api/zh/helpers/PositionalAudioHelper.html b/docs/examples/zh/helpers/PositionalAudioHelper.html similarity index 79% rename from docs/api/zh/helpers/PositionalAudioHelper.html rename to docs/examples/zh/helpers/PositionalAudioHelper.html index 7c5892758a8614..5bdc4c98b53418 100644 --- a/docs/api/zh/helpers/PositionalAudioHelper.html +++ b/docs/examples/zh/helpers/PositionalAudioHelper.html @@ -14,19 +14,17 @@

    [name]

    这一辅助对象显示[page:PositionalAudio]的方向锥。

    -

    示例

    - -
    [example:webaudio_orientation webaudio / orientation ]
    - -

    示例代码

    +

    代码示例

    -var positionalAudio = new THREE.PositionalAudio( listener ); -positionalAudio.setDirectionalCone( 180, 230, 0.1 ); + var positionalAudio = new THREE.PositionalAudio( listener ); + positionalAudio.setDirectionalCone( 180, 230, 0.1 ); -var helper = new PositionalAudioHelper( positionalAudio ); -positionalAudio.add( helper ); + var helper = new PositionalAudioHelper( positionalAudio ); + positionalAudio.add( helper ); +

    例子

    +
    [example:webaudio_orientation webaudio / orientation ]

    构造函数

    @@ -68,6 +66,8 @@

    [method:null update]()

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/PositionalAudioHelper.js examples/jsm/helpers/PositionalAudioHelper.js] +

    diff --git a/docs/api/zh/helpers/RectAreaLightHelper.html b/docs/examples/zh/helpers/RectAreaLightHelper.html similarity index 81% rename from docs/api/zh/helpers/RectAreaLightHelper.html rename to docs/examples/zh/helpers/RectAreaLightHelper.html index 523c391a8ab9c9..52696d9d9675b9 100644 --- a/docs/api/zh/helpers/RectAreaLightHelper.html +++ b/docs/examples/zh/helpers/RectAreaLightHelper.html @@ -16,14 +16,12 @@

    [name]

    创建一个表示 [page:RectAreaLight] 的辅助对象.

    -

    例子

    +

    代码示例

    -var light = new THREE.RectAreaLight( 0xffffbb, 1.0, 5, 5 ); - -var helper = new THREE.RectAreaLightHelper( light ); - -scene.add( helper ); + var light = new THREE.RectAreaLight( 0xffffbb, 1.0, 5, 5 ); + var helper = new RectAreaLightHelper( light ); + scene.add( helper ); @@ -62,6 +60,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/RectAreaLightHelper.js examples/jsm/helpers/RectAreaLightHelper.js] +

    diff --git a/docs/api/zh/helpers/VertexNormalsHelper.html b/docs/examples/zh/helpers/VertexNormalsHelper.html similarity index 84% rename from docs/api/zh/helpers/VertexNormalsHelper.html rename to docs/examples/zh/helpers/VertexNormalsHelper.html index 9913f3c971c5d2..8fead40566cfa7 100644 --- a/docs/api/zh/helpers/VertexNormalsHelper.html +++ b/docs/examples/zh/helpers/VertexNormalsHelper.html @@ -20,21 +20,23 @@

    [name]

    不像面法线辅助对象 [page:FaceNormalsHelper], 该辅助对象在 [page:BufferGeometry] 上也能正常运行.

    -

    例子

    - - [example:webgl_helpers WebGL / helpers] +

    代码示例

    - var geometry = new THREE.BoxGeometry( 10, 10, 10, 2, 2, 2 ); + var geometry = new THREE.BoxBufferGeometry( 10, 10, 10, 2, 2, 2 ); var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); var box = new THREE.Mesh( geometry, material ); - var helper = new THREE.VertexNormalsHelper( box, 2, 0x00ff00, 1 ); + var helper = new VertexNormalsHelper( box, 2, 0x00ff00, 1 ); scene.add( box ); scene.add( helper ); +

    例子

    +

    + [example:webgl_helpers WebGL / helpers] +

    构造函数

    @@ -74,6 +76,8 @@

    [method:null update]()

    源码

    - [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/VertexNormalsHelper.js examples/jsm/helpers/VertexNormalsHelper.js] +

    diff --git a/docs/examples/zh/helpers/VertexTangentsHelper.html b/docs/examples/zh/helpers/VertexTangentsHelper.html new file mode 100644 index 00000000000000..f5094e223235aa --- /dev/null +++ b/docs/examples/zh/helpers/VertexTangentsHelper.html @@ -0,0 +1,83 @@ + + + + + + + + + + + [page:Object3D] → [page:Line] → [page:LineSegments] → + +

    [name]

    + +

    + Renders arrows to visualize an object's vertex tangent vectors. + Requires that tangents have been specified in a [page:BufferAttribute custom attribute] or + have been calculated using [page:BufferGeometryUtils.computeTangents computeTangents].

    + + This helper supports [page:BufferGeometry] only. +

    + +

    代码示例

    + + + var geometry = new THREE.BoxBufferGeometry( 10, 10, 10, 2, 2, 2 ); + var material = new THREE.MeshNormalMaterial(); + var box = new THREE.Mesh( geometry, material ); + + var helper = new VertexTangentsHelper( box, 1, 0x00ffff, 1 ); + + scene.add( box ); + scene.add( helper ); + + +

    例子

    +

    + [example:webgl_helpers WebGL / helpers] +

    + +

    Constructor

    + + +

    [name]( [param:Object3D object], [param:Number size], [param:Hex color], [param:Number linewidth] )

    +

    + [page:Object3D object] -- object for which to render vertex tangents.
    + [page:Number size] -- (optional) length of the arrows. Default is *1*.
    + [page:Hex color] -- hex color of the arrows. Default is 0x00ffff.
    + [page:Number linewidth] -- (optional) width of the arrow lines. Default is *1*. (Setting lineWidth is currently not supported.) +

    + + +

    Properties

    +

    See the base [page:LineSegments] class for common properties.

    + +

    [property:object matrixAutoUpdate]

    +

    + See [page:Object3D.matrixAutoUpdate]. Set to *false* here as the helper is using the + objects's [page:Object3D.matrixWorld matrixWorld]. +

    + +

    [property:Object3D object]

    +

    The object for which the vertex tangents are being visualized.

    + +

    [property:Number size]

    +

    Length of the arrows. Default is *1*.

    + + +

    Methods

    +

    See the base [page:LineSegments] class for common methods.

    + + +

    [method:null update]()

    +

    Updates the vertex tangents preview based on the object's world transform.

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/helpers/VertexTangentsHelper.js examples/jsm/helpers/VertexTangentsHelper.js] +

    + + diff --git a/docs/examples/zh/loaders/BabylonLoader.html b/docs/examples/zh/loaders/BabylonLoader.html deleted file mode 100644 index a023ad0bc35968..00000000000000 --- a/docs/examples/zh/loaders/BabylonLoader.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - -

    [name]

    - -

    A loader for loading a .babylon resource.
    - The .babylon file format used by - Babylon.js. -

    - -

    Example

    - - - // instantiate a loader - var loader = new THREE.BabylonLoader(); - - // load a Babylon resource - loader.load( - // resource URL - 'models/babylon/skull.babylon', - // called when resource is loaded - function ( object ) { - - scene.add( object ); - - }, - // called when loading is in progress - function ( xhr ) { - - console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' ); - - }, - // called when loading has errors - function ( xhr ) { - - console.log( 'An error happened' ); - - } - ); - - - [example:webgl_loader_babylon] - -

    Constructor

    - -

    [name]( [param:LoadingManager manager] )

    -

    - [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager]. -

    -

    - Creates a new [name]. -

    - -

    Properties

    - - -

    Methods

    - -

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    -

    - [page:String url] — A string containing the path/URL of the .babylon file.
    - [page:function onLoad] — (optional) A function to be called after loading is successfully completed. The function receives the loaded [page:Object3D] as an argument.
    - [page:function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.
    - [page:function onError] — (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.
    -

    -

    - Begin loading from url and call onLoad with the parsed response content. -

    - -

    [method:Object3D parse]( [param:Object json] )

    -

    - [page:Object json] — The JSON structure to parse. -

    -

    - Parse a JSON structure and return an [page:Object3D object] or a [page:Scene scene].
    - Found objects are converted to [page:Mesh] with a [page:BufferGeometry] and a default [page:MeshPhongMaterial].
    - Lights are parsed accordingly. -

    - -

    [method:BabylonLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    - -

    Source

    - - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/BabylonLoader.js examples/js/loaders/BabylonLoader.js] - - diff --git a/docs/examples/zh/loaders/BasisTextureLoader.html b/docs/examples/zh/loaders/BasisTextureLoader.html index 433ca3b2c14674..eb80463232c594 100644 --- a/docs/examples/zh/loaders/BasisTextureLoader.html +++ b/docs/examples/zh/loaders/BasisTextureLoader.html @@ -9,6 +9,7 @@ [page:Loader] → +

    [name]

    @@ -24,15 +25,15 @@

    [name]

    This loader parallelizes the transcoding process across a configurable number of web workers, before transferring the transcoded compressed texture back to the main thread. The required WASM transcoder and JS wrapper are available from the - [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/basis examples/js/libs/basis] + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/basis examples/jsm/libs/basis] directory.

    -

    Example

    +

    代码示例

    - var basisLoader = new THREE.BasisTextureLoader(); - basisLoader.setTranscoderPath( 'examples/js/libs/basis/' ); + var basisLoader = new BasisTextureLoader(); + basisLoader.setTranscoderPath( 'examples/jsm/libs/basis/' ); basisLoader.detectSupport( renderer ); basisLoader.load( 'diffuse.basis', function ( texture ) { @@ -49,7 +50,11 @@

    Example

    } );
    - [example:webgl_loader_texture_basis] +

    例子

    + +

    + [example:webgl_loader_texture_basis] +

    Browser compatibility

    @@ -57,8 +62,8 @@

    Browser compatibility

    BasisTextureLoader transcodes input textures in '.basis' format to an appropriate compressed texture format for the target device, where possible. This allows the same source texture to be served across - desktop, Android, and iOS devices, and transcoded into DXT, ETC1, or - PVRTC1. Other output formats may be supported in the future. + desktop, Android, and iOS devices, and transcoded into ASTC, DXT, ETC1, + or PVRTC1. Other output formats may be supported in the future.

    Transcoding to PVRTC1 (for iOS) requires square power-of-two textures. @@ -81,7 +86,11 @@

    [name]( [param:LoadingManager manager] )

    Creates a new [name].

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    +

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -103,21 +112,13 @@

    [method:this detectSupport]( [param:WebGLRenderer renderer] )

    the output format for the transcoder. Must be called before loading a texture.

    -

    [method:this setCrossOrigin]( [param:String crossOrigin] )

    -

    - [page:String crossOrigin] — Options are '', 'anonymous', or 'use-credentials'. Default is 'anonymous'. -

    -

    - Sets options for CORS requests. -

    -

    [method:this setTranscoderPath]( [param:String path] )

    [page:String path] — Path to folder containing the WASM transcoder and JS wrapper.

    The WASM transcoder and JS wrapper are available from the - [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/basis examples/js/libs/basis] + [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/basis examples/jsm/libs/basis] directory.

    @@ -136,6 +137,8 @@

    [method:this dispose]()

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/BasisTextureLoader.js examples/js/loaders/BasisTextureLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/BasisTextureLoader.js examples/jsm/loaders/BasisTextureLoader.js] +

    diff --git a/docs/examples/zh/loaders/DRACOLoader.html b/docs/examples/zh/loaders/DRACOLoader.html index a1ff9af73f94dd..6f2c69e741117b 100644 --- a/docs/examples/zh/loaders/DRACOLoader.html +++ b/docs/examples/zh/loaders/DRACOLoader.html @@ -27,17 +27,17 @@

    [name]

    using Draco with glTF, an instance of DRACOLoader will be used internally by [page:GLTFLoader].

    -

    Example

    +

    代码示例

    // Instantiate a loader - var loader = new THREE.DRACOLoader(); + var loader = new DRACOLoader(); // Specify path to a folder containing WASM/JS decoding libraries. - THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' ); + loader.setDecoderPath( '/examples/jsm/libs/draco/' ); // Optional: Pre-fetch Draco WASM/JS module. - THREE.DRACOLoader.getDecoderModule(); + loader.preload(); // Load a Draco geometry loader.load( @@ -66,7 +66,11 @@

    Example

    );
    - [example:webgl_loader_draco] +

    例子

    + +

    + [example:webgl_loader_draco] +

    Browser compatibility

    @@ -90,56 +94,62 @@

    [name]( [param:LoadingManager manager] )

    Creates a new [name].

    -

    Static Methods

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    -

    [method:null setDecoderPath]( [param:String value] )

    -

    - [page:String value] — Path to folder containing the JS and WASM decoder libraries. -

    +

    Methods

    +

    See the base [page:Loader] class for common methods.

    -

    [method:null setDecoderConfig]( [param:Object config] )

    +

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    - [page:String config.type] - (Optional) "js" or "wasm".
    + [page:String url] — A string containing the path/URL of the .drc file.
    + [page:Function onLoad] — A function to be called after the loading is successfully completed.
    + [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    + [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.

    - Provides configuration for the decoder libraries. Configuration cannot be changed - after loading the decoders. + Begin loading from url and call the onLoad function with the decompressed geometry.

    -

    [method:Promise getDecoderModule]()

    +

    [method:this setDecoderPath]( [param:String value] )

    - Requests the decoder libraries, if not already loaded. + [page:String value] — Path to folder containing the JS and WASM decoder libraries.

    -

    [method:null releaseDecoderModule]()

    +

    [method:this setDecoderConfig]( [param:Object config] )

    - Disposes of the decoder library and deallocates memory. The decoder - [link:https://github.com/google/draco/issues/349 cannot be reloaded afterward]. + [page:String config.type] - (Optional) "js" or "wasm".
    +

    +

    + Provides configuration for the decoder libraries. Configuration cannot be changed + after decoding begins.

    -

    Methods

    - -

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    +

    [method:this setWorkerLimit]( [param:Number workerLimit] )

    - [page:String url] — A string containing the path/URL of the .drc file.
    - [page:Function onLoad] — A function to be called after the loading is successfully completed.
    - [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    - [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    + [page:Number workerLimit] - Maximum number of workers to be allocated. Default is 4.

    - Begin loading from url and call the onLoad function with the decompressed geometry. + Sets the maximum number of [link:https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers Web Workers] + to be used during decoding. A lower limit may be preferable if workers are also for other tasks + in the application.

    -

    [method:DRACOLoader setPath]( [param:String path] )

    +

    [method:this preload]()

    - [page:String path] — Base path. + Requests the decoder libraries, if not already loaded.

    + +

    [method:this dispose]()

    - Set the base path for the .drc file. + Disposes of the decoder resources and deallocates memory. The decoder + [link:https://github.com/google/draco/issues/349 cannot be reloaded afterward].

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/DRACOLoader.js examples/js/loaders/DRACOLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/DRACOLoader.js examples/jsm/loaders/DRACOLoader.js] +

    diff --git a/docs/examples/zh/loaders/GLTFLoader.html b/docs/examples/zh/loaders/GLTFLoader.html index f0251f461d8f69..ccb6618e437977 100644 --- a/docs/examples/zh/loaders/GLTFLoader.html +++ b/docs/examples/zh/loaders/GLTFLoader.html @@ -9,58 +9,57 @@ [page:Loader] → -

    [name]

    - -

    A loader for glTF 2.0 resources.

    - [link:https://www.khronos.org/gltf glTF] (GL Transmission Format) is an - [link:https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 open format specification] - for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf) - or binary (.glb) format. External files store textures (.jpg, .png) and additional binary - data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials, - textures, skins, skeletons, morph targets, animations, lights, and/or cameras. + +

    GLTF加载器([name])

    + +

    用于载入glTF 2.0资源的加载器。

    + [link:https://www.khronos.org/gltf glTF](gl传输格式)是一种开放格式的规范 + ([link:https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 open format specification]), + 用于更高效地传输、加载3D内容。该类文件以JSON(.glft)格式或二进制(.glb)格式提供, + 外部文件存储贴图(.jpg、.png)和额外的二进制数据(.bin)。一个glTF组件可传输一个或多个场景, + 包括网格、材质、贴图、蒙皮、骨架、变形目标、动画、灯光以及摄像机。

    -

    Extensions

    +

    扩展

    - GLTFLoader supports the following - [link:https://github.com/KhronosGroup/glTF/tree/master/extensions/ glTF 2.0 extensions]: + GLTFLoader支持下列glTF 2.0扩展([link:https://github.com/KhronosGroup/glTF/tree/master/extensions/ glTF 2.0 extensions]):

    • KHR_draco_mesh_compression
    • KHR_materials_pbrSpecularGlossiness
    • KHR_materials_unlit
    • +
    • KHR_mesh_quantization
    • KHR_lights_punctual1
    • KHR_texture_transform2
    • MSFT_texture_dds

    - 1Requires [link:https://threejs.org/docs/#api/en/renderers/WebGLRenderer.physicallyCorrectLights physicallyCorrectLights] to be enabled. + 1需要[link:https://threejs.org/docs/#api/en/renderers/WebGLRenderer.physicallyCorrectLights physicallyCorrectLights]被启用。

    - 2UV transforms are supported, with several key limitations. Transforms applied to + 2支持UV变换,但存在一些重要的限制。 + Transforms applied to a texture using the first UV slot (all textures except aoMap and lightMap) must share the same - transform, or no transfor at all. The aoMap and lightMap textures cannot be transformed. No - more than one transform may be used per material. Each use of a texture with a unique - transform will result in an additional GPU texture upload. See - #[link:https://github.com/mrdoob/three.js/pull/13831 13831] and - #[link:https://github.com/mrdoob/three.js/issues/12788 12788]. + transform, or no transfor at all. + aoMap 和 lightMap 纹理不能被变换。每个材质最多只能使用一次变换。 + 每次对使用具有唯一变换的纹理都会导致一次额外的GPU纹理上传。 + 请参阅#[link:https://github.com/mrdoob/three.js/pull/13831 13831] 和 + #[link:https://github.com/mrdoob/three.js/issues/12788 12788]。

    -

    Example

    +

    代码示例

    // Instantiate a loader - var loader = new THREE.GLTFLoader(); + var loader = new GLTFLoader(); // Optional: Provide a DRACOLoader instance to decode compressed mesh data - THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' ); - loader.setDRACOLoader( new THREE.DRACOLoader() ); - - // Optional: Pre-fetch Draco WASM/JS module, to save time while parsing. - THREE.DRACOLoader.getDecoderModule(); + var dracoLoader = new DRACOLoader(); + dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' ); + loader.setDRACOLoader( dracoLoader ); // Load a glTF resource loader.load( @@ -72,8 +71,8 @@

    Example

    scene.add( gltf.scene ); gltf.animations; // Array<THREE.AnimationClip> - gltf.scene; // THREE.Scene - gltf.scenes; // Array<THREE.Scene> + gltf.scene; // THREE.Group + gltf.scenes; // Array<THREE.Group> gltf.cameras; // Array<THREE.Camera> gltf.asset; // Object @@ -93,31 +92,30 @@

    Example

    );
    - [example:webgl_loader_gltf] +

    例子

    + +

    + [example:webgl_loader_gltf] +

    -

    Browser compatibility

    +

    浏览器兼容性

    -

    GLTFLoader relies on ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises], - which are not supported in IE11. To use the loader in IE11, you must - [link:https://github.com/stefanpenner/es6-promise include a polyfill] - providing a Promise replacement.

    +

    GLTFLoader 依赖 ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises], + 这一特性不支持IE11。若要在IE11中使用该加载器,你必须引入polyfill([link:https://github.com/stefanpenner/es6-promise include a polyfill]) + 来提供一个Promise的替代方案。

    -

    Textures

    +

    纹理

    -

    Textures containing color information (.map, .emissiveMap, and .specularMap) always use sRGB colorspace in - glTF, while vertex colors and material properties (.color, .emissive, .specular) use linear colorspace. In a - typical rendering workflow, textures are converted to linear colorspace by the renderer, lighting calculations - are made, then final output is converted back to sRGB and displayed on screen. Unless you need post-processing - in linear colorspace, always configure [page:WebGLRenderer] as follows when using glTF:

    +

    纹理中包含的颜色信息(.map, .emissiveMap, 和 .specularMap)在glTF中总是使用sRGB颜色空间,而顶点颜色和材质属性(.color, .emissive, .specular) + 则使用线性颜色空间。在典型的渲染工作流程中,纹理会被渲染器转换为线性颜色空间,进行光照计算,然后最终输出会被转换回 sRGB + 颜色空间并显示在屏幕上。除非你需要使用线性颜色空间进行后期处理,否则请在使用glTF的时候将[page:WebGLRenderer]进行如下配置:

    - renderer.gammaOutput = true; - renderer.gammaFactor = 2.2; + renderer.outputEncoding = THREE.sRGBEncoding; -

    GLTFLoader will automatically configure textures referenced from a .gltf or .glb file correctly, with the - assumption that the renderer is set up as shown above. When loading textures externally (e.g., using - [page:TextureLoader]) and applying them to a glTF model, colorspace and orientation must be given:

    +

    假设渲染器的配置如上所示,则GLTFLoader将可以正确地自动配置从.gltf或.glb文件中引用的纹理。 + 当从外部加载纹理(例如,使用[page:TextureLoader])并将纹理应用到glTF模型,则必须给定对应的颜色空间与朝向:

    // If texture is used for color information, set colorspace. @@ -127,11 +125,11 @@

    Textures

    texture.flipY = false;
    -

    Custom extensions

    +

    自定义扩展

    - Metadata from unknown extensions is preserved as “.userData.gltfExtensions” on Object3D, Scene, and Material instances, - or attached to the response “gltf” object. Example: + 来自未知扩展的元数据会被保存到Object3D、Group和Material实例中上的“.userData.gltfExtensions”, + 或被附加到 response “gltf”对象。示例:

    @@ -152,79 +150,61 @@

    Custom extensions



    -

    Constructor

    +

    构造函数

    [name]( [param:LoadingManager manager] )

    - [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager]. + [page:LoadingManager manager] — 该加载器将要使用的 [page:LoadingManager loadingManager] 。默认为 [page:LoadingManager THREE.DefaultLoadingManager]。

    - Creates a new [name]. + 创建一个新的[name]。

    -

    Properties

    +

    属性

    +

    共有属性请参见其基类[page:Loader]。

    - -

    Methods

    +

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    - [page:String url] — A string containing the path/URL of the .gltf or .glb file.
    - [page:Function onLoad] — A function to be called after the loading is successfully completed. The function receives the loaded JSON response returned from [page:Function parse].
    - [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    - [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    -

    -

    - Begin loading from url and call the callback function with the parsed response content. -

    - -

    [method:GLTFLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the .gltf/.glb file. -

    - -

    [method:GLTFLoader setResourcePath]( [param:String path] )

    -

    - [page:String path] — Base path for loading additional resources e.g. textures and .bin data. + [page:String url] — 包含有.gltf/.glb文件路径/URL的字符串。
    + [page:Function onLoad] — 加载成功完成后将会被调用的函数。该函数接收[page:Function parse]所返回的已加载的JSON响应。
    + [page:Function onProgress] — (可选)加载正在进行过程中会被调用的函数。其参数将会是XMLHttpRequest实例,包含有总字节数.[page:Integer total]与已加载的字节数.[page:Integer loaded]。
    + [page:Function onError] — (可选)若在加载过程发生错误,将被调用的函数。该函数接收error来作为参数。

    - Set the base path for additional resources. -

    - -

    [method:null setCrossOrigin]( [param:String value] )

    -

    - [page:String value] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. + 开始从url加载,并使用解析过的响应内容调用回调函数。

    [method:null setDRACOLoader]( [param:DRACOLoader dracoLoader] )

    - [page:DRACOLoader dracoLoader] — Instance of THREE.DRACOLoader, to be used for decoding assets compressed with the KHR_draco_mesh_compression extension. + [page:DRACOLoader dracoLoader] — THREE.DRACOLoader的实例,用于解码使用KHR_draco_mesh_compression扩展压缩过的文件。

    - Refer to this [link:https://github.com/mrdoob/three.js/tree/dev/examples/js/libs/draco#readme readme] for the details of Draco and its decoder. + 请参阅[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/draco#readme readme]来了解Draco及其解码器的详细信息。

    [method:null setDDSLoader]( [param:DDSLoader ddsLoader] )

    - [page:DDSLoader ddsLoader] — Instance of THREE.DDSLoader, to be used for loading compressed textures with the MSFT_TEXTURE_DDS extension. + [page:DDSLoader ddsLoader] — THREE.DDSLoader的实例,用于加载使用MSFT_TEXTURE_DDS扩展压缩过的纹理。

    [method:null parse]( [param:ArrayBuffer data], [param:String path], [param:Function onLoad], [param:Function onError] )

    - [page:ArrayBuffer data] — glTF asset to parse, as an ArrayBuffer or JSON string.
    - [page:String path] — The base path from which to find subsequent glTF resources such as textures and .bin data files.
    - [page:Function onLoad] — A function to be called when parse completes.
    - [page:Function onError] — (optional) A function to be called if an error occurs during parsing. The function receives error as an argument.
    + [page:ArrayBuffer data] — 需要解析的glTF文件,值为一个ArrayBuffer或JSON字符串。
    + [page:String path] — 用于找到后续glTF资源(如纹理和.bin数据文件)的基础路径。
    + [page:Function onLoad] — 解析成功完成后将会被调用的函数。
    + [page:Function onError] — (可选)若在解析过程发生错误,将被调用的函数。该函数接收error来作为参数。

    - Parse a glTF-based ArrayBuffer or JSON String and fire [page:Function onLoad] callback when complete. The argument to [page:Function onLoad] will be an [page:object] that contains loaded parts: .[page:Scene scene], .[page:Array scenes], .[page:Array cameras], .[page:Array animations], and .[page:Object asset]. + 解析基于glTF的ArrayBuffer或JSON字符串,并在完成后触发[page:Function onLoad]回调。[page:Function onLoad]的参数将是一个包含有已加载部分的[page:object]:.[page:Group scene]、 .[page:Array scenes]、 .[page:Array cameras]、 .[page:Array animations] 和 .[page:Object asset]。

    -

    Source

    +

    源代码

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/GLTFLoader.js examples/js/loaders/GLTFLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/GLTFLoader.js examples/jsm/loaders/GLTFLoader.js] +

    diff --git a/docs/examples/zh/loaders/LoaderSupport.html b/docs/examples/zh/loaders/LoaderSupport.html deleted file mode 100644 index 3624ef036816e1..00000000000000 --- a/docs/examples/zh/loaders/LoaderSupport.html +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - -

    [name]

    - -

    Supporting classes for file loaders and web worker based loaders.

    - -

    Sub-Classes

    - [page:LoaderSupport.Builder]
    - [page:LoaderSupport.LoadedMeshUserOverride]
    - [page:LoaderSupport.WorkerSupport]
    - [page:LoaderSupport.WorkerRunnerRefImpl]
    - [page:LoaderSupport.WorkerDirector]
    - [page:LoaderSupport.ResourceDescriptor]
    - [page:LoaderSupport.PrepData]
    - [page:LoaderSupport.Callbacks]
    - [page:LoaderSupport.Validator]
    - - -

    Example

    - - [example:webgl_loader_obj2_meshspray] - Example using [page:LoaderSupport.LoaderWorkerDirector] and [page:LoaderSupport.LoaderWorkerSupport].
    - -

    Classes

    -
    - -

    Builder

    -

    Constructor

    - -

    Builder()

    -

    - Builds one or many [page:Mesh] from one raw set of Arraybuffers, materialGroup descriptions and further parameters. - Supports vertex, vertexColor, normal, uv and index buffers. -

    - - -

    Methods

    - -

    [method:null setLogging] ( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:null init] ()

    -

    - Initializes the Builder (currently only default material initialisation). -

    - - -

    [method:null setMaterials] ( Array of [param:Material materials] )

    -

    - Array of [page:Material materials] - Array of [page:Material Materials] -

    -

    - Set materials loaded by any supplier of an Array of [page:Material Materials]. -

    - - -

    [method:Array processPayload] ( Object payload )

    -

    - [page:Object payload] - Raw Mesh or Material descriptions. -

    -

    - Delegates processing of the payload (mesh building or material update) to the corresponding functions (BW-compatibility). -

    - - -

    [method:Array buildMeshes] ( Object meshPayload )

    -

    - [page:Object meshPayload] - Raw mesh description (buffers, params, materials) used to build one to many meshes. -

    -

    - Builds one or multiple meshes from the data described in the payload (buffers, params, material info). -

    - - -

    [method:null updateMaterials] ( Object materialPayload )

    -

    - [page:Object materialPayload] - Material update instructions -

    -

    - Updates the materials with contained material objects (sync) or from alteration instructions (async). -

    - - -

    [method:Object getMaterialsJSON] ()

    -

    - Returns the mapping object of material name and corresponding jsonified material. -

    - - -

    [method:Object getMaterials] ()

    -

    - Returns the mapping object of material name and corresponding material. -

    -
    -
    - - -

    LoadedMeshUserOverride

    -

    Constructor

    - -

    LoadedMeshUserOverride( [param:Boolean disregardMesh], [param:BufferGeometry bufferGeometry] )

    -

    - [page:Boolean disregardMesh] - Tell implementation to completely disregard this mesh
    - [page:Boolean alteredMesh] - Tell implementation that mesh(es) have been altered or added -

    -

    - Object to return by callback onMeshAlter. Used to disregard a certain mesh or to return one to many meshes. -

    - - -

    Methods

    - -

    [method:null addMesh] ( [param:Mesh mesh] )

    -

    - [page:Mesh mesh] - Mesh -

    -

    - Add a mesh created within callback. -

    - - -

    [method:boolean isDisregardMesh] ()

    -

    - Answers if mesh shall be disregarded completely. -

    - - -

    [method:boolean providesAlteredMeshes] ()

    -

    - Answers if new mesh(es) were created. -

    -
    -
    - - -

    WorkerSupport

    -

    Constructor

    - -

    WorkerSupport()

    -

    - This class provides means to transform existing parser code into a web worker. - It defines a simple communication protocol which allows to configure the worker and receive raw mesh data during execution. -

    - - -

    Methods

    - -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:null setForceWorkerDataCopy]( [param:Boolean forceWorkerDataCopy] )

    -

    - [page:Boolean forceWorkerDataCopy] True or false. -

    -

    - Forces all ArrayBuffers to be transferred to worker to be copied. -

    - - -

    [method:null validate] ( [param:Function functionCodeBuilder], Array of [param:String libLocations], [param:String libPath], [param:LoaderSupport.WorkerRunnerRefImpl runnerImpl] )

    -

    - [page:Function functionCodeBuilder] - Function that is invoked with funcBuildObject and funcBuildSingleton that allows stringification of objects and singletons.
    - Array of [page:String libLocations] - URL of libraries that shall be added to worker code relative to libPath.
    - [page:String libPath] - Base path used for loading libraries.
    - [page:LoaderSupport.WorkerRunnerRefImpl runnerImpl] - The default worker parser wrapper implementation (communication and execution). An extended class could be passed here. -

    -

    - Validate the status of worker code and the derived worker. -

    - - -

    [method:null setTerminateRequested] ( [param:Boolean terminateRequested] )

    -

    - [page:Boolean terminateRequested] - True or false. -

    -

    - Request termination of worker once parser is finished. -

    - - -

    [method:null setCallbacks] ( [param:Function builder], [param:Function onLoad] )

    -

    - [page:Function builder] - The builder function. Default is [page:LoaderSupport.Builder].
    - [page:Function onLoad] - The function that is called when parsing is complete. -

    -

    - Specify functions that should be build when new raw mesh data becomes available and when the parser is finished. -

    - - -

    [method:null run] ( [param:Object payload] )

    -

    - [page:Object payload] - Raw mesh description (buffers, params, materials) used to build one to many meshes. -

    -

    - Runs the parser with the provided configuration. -

    -
    -
    - - -

    WorkerRunnerRefImpl

    -

    Constructor

    - -

    WorkerRunnerRefImpl()

    -

    - Default implementation of the WorkerRunner responsible for creation and configuration of the parser within the worker. -

    - - -

    Methods

    - -

    [method:null applyProperties] ( [param:Object parser], [param:Object params] )

    -

    - [page:Object parser] - The parser instance
    - [page:Object params] - The parameter object -

    -

    - Applies values from parameter object via set functions or via direct assignment. -

    - - -

    [method:null run] ( [param:Object payload] )

    -

    - [page:Object payload] - Raw mesh description (buffers, params, materials) used to build one to many meshes. -

    -

    - Configures the Parser implementation according the supplied configuration object. -

    -
    -
    - - -

    WorkerDirector

    -

    Constructor

    - -

    WorkerDirector( [param:String classDef] )

    -

    - [page:String classDef] - Class definition to be used for construction -

    -

    - Orchestrate loading of multiple OBJ files/data from an instruction queue with a configurable amount of workers (1-16).
    - - Workflow:
    - - prepareWorkers
    - - enqueueForRun
    - - processQueue
    - - tearDown -

    - - -

    Methods

    - -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:null setForceWorkerDataCopy]( [param:Boolean forceWorkerDataCopy] )

    -

    - [page:Boolean forceWorkerDataCopy] True or false. -

    -

    - Forces all ArrayBuffers to be transferred to worker to be copied. -

    - - -

    [method:null prepareWorkers]( [param:WWOBJLoader2.Callbacks globalCallbacks], [param:Number maxQueueSize], [param:Number maxWebWorkers] )

    -

    - [page:LoaderSupport.Callbacks globalCallbacks] - Register global callbacks used by all web workers
    - [page:Number maxQueueSize] - Set the maximum size of the instruction queue (1-1024)
    - [page:Number maxWebWorkers] - Set the maximum amount of workers (1-16) -

    -

    - Create or destroy workers according limits. Set the name and register callbacks for dynamically created web workers. -

    - - -

    [method:null enqueueForRun]( [param:LoaderSupport.PrepData runParams] )

    -

    - [page:LoaderSupport.PrepData runParams] -

    -

    - Store run instructions in internal instructionQueue. -

    - - -

    [method:null processQueue]()

    -

    - Process the instructionQueue until it is depleted. -

    - - -

    [method:null tearDown]( [param:Function callbackOnFinishedProcessing] )

    -

    - [page:Function callbackOnFinishedProcessing] - Function called once all workers finished processing. -

    -

    - Terminate all workers. -

    - - -

    [method:null getMaxQueueSize]()

    -

    - Returns the maximum length of the instruction queue. -

    - - -

    [method:null getMaxWebWorkers]()

    -

    - Returns the maximum number of workers. -

    - -

    [method:Boolean isRunning]()

    -

    - Returns if any workers are running. -

    - - -

    [method:null setCrossOrigin]( [param:String crossOrigin] )

    -

    - [page:String crossOrigin] - CORS value -

    -

    - Sets the CORS string to be used. -

    -
    -
    - - -

    ResourceDescriptor

    -

    Constructor

    - -

    ResourceDescriptor( [param:String url], [param:String extension] )

    -

    - [page:String url] - URL to the file
    - [page:String extension] - The file extension (type) -

    -

    - A resource description used by [page:LoaderSupport.PrepData] and others. -

    - -

    Methods

    - -

    [method:null setContent]( [param:Object content )

    -

    - [page:Object content] - The file content as ArrayBuffer or text -

    -

    - Set the content of this resource -

    - - -

    [method:null setResourcePath] ( [param:String resourcePath] )

    -

    - [page:String resourcePath] - URL -

    -

    - Allows to specify resourcePath for dependencies of specified resource. -

    -
    -
    - - -

    PrepData

    -

    Constructor

    - -

    PrepData( [param:String modelName] )

    -

    - [page:String modelName] - Overall name of the model -

    -

    - Configuration instructions to be used by run method. -

    - - -

    Methods

    - -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    -

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. -

    -

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. -

    - - -

    [method:Callbacks getCallbacks]()

    -

    - Returns all callbacks as [page:LoaderSupport.Callbacks]. -

    - - -

    [method:null addResource]( [param:LoaderSupport.ResourceDescriptor resource] )

    -

    - [page:LoaderSupport.ResourceDescriptor resource] Adds a [page:LoaderSupport.ResourceDescriptor] -

    -

    - Add a resource description. -

    - - -

    [method:null checkResourceDescriptorFiles] ( [param:LoaderSupport.ResourceDescriptor resources], [param:Object fileDesc] )

    -

    - [page:LoaderSupport.ResourceDescriptor resources] - Array of [page:LoaderSupport.ResourceDescriptor]
    - [page:Object fileDesc] - Object describing which resources are of interest (ext, type (string or UInt8Array) and ignore (boolean)) -

    -

    - Identify files or content of interest from an Array of [page:LoaderSupport.ResourceDescriptor]. - Returns Object with each "ext" and the corresponding [page:LoaderSupport.ResourceDescriptor] -

    - - -

    [method:PrepData clone] ()

    -

    - Clones this object and returns it afterwards. Callbacks and resources are not cloned deep (references!). -

    -
    -
    - - -

    Callbacks

    -

    Constructor

    - -

    Callbacks()

    -

    - Callbacks utilized by loaders and builder. -

    - - -

    Methods

    - -

    [method:null setCallbackOnProgress]( [param:Function callbackOnProgress] )

    -

    - [page:Function callbackOnProgress] - Callback function for described functionality -

    -

    - Register callback function that is invoked by internal function "announceProgress" to print feedback. -

    - -

    [method:null setCallbackOnReportError]( [param:Function callbackOnReportError] )

    -

    - [page:Function callbackOnReportError] - Callback function for described functionality -

    -

    - Register callback function that is invoked when an error is reported. -

    - -

    [method:null setCallbackOnMeshAlter]( [param:Function callbackOnMeshAlter] )

    -

    - [page:Function callbackOnMeshAlter] - Callback function for described functionality -

    -

    - Register callback function that is called every time a mesh was loaded. - Use [page:LoadedMeshUserOverride] for alteration instructions (geometry, material or disregard mesh). -

    - - -

    [method:null setCallbackOnLoad]( [param:Function callbackOnLoad] )

    -

    - [page:Function callbackOnLoad] - Callback function for described functionality -

    -

    - Register callback function that is called once loading of the complete OBJ file is completed. -

    - -

    [method:null setCallbackOnLoadMaterials]( [param:Function callbackOnLoadMaterials] )

    -

    - [page:Function callbackOnLoadMaterials] - Callback function for described functionality -

    -

    - Register callback function that is called when materials have been loaded. -

    -
    -
    - - -

    Validator

    -

    Constructor

    - -

    Validator()

    -

    - Validation functions. -

    - - -

    Methods

    - -

    [method:Boolean isValid]( [param:Object input] )

    -

    - [page:Object input] - Can be anything -

    -

    - If given input is null or undefined, false is returned otherwise true. -

    - - -

    [method:null verifyInput]( [param:Object input], [param:Object defaultValue] )

    -

    - [page:Object input] - Can be anything
    - [page:Object defaultValue] - Can be anything -

    -

    - If given input is null or undefined, the defaultValue is returned otherwise the given input. -

    -
    -
    - -

    Source

    - - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/LoaderSupport.js examples/js/loaders/LoaderSupport.js] - - - diff --git a/docs/examples/zh/loaders/MMDLoader.html b/docs/examples/zh/loaders/MMDLoader.html index 3287ec82207a68..4c6ecee6c08cea 100644 --- a/docs/examples/zh/loaders/MMDLoader.html +++ b/docs/examples/zh/loaders/MMDLoader.html @@ -9,19 +9,20 @@ [page:Loader] → -

    [name]

    -

    A loader for MMD resources.

    - [name] creates Three.js Objects from MMD resources as PMD, PMX, VMD, and VPD files. - See [page:MMDAnimationHelper] for MMD animation handling as IK, Grant, and Physics.

    +

    MMD加载器([name])

    - If you want raw content of MMD resources, use .loadPMD/PMX/VMD/VPD methods. +

    一个用于加载MMD资源的加载器。

    + [name]从MMD资源(例如PMD、PMX、VMD和VPD文件)中创建Three.js物体(对象)。 + 请参阅[page:MMDAnimationHelper]来了解MMD动画的处理,例如IK、Grant和Physics。

    -

    Example

    + 如果你想要MMD资源的原始内容,请使用.loadPMD/PMX/VMD/VPD方法。 + +

    代码示例

    // Instantiate a loader - var loader = new THREE.MMDLoader(); + var loader = new MMDLoader(); // Load a MMD model loader.load( @@ -48,94 +49,76 @@

    Example

    );
    +

    例子

    +

    [example:webgl_loader_mmd]
    [example:webgl_loader_mmd_pose]
    - [example:webgl_loader_mmd_audio]
    - -
    -


    + [example:webgl_loader_mmd_audio] +

    -

    Constructor

    +

    构造函数

    -

    [name]( [param:LoadingManager manager] )

    +

    [name]( [param:LoadingManager manager] )

    - [page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager]. + [page:LoadingManager manager] — 加载器使用的[page:LoadingManager loadingManager](加载管理器),默认值是[page:LoadingManager THREE.DefaultLoadingManager]。

    - Creates a new [name]. + 创建一个新的[name]。

    -

    Properties

    +

    属性

    +

    共有属性请参见其基类[page:Loader]。

    - -

    Methods

    +

    方法

    +

    共有方法请参见其基类[page:Loader]。

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    - [page:String url] — A string containing the path/URL of the .pmd or .pmx file.
    - [page:Function onLoad] — A function to be called after the loading is successfully completed.
    - [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    - [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    + [page:String url] — 一个包含有.pmd.pmx文件的路径或URL的字符串。
    + [page:Function onLoad] — 当加载过程成功完成以后将被调用的函数。
    + [page:Function onProgress] — (可选)加载过程正在进行的时候被调用的函数。其参数是一个XMLHttpRequest实例,其包含了[page:Integer total] bytes(总的字节数)和[page:Integer loaded] bytes(已经载入的字节数)。
    + [page:Function onError] — (可选) 加载过程中若发生了错误将被调用的函数。这一函数接收错误作为参数。

    - Begin loading PMD/PMX model file from url and fire the callback function with the parsed [page:SkinnedMesh] containing [page:BufferGeometry] and an array of [page:MeshToonMaterial]. + 开始从URL中加载PMD/PMX模型文件,并使用包含有已被解析的[page:SkinnedMesh]和[page:MeshToonMaterial]数组的[page:BufferGeometry]对象来触发回调函数。

    [method:null loadAnimation]( [param:String url], [param:Object3D object], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    - [page:String url] — A string or an array of string containing the path/URL of the .vmd file(s).If two or more files are specified, they'll be merged.
    - [page:Object3D object] — [page:SkinnedMesh] or [page:Camera]. Clip and its tacks will be fitting to this object.
    - [page:Function onLoad] — A function to be called after the loading is successfully completed.
    - [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    - [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    + [page:String url] — 一个包含有.vmd文件的路径或URL的字符串或字符串数组。如果两个及以上文件被指定,它们将会合并。
    + [page:Object3D object] — [page:SkinnedMesh] 或 [page:Camera]。 剪辑及其轨道将会适应到该对象。
    + [page:Function onLoad] — 成功加载完成后被调用的函数。
    + [page:Function onProgress] — (可选)当加载正在进行时被调用的函数,参数将是XMLHttpRequest实例,其包含了 .[page:Integer total] (总的)和 .[page:Integer loaded] (已加载的)字节数。
    + [page:Function onError] — (可选)如果加载过程中发生错误时被调用的函数,该函数接受一个错误来作为参数。

    - Begin loading VMD motion file(s) from url(s) and fire the callback function with the parsed [page:AnimatioinClip]. + 开始从url(s)加载VMD动画文件(可能有多个文件),并使用已解析的[page:AnimatioinClip]触发回调函数。

    [method:null loadWithAnimation]( [param:String modelUrl], [param:String vmdUrl], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    - [page:String modelUrl] — A string containing the path/URL of the .pmd or .pmx file.
    - [page:String vmdUrl] — A string or an array of string containing the path/URL of the .vmd file(s).
    - [page:Function onLoad] — A function to be called after the loading is successfully completed.
    - [page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes.
    - [page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
    -

    -

    - Begin loading PMD/PMX model file and VMD motion file(s) from urls and fire the callback function with an [page:Object] containing parsed [page:SkinnedMesh] and [page:AnimationClip] fitting to the [page:SkinnedMesh]. + [page:String modelUrl] — 一个包含有.pmd.pmx文件的路径或URL的字符串。
    + [page:String vmdUrl] — 一个包含有.vmd文件的路径或URL的字符串或字符串数组。
    + [page:Function onLoad] — 成功加载完成后被调用的函数。
    + [page:Function onProgress] — (可选)当加载正在进行时被调用的函数,参数将是XMLHttpRequest实例,其包含了 .[page:Integer total] (总的)和 .[page:Integer loaded] (已加载的)字节数。
    + [page:Function onError] — (可选)如果加载过程中发生错误时被调用的函数,该函数接受一个错误来作为参数。

    - -

    [method:MMDLoader setCrossOrigin]( [param:String crossOrigin] )

    - [page:String crossOrigin] — The crossOrigin string to implement CORS for loading the url from a different domain that allows CORS. + 开始从URL中加载PMD/PMX模型文件和VMD动画文件(可能有多个文件),并使用一个[page:Object] —— 包含有已解析的[page:SkinnedMesh]和适应[page:SkinnedMesh]的[page:AnimationClip],来触发回调函数。

    [method:MMDLoader setAnimationPath]( [param:String animationPath] )

    - [page:String animationPath] — Base path for loading animation data (VMD/VPD files). + [page:String animationPath] — 用于加载动画数据(VMD/VPD 文件)的基础路径。 Base path for loading animation data (VMD/VPD files).

    - Set the base path for additional resources like textures. + 设置额外资源(例如贴图)的基础路径。

    -

    [method:MMDLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Sets the base path or URL from which to load files. -

    +

    源代码

    -

    [method:MMDLoader setResourcePath]( [param:String resourcePath] )

    - [page:String resourcePath] — Base path for loading additional resources e.g. textures. + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/MMDLoader.js examples/jsm/loaders/MMDLoader.js]

    -

    - Set the base path for additional resources like textures. -

    - -

    Source

    - - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/MMDLoader.js examples/js/loaders/MMDLoader.js] diff --git a/docs/examples/zh/loaders/MTLLoader.html b/docs/examples/zh/loaders/MTLLoader.html index 82111f6da165e9..aab6afa1af6746 100644 --- a/docs/examples/zh/loaders/MTLLoader.html +++ b/docs/examples/zh/loaders/MTLLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -27,10 +28,10 @@

    [name]( [param:LoadingManager loadingManager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    - +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -43,35 +44,6 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and return the loaded material.

    - -

    [method:MTLLoader setPath]( [param:String path] )

    -

    - [page:String path] — required
    -

    -

    - Set base path for MTL file. -

    - - -

    [method:MTLLoader setResourcePath]( [param:String path] )

    -

    - [page:String path] — required
    -

    -

    - Set base path for additional resources like textures. If set, this path will be used as the base path. -

    - - -

    [method:MTLLoader setCrossOrigin]( [param:String value] )

    -

    - [page:String value] — required
    -

    -

    - If set, assigns the [link:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes crossOrigin] - attribute of the image to the value of *crossOrigin*, prior to starting the load. Default is *"anonymous"*. -

    - -

    [method:MTLLoader setMaterialOptions]( [param:Object options] )

    [page:Object options] — required @@ -100,6 +72,8 @@

    [method:MTLLoaderMaterialCreator parse]( [param:String text, param:String pa

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/[name].js examples/js/loaders/[name].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/[name].js examples/jsm/loaders/[name].js] +

    diff --git a/docs/examples/zh/loaders/OBJLoader.html b/docs/examples/zh/loaders/OBJLoader.html index 1cf6b610beb97e..1babee57c8e738 100644 --- a/docs/examples/zh/loaders/OBJLoader.html +++ b/docs/examples/zh/loaders/OBJLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -18,12 +19,11 @@

    [name]

    vertices, and texture vertices.

    - -

    Example

    +

    代码示例

    // instantiate a loader - var loader = new THREE.OBJLoader(); + var loader = new OBJLoader(); // load a resource loader.load( @@ -50,8 +50,10 @@

    Example

    );
    - [example:webgl_loader_obj] - +

    例子

    +

    + [example:webgl_loader_obj] +

    Constructor

    @@ -64,9 +66,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -97,13 +100,10 @@

    [method:OBJLoader setMaterials]( [param:MTLLoader.MaterialCreator materials] Sets materials loaded by MTLLoader or any other supplier of a [page:MTLLoaderMaterialCreator MTLLoader.MaterialCreator].

    -

    [method:OBJLoader setPath]( [param:String path] )

    -

    - Sets the base path or URL from which to load files. This can be useful to avoid repetition if you are calling [page:OBJLoader.load .load] multiple times on the same directory. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js examples/js/loaders/OBJLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/OBJLoader.js examples/jsm/loaders/OBJLoader.js] +

    diff --git a/docs/examples/zh/loaders/OBJLoader2.html b/docs/examples/zh/loaders/OBJLoader2.html index 316aaab077d70c..9bbb75e79c8133 100644 --- a/docs/examples/zh/loaders/OBJLoader2.html +++ b/docs/examples/zh/loaders/OBJLoader2.html @@ -18,193 +18,190 @@

    [name]

    vertices, and texture vertices.

    -

    Examples

    +

    代码示例

    // instantiate the loader - var loader = new THREE.OBJLoader2(); + let loader = new OBJLoader2(); // function called on successful load - var callbackOnLoad = function ( event ) { - scene.add( event.detail.loaderRootNode ); - }; + function callbackOnLoad ( object3d ) { + scene.add( object3d ); + } // load a resource from provided URL synchronously - loader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null, false ); + loader.load( 'obj/female02/female02.obj', callbackOnLoad, null, null, null ); - [example:webgl_loader_obj2] - Simple example
    - [example:webgl_loader_obj2_options] - Example for multiple use-cases (parse, load and run with instructions (sync and async)
    - [example:webgl_loader_obj2_run_director] - Advanced example using [page:LoaderSupport.LoaderWorkerDirector] for orchestration of multiple workers. - +

    例子

    +

    + [example:webgl_loader_obj2] - Simple example
    + [example:webgl_loader_obj2_options] - Example for multiple use-cases (parse and load, sync or in parallel to main (see [page:OBJLoader2Parallel])) +

    Constructor

    -

    [name]( [param:LoadingManager manager], [param:LoaderSupport.ConsoleLogger logger] )

    +

    [name]( [param:LoadingManager manager] )

    [page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
    - [page:LoaderSupport.ConsoleLogger logger] - logger to be used

    - Use [name] to load OBJ data from files or to parse OBJ data from arraybuffer or text. + Creates a new [name]. Use it to load OBJ data from files or to parse OBJ data from arraybuffer or text.

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    + +

    Methods

    +

    See the base [page:Loader] class for common methods.

    +

    [method:Object3D parse]( [param:arraybuffer content]|[param:String content] )

    [[page:arraybuffer content]|[page:String content]] OBJ data as Uint8Array or String

    - Parses OBJ data synchronously from arraybuffer or string and returns the [page:Object3D loaderRoorNode]. -

    - - -

    [method:Object3D parseAsync]( [param:arraybuffer content], [param:Function onLoad] )

    -

    - [page:arraybuffer content] - OBJ data as Uint8Array
    - [page:Function onLoad] - Called after worker successfully completed loading
    -

    -

    - Parses OBJ content asynchronously from arraybuffer. + Parses OBJ data synchronously from arraybuffer or string and returns the [page:Object3D baseObject3d].

    -

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError], [param:Function onMeshAlter], [param:boolean useAsync] )

    +

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError], [param:Function onMeshAlter] )

    [page:String url] - A string containing the path/URL of the file to be loaded.
    [page:Function onLoad] - A function to be called after loading is successfully completed. The function receives loaded [page:Object3D] as an argument.
    [page:Function onProgress] - (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.
    [page:Function onError] - (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.
    [page:Function onMeshAlter] - (optional) A function to be called after a new mesh raw data becomes available for alteration.
    - [page:boolean useAsync] - (optional) If true, uses async loading with worker, if false loads data synchronously.

    Use this convenient method to load a file at the given URL. By default the fileLoader uses an ArrayBuffer.

    -

    [method:null run]( [param:LoaderSupport.PrepData params], [param:LoaderSupport.WorkerSupport workerSupportExternal] )

    +

    [method:OBJLoader2 setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    - [page:LoaderSupport.PrepData params] - prepData All parameters and resources required for execution
    - [page:LoaderSupport.WorkerSupport workerSupportExternal] - Use pre-existing WorkerSupport + [page:Boolean enabled] True or false.
    + [page:Boolean debug] True or false.

    - Run the loader according the provided instructions. + Enable or disable logging in general (except warn and error), plus enable or disable debug logging.

    -

    [method:null setLogging]( [param:Boolean enabled], [param:Boolean debug] )

    +

    [method:OBJLoader2 addMaterialPerSmoothingGroup] ( [param:boolean materialPerSmoothingGroup] )

    - [page:Boolean enabled] True or false.
    - [page:Boolean debug] True or false. + [page:boolean materialPerSmoothingGroup]

    - Enable or disable logging in general (except warn and error), plus enable or disable debug logging. + Tells whether a material shall be created per smoothing group.

    -

    [method:null setModelName] ( [param:String modelName] )

    +

    [method:OBJLoader2 setUseOAsMesh] ( [param:boolean useOAsMesh] )

    - [page:String modelName] + [page:boolean useOAsMesh]

    - Set the name of the model. + Usually 'o' is meta-information and does not result in creation of new meshes, but mesh creation on occurrence of "o" can be enforced.

    -

    [method:null setPath] ( [param:String path] )

    +

    [method:OBJLoader2 setUseIndices]( [param:Boolean useIndices] )

    - [page:String path] - URL + [page:Boolean useIndices]

    - The URL of the base path. + Instructs loaders to create indexed [page:BufferGeometry].

    -

    [method:null setResourcePath] ( [param:String resourcePath] )

    +

    [method:OBJLoader2 setDisregardNormals]( [param:Boolean disregardNormals] )

    +

    + [page:Boolean disregardNormals] +

    - [page:String resourcePath] - URL + Tells whether normals should be completely disregarded and regenerated. +

    + + +

    [method:OBJLoader2 setModelName] ( [param:String modelName] )

    +

    + [page:String modelName]

    - Allows to specify resourcePath for dependencies of specified resource. + Set the name of the model.

    -

    [method:null setStreamMeshesTo] ( [param:Object3D streamMeshesTo] )

    +

    [method:OBJLoader2 setBaseObject3d] ( [param:Object3d baseObject3d] )

    - [page:Object3D streamMeshesTo] - Object already attached to scenegraph where new meshes will be attached to + [page:Object3D baseObject3d - Object already attached to scenegraph where new meshes will be attached to

    Set the node where the loaded objects will be attached directly.

    -

    [method:null setMaterials] ( Array of [param:Material materials] )

    +

    [method:OBJLoader2 setMaterials] ( [param:Object materials] )

    - Array of [page:Material materials] - Array of [page:Material Materials] + [page:Object materials] - materials Object with named [page:Material Materials]

    - Set materials loaded by MTLLoader or any other supplier of an Array of [page:Material Materials]. + Add materials as associated array.

    -

    [method:null setUseIndices]( [param:Boolean useIndices] )

    +

    [method:OBJLoader2 setCallbackOnLoad] ( [param:Function onLoad] )

    - [page:Boolean useIndices] + [page:Function onLoad]

    - Instructs loaders to create indexed [page:BufferGeometry]. + Register a function that is called when parsing was completed.

    -

    [method:null setDisregardNormals]( [param:Boolean disregardNormals] )

    +

    [method:OBJLoader2 setCallbackOnAssetAvailable] ( [param:Function onAssetAvailable] )

    - [page:Boolean disregardNormals] + [page:Function onAssetAvailable]

    - Tells whether normals should be completely disregarded and regenerated. + Register a function that is called once an asset (mesh/material) becomes available.

    -

    [method:null setMaterialPerSmoothingGroup] ( [param:boolean materialPerSmoothingGroup] )

    +

    [method:OBJLoader2 setCallbackOnProgress] ( [param:Function onProgress] )

    - [page:boolean materialPerSmoothingGroup] + [page:Function onProgress]

    - Tells whether a material shall be created per smoothing group. + Register a function that is used to report overall processing progress.

    -

    [method:null onProgress]( [param:String type], [param:String text], [param:Number numericalValue] )

    +

    [method:OBJLoader2 setCallbackOnError] ( [param:Function onError] )

    - [page:String type] - The type of event
    - [page:String text] - Textual description of the event
    - [page:Number numericalValue] - Numerical value describing the progress + [page:Function onError]

    - Announce feedback which is give to the registered [page:LoaderSupport.Callbacks]. + Register an error handler function that is called if errors occur. It can decide to just log or to throw an exception.

    -

    [method:null loadMtl]( [param:String url], [param:Object content], [param:Function callbackOnLoad], [param:String crossOrigin], [param:Object materialOptions])

    +

    [method:OBJLoader2 setCallbackOnMeshAlter] ( [param:Function onMeshAlter] )

    - [page:String url] - URL to the file
    - [page:Object content] - The file content as arraybuffer or text
    - [page:Function onLoad] - Callback to be called after successful load
    - [page:Function onProgress] - (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains [page:Integer total] and [page:Integer loaded] bytes.
    - [page:Function onError] - (optional) A function to be called if an error occurs during loading. The function receives the error as an argument.
    - [page:String crossOrigin] - (optional) CORS value
    - [page:Function materialOptions] - (optional) Set material loading options for MTLLoader + [page:Function onMeshAlter]

    - Utility method for loading an mtl file according resource description. Provide url or content. + Register a function that is called once a single mesh is available and it could be altered by the supplied function.

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader2.js examples/js/loaders/OBJLoader2.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/OBJLoader2.js examples/jsm/loaders/OBJLoader2.js] +

    diff --git a/docs/examples/zh/loaders/OBJLoader2Parallel.html b/docs/examples/zh/loaders/OBJLoader2Parallel.html new file mode 100644 index 00000000000000..28ec26e8abadda --- /dev/null +++ b/docs/examples/zh/loaders/OBJLoader2Parallel.html @@ -0,0 +1,111 @@ + + + + + + + + + + + +

    [name]

    + +

    A loader for loading a .obj resource.
    + The OBJ file format is a simple data-format + that represents 3D geometry in a human readable format as, the position of each vertex, the UV position of + each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of + vertices, and texture vertices. +

    + +

    代码示例

    + + + // instantiate the loader + let objLoader2Parallel = new OBJLoader2Parallel(); + + // define where to attach the data + let local = new THREE.Object3D(); + + // function called on successful completion of parsing + function callbackOnLoad( object3d, message ) { + local.add( object3d ); + } + + // load a resource from provided URL in parallel to Main + objLoader2Parallel.load( 'models/obj/walt/WaltHead.obj', callbackOnLoad, null, null, null ); + + +

    例子

    +

    + [example:webgl_loader_obj2_options] - Example for multiple use-cases (parse and load, sync (see [page:OBJLoader2]) or in parallel to main) +

    + +

    Constructor

    + +

    [name]( [param:LoadingManager manager] )

    +

    + [page:LoadingManager manager] - The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
    +

    +

    + Creates a new [name]. Use it to load OBJ data from files or to parse OBJ data from arraybuffer. + It extends [page:OBJLoader2] with the capability to run the parser in a web worker. +

    + + +

    Properties

    +

    See the base [page:OBJLoader2] class for common properties.

    + + +

    Methods

    +

    See the base [page:OBJLoader2] class for common methods.

    + + +

    [method:Object3D parse]

    +

    See [page:OBJLoader2.parse].
    + The callback [page:OBJLoader2.setCallbackOnLoad OBJLoader2.onLoad] needs to be set to be able to receive the content if used in parallel mode. + Fallback is possible via [page:OBJLoader2Parallel.setExecuteParallel]. +

    + + +

    [method:null load]

    +

    See [page:OBJLoader2.load].

    + + +

    [method:OBJLoader2Parallel setExecuteParallel] ( [param:boolean executeParallel] )

    +

    + [page:boolean executeParallel] - True or False +

    +

    + Execution of parse in parallel via Worker is default, but synchronous [page:OBJLoader2] parsing can be enforced via false here. +

    + + +

    [method:OBJLoader2Parallel setPreferJsmWorker] ( [param:boolean preferJsmWorker] )

    +

    + [page:boolean preferJsmWorker] - True or False +

    +

    + Set whether jsm modules in workers should be used. This requires browser support which is currently only experimental. +

    + + +

    [method:WorkerExecutionSupport getWorkerExecutionSupport] ()

    +

    + Allow to get hold of [page:WorkerExecutionSupport] for configuration purposes. +

    + + +

    [method:CodeBuilderInstructions buildWorkerCode] ()

    +

    + Provide instructions on what is to be contained in the worker. +

    + + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/OBJLoader2Parallel.js examples/jsm/loaders/OBJLoader2Parallel.js] +

    + + diff --git a/docs/examples/zh/loaders/PCDLoader.html b/docs/examples/zh/loaders/PCDLoader.html index 31b11c46607d1a..d6776b14793736 100644 --- a/docs/examples/zh/loaders/PCDLoader.html +++ b/docs/examples/zh/loaders/PCDLoader.html @@ -8,20 +8,21 @@ + [page:Loader] →

    [name]

    A loader for loading a .pcd resource.
    Point Cloud Data is a file format for Point Cloud Library.
    - Loader support ascii and binary. Compressed binary files are not supported. + Loader support ascii and (compressed) binary.

    -

    Example

    +

    代码示例

    // instantiate a loader - var loader = new THREE.PCDLoader(); + var loader = new PCDLoader(); // load a resource loader.load( @@ -48,8 +49,10 @@

    Example

    );
    - [example:webgl_loader_pcd] - +

    例子

    +

    + [example:webgl_loader_pcd] +

    Constructor

    @@ -62,6 +65,7 @@

    [name]( [param:LoadingManager manager] )

    Properties

    +

    See the base [page:Loader] class for common properties.

    [page:Boolean littleEndian]

    @@ -69,6 +73,7 @@

    [page:Boolean littleEndian]

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -93,16 +98,10 @@

    [method:Object3D parse]( [param:Arraybuffer data],[param:String url] )

    The object is converted to [page:Points] with a [page:BufferGeometry] and a [page:PointsMaterial].

    -

    [method:PCDLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PCDLoader.js examples/js/loaders/PCDLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PCDLoader.js examples/jsm/loaders/PCDLoader.js] +

    diff --git a/docs/examples/zh/loaders/PDBLoader.html b/docs/examples/zh/loaders/PDBLoader.html index 09c2cd9e6780ae..2a8b2f55433745 100644 --- a/docs/examples/zh/loaders/PDBLoader.html +++ b/docs/examples/zh/loaders/PDBLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -15,11 +16,11 @@

    [name]

    The Protein Data Bank file format is a textual file describing the three-dimensional structures of molecules.

    -

    Example

    +

    代码示例

    // instantiate a loader - var loader = new THREE.PDBLoader(); + var loader = new PDBLoader(); // load a PDB resource loader.load( @@ -50,8 +51,10 @@

    Example

    );
    - [example:webgl_loader_pdb] - +

    例子

    +

    + [example:webgl_loader_pdb] +

    Constructor

    @@ -64,9 +67,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -87,16 +91,10 @@

    [method:Object parse]( [param:String text] )

    Parse a pdb text and return a JSON structure.

    -

    [method:PDBLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PDBLoader.js examples/js/loaders/PDBLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PDBLoader.js examples/jsm/loaders/PDBLoader.js] +

    diff --git a/docs/examples/zh/loaders/PRWMLoader.html b/docs/examples/zh/loaders/PRWMLoader.html index ae7da8413ca01b..60d18c07adcef7 100644 --- a/docs/examples/zh/loaders/PRWMLoader.html +++ b/docs/examples/zh/loaders/PRWMLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -19,11 +20,11 @@

    [name]

    on this here.

    -

    Example

    +

    代码示例

    // instantiate a loader - var loader = new THREE.PRWMLoader(); + var loader = new PRWMLoader(); // load a resource loader.load( @@ -51,8 +52,10 @@

    Example

    );
    - [example:webgl_loader_prwm] - +

    例子

    +

    + [example:webgl_loader_prwm] +

    Constructor

    @@ -65,9 +68,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -94,22 +98,10 @@

    PRWMLoader.isBigEndianPlatform( )

    Return true if the endianness of the platform is Big Endian, false otherwise.

    -

    [method:PRWMLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/PRWMLoader.js examples/js/loaders/PRWMLoader.js] - -

    Additional notes

    -

    - This loader is additionally available on npm as three-prwm-loader. + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PRWMLoader.js examples/jsm/loaders/PRWMLoader.js]

    diff --git a/docs/examples/zh/loaders/SVGLoader.html b/docs/examples/zh/loaders/SVGLoader.html index caca171e47b5bc..890809898bd5d3 100644 --- a/docs/examples/zh/loaders/SVGLoader.html +++ b/docs/examples/zh/loaders/SVGLoader.html @@ -8,6 +8,7 @@ + [page:Loader] →

    [name]

    @@ -15,11 +16,11 @@

    [name]

    Scalable Vector Graphics is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation.

    -

    Example

    +

    代码示例

    // instantiate a loader - var loader = new THREE.SVGLoader(); + var loader = new SVGLoader(); // load a SVG resource loader.load( @@ -72,7 +73,10 @@

    Example

    );
    - [example:webgl_loader_svg] +

    例子

    +

    + [example:webgl_loader_svg] +

    Constructor

    @@ -85,9 +89,10 @@

    [name]( [param:LoadingManager manager] )

    Properties

    - +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:null load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -100,16 +105,10 @@

    [method:null load]( [param:String url], [param:Function onLoad], [param:Func Begin loading from url and call onLoad with the response content.

    -

    [method:SVGLoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/SVGLoader.js examples/js/loaders/SVGLoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/SVGLoader.js examples/jsm/loaders/SVGLoader.js] +

    diff --git a/docs/examples/zh/loaders/TGALoader.html b/docs/examples/zh/loaders/TGALoader.html index 2c75666ede263a..b10b8ceb005890 100644 --- a/docs/examples/zh/loaders/TGALoader.html +++ b/docs/examples/zh/loaders/TGALoader.html @@ -8,17 +8,19 @@ + [page:Loader] → +

    [name]

    A loader for loading a .tga resource.
    TGA is a raster graphics, image file format.

    -

    Example

    +

    代码示例

    // instantiate a loader - var loader = new THREE.TGALoader(); + var loader = new TGALoader(); // load a resource var texture = loader.load( @@ -50,7 +52,10 @@

    Example

    } );
    - [example:webgl_materials_texture_tga] +

    例子

    +

    + [example:webgl_loader_texture_tga] +

    Constructor

    @@ -62,8 +67,11 @@

    [name]( [param:LoadingManager manager] )

    Creates a new [name].

    +

    Properties

    +

    See the base [page:Loader] class for common properties.

    Methods

    +

    See the base [page:Loader] class for common methods.

    [method:DataTexture load]( [param:String url], [param:Function onLoad], [param:Function onProgress], [param:Function onError] )

    @@ -76,16 +84,10 @@

    [method:DataTexture load]( [param:String url], [param:Function onLoad], [par Begin loading from url and pass the loaded [page:DataTexture texture] to onLoad. The [page:DataTexture texture] is also directly returned for immediate use (but may not be fully loaded).

    -

    [method:TGALoader setPath]( [param:String path] )

    -

    - [page:String path] — Base path. -

    -

    - Set the base path for the file. -

    -

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/TGALoader.js examples/js/loaders/TGALoader.js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/TGALoader.js examples/jsm/loaders/TGALoader.js] +

    diff --git a/docs/examples/zh/Lut.html b/docs/examples/zh/math/Lut.html similarity index 91% rename from docs/examples/zh/Lut.html rename to docs/examples/zh/math/Lut.html index c4bdc641f5aeea..e3b9f748b03de7 100644 --- a/docs/examples/zh/Lut.html +++ b/docs/examples/zh/math/Lut.html @@ -2,7 +2,7 @@ - + @@ -15,11 +15,11 @@

    [name]

    -

    Example

    - var lut = new THREE.Lut( "rainbow", 512 ); - var data = [0, 10.1, 4.2, 3.4, 63, 28]; - lut.setMax(63); - color = lut.getColor(10); +

    代码示例

    + + var lut = new Lut( 'rainbow', 512 ); + var color = lut.getColor( 0.5 ); +

    Constructor

    @@ -138,6 +138,8 @@

    [method:Lut getColor]( value ) [param:Lut this]

    Source

    - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/[path].js examples/js/math/[path].js] +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/[path].js examples/jsm/math/[path].js] +

    diff --git a/docs/examples/zh/math/MeshSurfaceSampler.html b/docs/examples/zh/math/MeshSurfaceSampler.html new file mode 100644 index 00000000000000..086eac189f1dbd --- /dev/null +++ b/docs/examples/zh/math/MeshSurfaceSampler.html @@ -0,0 +1,86 @@ + + + + + + + + + + +

    [name]

    + +

    Utility class for sampling weighted random points on the surface of a mesh.

    + +

    Weighted sampling is useful for effects like heavier foliage growth in certain areas of terrain, or concentrated particle emissions from specific parts of a mesh. Vertex weights may be written programmatically, or painted by hand as vertex colors in 3D tools like Blender.

    + +

    代码示例

    + + + // Create a sampler for a Mesh surface. + var sampler = new MeshSurfaceSampler( surfaceMesh ) + .setWeightAttribute( 'color' ) + .build(); + + var sampleMesh = new THREE.InstancedMesh( sampleGeometry, sampleMaterial, 100 ); + + var _position = new THREE.Vector3(); + var _normal = new THREE.Vector3(); + var _matrix = new THREE.Matrix4(); + + // Sample randomly from the surface, creating an instance of the sample + // geometry at each sample point. + for ( var i = 0; i < 100; i ++ ) { + + sampler.sample( _position, _normal ); + + _matrix.makeTranslation( _position.x, _position.y, _position.z ); + + mesh.setMatrixAt( i, _matrix ); + + } + + mesh.instanceMatrix.needsUpdate = true; + + scene.add( mesh ); + + +

    例子

    +

    + [example:webgl_instancing_scatter] +

    + +

    Constructor

    + +

    [name]( [param:Mesh mesh] )

    +

    + [page:Mesh mesh] — Surface mesh from which to sample. +

    +

    + Creates a new [name]. If the input geometry is indexed, a non-indexed copy is made. After construction, the sampler is not able to return samples until [page:MeshSurfaceSampler.build build] is called. +

    + +

    Methods

    + +

    [method:this setWeightAttribute]( [param:String name] )

    +

    + Specifies a vertex attribute to be used as a weight when sampling from the surface. Faces with higher weights are more likely to be sampled, and those with weights of zero will not be sampled at all. For vector attributes, only .x is used in sampling. +

    +

    If no weight attribute is selected, sampling is randomly distributed by area.

    + +

    [method:this build]()

    +

    + Processes the input geometry and prepares to return samples. Any configuration of the geometry or sampler must occur before this method is called. Time complexity is O(n) for a surface with n faces. +

    + +

    [method:this sample]( [param:Vector3 targetPosition], [param:Vector3 targetNormal] )

    +

    + Selects a random point on the surface of the input geometry, returning the position and normal vector at that point. Time complexity is O(log n) for a surface with n faces.

    + +

    Source

    + +

    + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/MeshSurfaceSampler.js examples/jsm/math/MeshSurfaceSampler.js] +

    + + diff --git a/docs/examples/zh/math/convexhull/ConvexHull.html b/docs/examples/zh/math/convexhull/ConvexHull.html index f301ec2712949f..09ef56195a57ac 100644 --- a/docs/examples/zh/math/convexhull/ConvexHull.html +++ b/docs/examples/zh/math/convexhull/ConvexHull.html @@ -20,6 +20,7 @@

    Constructor

    [name]()

    + Creates a new instance of [name].

    Properties

    @@ -57,28 +58,35 @@

    [property:Array vertices]

    Methods

    [method:HalfEdge addAdjoiningFace]( [param:VertexNode eyeVertex], [param:HalfEdge horizonEdge] )

    - [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    - [page:HalfEdge horizonEdge] - A single edge of the horizon.

    +

    + [page:VertexNode eyeVertex] - The vertex that is added to the hull.
    + [page:HalfEdge horizonEdge] - A single edge of the horizon.

    -

    Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order. - All the half edges are created in CCW order thus the face is always pointing outside the hull

    + Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order. + All the half edges are created in CCW order thus the face is always pointing outside the hull +

    [method:ConvexHull addNewFaces]( [param:VertexNode eyeVertex], [param:HalfEdge horizonEdge] )

    - [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    - [page:HalfEdge horizon] - An array of half-edges that form the horizon.

    +

    + [page:VertexNode eyeVertex] - The vertex that is added to the hull.
    + [page:HalfEdge horizon] - An array of half-edges that form the horizon.

    -

    Adds 'horizon.length' faces to the hull, each face will be linked with the horizon opposite face and the face on the left/right.

    + Adds 'horizon.length' faces to the hull, each face will be linked with the horizon opposite face and the face on the left/right. +

    [method:ConvexHull addVertexToFace]( [param:VertexNode vertex], [param:Face face] )

    - [page:VertexNodeNode vertex] - The vertex to add.

    - [page:Face face] - The target face.

    +

    + [page:VertexNodeNode vertex] - The vertex to add.
    + [page:Face face] - The target face.

    -

    Adds a vertex to the 'assigned' list of vertices and assigns it to the given face.

    + Adds a vertex to the 'assigned' list of vertices and assigns it to the given face. +

    [method:ConvexHull addVertexToHull]( [param:VertexNode eyeVertex] )

    - [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    +

    + [page:VertexNode eyeVertex] - The vertex that is added to the hull.

    -

    Adds a vertex to the hull with the following algorithm + Adds a vertex to the hull with the following algorithm

    • Compute the 'horizon' which is a chain of half edges. For an edge to belong to this group it must be the edge connecting a face that can see 'eyeVertex' and a face which cannot see 'eyeVertex'.
    • All the faces that can see 'eyeVertex' have its visible vertices removed from the assigned vertex list.
    • @@ -100,27 +108,32 @@

      [method:Object computeExtremes]()

      Computes the extremes values (min/max vectors) which will be used to compute the inital hull.

      [method:ConvexHull computeHorizon]( [param:Vector3 eyePoint], [param:HalfEdge crossEdge], [param:Face face], [param:Array horizon] )

      - [page:Vector3 eyePoint] - The 3D-coordinates of a point.

      - [page:HalfEdge crossEdge] - The edge used to jump to the current face.

      - [page:Face face] - The current face being tested.

      - [page:Array horizon] - The edges that form part of the horizon in CCW order.

      +

      + [page:Vector3 eyePoint] - The 3D-coordinates of a point.
      + [page:HalfEdge crossEdge] - The edge used to jump to the current face.
      + [page:Face face] - The current face being tested.
      + [page:Array horizon] - The edges that form part of the horizon in CCW order.

      -

      Computes a chain of half edges in CCW order called the 'horizon'. For an edge to be part of the horizon it must join a face that can see 'eyePoint' and a face that cannot see 'eyePoint'.

      + Computes a chain of half edges in CCW order called the 'horizon'. For an edge to be part of the horizon it must join a face that can see 'eyePoint' and a face that cannot see 'eyePoint'. +

      [method:ConvexHull computeInitialHull]()

      Computes the initial simplex assigning to its faces all the points that are candidates to form part of the hull.

      [method:ConvexHull containsPoint]( [param:Vector3 point] )

      - [page:Vector3 point] - A point in 3D space.

      +

      + [page:Vector3 point] - A point in 3D space.

      -

      Returns *true* if the given point is inside this convex hull.

      + Returns *true* if the given point is inside this convex hull. +

      [method:ConvexHull deleteFaceVertices]( [param:Face face], [param:Face absorbingFace] )

      - [page:Face face] - The given face.

      - [page:Face absorbingFace] - An optional face that tries to absorb the vertices of the first face.

      +

      + [page:Face face] - The given face.
      + [page:Face absorbingFace] - An optional face that tries to absorb the vertices of the first face.

      -

      Removes all the visible vertices that 'face' is able to see. + Removes all the visible vertices that 'face' is able to see.

      • If 'absorbingFace' doesn't exist, then all the removed vertices will be added to the 'unassigned' vertex list.
      • If 'absorbingFace' exists, then this method will assign all the vertices of 'face' that can see 'absorbingFace'.
      • @@ -129,15 +142,19 @@

        [method:ConvexHull deleteFaceVertices]( [param:Face face], [param:Face absor

        [method:Vector3 intersectRay]( [param:Ray ray], [param:Vector3 target] )

        - [page:Ray ray] - The given ray.

        - [page:Vector3 target] - The target vector representing the intersection point.

        +

        + [page:Ray ray] - The given ray.
        + [page:Vector3 target] - The target vector representing the intersection point.

        -

        Performs a ray intersection test with this convext hull. If no intersection is found, *null* is returned.

        + Performs a ray intersection test with this convext hull. If no intersection is found, *null* is returned. +

        [method:Boolean intersectsRay]( [param:Ray ray] )

        - [page:Ray ray] - The given ray.

        +

        + [page:Ray ray] - The given ray.

        -

        Returns *true* if the given ray intersects with this convex hull.

        + Returns *true* if the given ray intersects with this convex hull. +

        [method:ConvexHull makeEmpty]()

        @@ -158,34 +175,45 @@

        [method:ConvexHull reindexFaces]()

        Removes inactive (e.g. deleted) faces from the internal face list.

        [method:VertexNode removeAllVerticesFromFace]( [param:Face face] )

        - [page:Face face] - The given face.

        +

        + [page:Face face] - The given face.

        -

        Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertext list.

        + Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertext list. +

        [method:ConvexHull removeVertexFromFace]( [param:VertexNode vertex], [param:Face face] )

        - [page:VertexNode vertex] - The vertex to remove.

        - [page:Face face] - The target face.

        +

        + [page:VertexNode vertex] - The vertex to remove.
        + [page:Face face] - The target face.

        -

        Removes a vertex from the 'assigned' list of vertices and from the given face. It also makes sure that the link from 'face' to the first vertex it sees in 'assigned' is linked correctly after the removal.

        + Removes a vertex from the 'assigned' list of vertices and from the given face. It also makes sure that the link from 'face' to the first vertex it sees in 'assigned' is linked correctly after the removal. +

        [method:ConvexHull resolveUnassignedPoints]( [param:Array newFaces] )

        - [page:Face newFaces] - An array of new faces.

        +

        + [page:Face newFaces] - An array of new faces.

        -

        Reassigns as many vertices as possible from the unassigned list to the new faces.

        + Reassigns as many vertices as possible from the unassigned list to the new faces. +

        [method:ConvexHull setFromObject]( [param:Object3D object] )

        - [page:Object3D object] - [page:Object3D] to compute the convex hull of.

        +

        + [page:Object3D object] - [page:Object3D] to compute the convex hull of.

        -

        Computes the convex hull of an [page:Object3D] (including its children), - accounting for the world transforms of both the object and its childrens.

        + Computes the convex hull of an [page:Object3D] (including its children),accounting for the world transforms of both the object and its childrens. +

        [method:ConvexHull setFromPoints]( [param:Array points] )

        - [page:Array points] - Array of [page:Vector3 Vector3s] that the resulting convex hull will contain.

        +

        + [page:Array points] - Array of [page:Vector3 Vector3s] that the resulting convex hull will contain.

        -

        Computes to convex hull for the given array of points.

        + Computes to convex hull for the given array of points. +

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/ConvexHull.js] +

        diff --git a/docs/examples/zh/math/convexhull/Face.html b/docs/examples/zh/math/convexhull/Face.html index 265abcfc3257c5..f1797665aeaaba 100644 --- a/docs/examples/zh/math/convexhull/Face.html +++ b/docs/examples/zh/math/convexhull/Face.html @@ -20,6 +20,7 @@

        Constructor

        [name]()

        + Creates a new instance of [name].

        Properties

        @@ -62,28 +63,36 @@

        [property:HalfEdge edge]

        Methods

        [method:Face create]( [param:VertexNode a], [param:VertexNode b], [param:VertexNode c] )

        - [page:VertexNode a] - First vertex of the face.

        - [page:VertexNode b] - Second vertex of the face.

        - [page:VertexNode c] - Third vertex of the face.

        +

        + [page:VertexNode a] - First vertex of the face.
        + [page:VertexNode b] - Second vertex of the face.
        + [page:VertexNode c] - Third vertex of the face.

        -

        Creates a face.

        + Creates a face. +

        [method:HalfEdge getEdge]( [param:Integer i] )

        - [page:Integer i] - The index of the edge.

        +

        + [page:Integer i] - The index of the edge.

        -

        Returns an edge by the given index.

        + Returns an edge by the given index. +

        [method:Face compute] ()

        Computes all properties of the face.

        [method:Float distanceToPoint]( [param:Vector3 point] )

        - [page:Vector3 point] - Any point in 3D space.

        +

        + [page:Vector3 point] - Any point in 3D space.

        -

        Returns the signed distance from a given point to the plane representation of this face.

        + Returns the signed distance from a given point to the plane representation of this face. +

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/zh/math/convexhull/HalfEdge.html b/docs/examples/zh/math/convexhull/HalfEdge.html index c8de2778faaee8..1a17670c09e0d2 100644 --- a/docs/examples/zh/math/convexhull/HalfEdge.html +++ b/docs/examples/zh/math/convexhull/HalfEdge.html @@ -20,10 +20,11 @@

        Constructor

        [name]( [param:VertexNode vertex], [param:Face face] )

        - [page:VertexNode vertex] - [page:VertexNode] A reference to its destination vertex.

        - [page:Face face] - [page:Face] A reference to its face.
        -

        + [page:VertexNode vertex] - [page:VertexNode] A reference to its destination vertex.
        + [page:Face face] - [page:Face] A reference to its face.

        + Creates a new instance of [name]. +

        Properties

        [property:VertexNode vertex]

        @@ -68,12 +69,16 @@

        [method:Float lengthSquared]()

        (straight-line length) of the edge.

        [method:HalfEdge setTwin]( [param:HalfEdge edge] )

        - [page:HalfEdge edge] - Any half-edge.

        +

        + [page:HalfEdge edge] - Any half-edge.

        -

        Sets the twin edge of this half-edge. It also ensures that the twin reference of the given half-edge is correctly set.

        + Sets the twin edge of this half-edge. It also ensures that the twin reference of the given half-edge is correctly set. +

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/zh/math/convexhull/VertexList.html b/docs/examples/zh/math/convexhull/VertexList.html index aa7ac965e16160..fa050a83a91cd4 100644 --- a/docs/examples/zh/math/convexhull/VertexList.html +++ b/docs/examples/zh/math/convexhull/VertexList.html @@ -20,6 +20,7 @@

        Constructor

        [name]()

        + Creates a new instance of [name].

        Properties

        @@ -47,38 +48,48 @@

        [method:VertexList clear]()

        [method:VertexList insertBefore]( [param:Vertex target], [param:Vertex vertex] )

        - [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.

        - [page:Vertex vertex] - The vertex to insert.

        -

        + [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.
        + [page:Vertex vertex] - The vertex to insert.

        -

        Inserts a vertex before a target vertex.

        + Inserts a vertex before a target vertex. +

        [method:VertexList insertAfter]( [param:Vertex target], [param:Vertex vertex] )

        - [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.

        - [page:Vertex vertex] - The vertex to insert.

        +

        + [page:Vertex target] - The target vertex. It's assumed that this vertex belongs to the linked list.
        + [page:Vertex vertex] - The vertex to insert.

        -

        Inserts a vertex after a target vertex.

        + Inserts a vertex after a target vertex. +

        [method:VertexList append]( [param:Vertex vertex] )

        - [page:Vertex vertex] - The vertex to append.

        +

        + [page:Vertex vertex] - The vertex to append.

        -

        Appends a vertex to the end of the linked list.

        + Appends a vertex to the end of the linked list. +

        [method:VertexList appendChain]( [param:Vertex vertex] )

        - [page:Vertex vertex] - The head vertex of a chain of vertices.

        +

        + [page:Vertex vertex] - The head vertex of a chain of vertices.

        -

        Appends a chain of vertices where the given vertex is the head.

        + Appends a chain of vertices where the given vertex is the head. +

        [method:VertexList remove]( [param:Vertex vertex] )

        - [page:Vertex vertex] - The vertex to remove.

        +

        + [page:Vertex vertex] - The vertex to remove.

        -

        Removes a vertex from the linked list.

        + Removes a vertex from the linked list. +

        [method:VertexList removeSubList]( [param:Vertex a], [param:Vertex b] )

        - [page:Vertex a] - The head of the sublist.

        - [page:Vertex b] - The tail of the sublist.

        +

        + [page:Vertex a] - The head of the sublist.
        + [page:Vertex b] - The tail of the sublist.

        -

        Removes a sublist of vertices from the linked list.

        + Removes a sublist of vertices from the linked list. +

        [method:Boolean isEmpty]()

        @@ -86,6 +97,8 @@

        [method:Boolean isEmpty]()

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/zh/math/convexhull/VertexNode.html b/docs/examples/zh/math/convexhull/VertexNode.html index 8c139829a31b01..e963c28835b0ef 100644 --- a/docs/examples/zh/math/convexhull/VertexNode.html +++ b/docs/examples/zh/math/convexhull/VertexNode.html @@ -21,6 +21,8 @@

        Constructor

        [name]( [param:Vector3 point] )

        [page:Vector3 point] - [page:Vector3] A point (x, y, z) in 3D space.

        + + Creates a new instance of [name].

        Properties

        @@ -47,6 +49,8 @@

        [property:Face face]

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/math/ConvexHull.js examples/js/math/ConvexHull.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/math/ConvexHull.js examples/jsm/math/ConvexHull.js] +

        diff --git a/docs/examples/zh/objects/Lensflare.html b/docs/examples/zh/objects/Lensflare.html index d9ba42c25f19fc..f52bc7bd3a8400 100644 --- a/docs/examples/zh/objects/Lensflare.html +++ b/docs/examples/zh/objects/Lensflare.html @@ -10,35 +10,36 @@ [page:Mesh] → -

        [name]

        +

        镜头光晕([name])

        - Creates a simulated lens flare that tracks a light.

        + 创建一个模拟追踪着灯光的镜头光晕。

        -

        Example

        +

        代码示例

        -

        - [example:webgl_lensflares lensflares] + + var light = new THREE.PointLight( 0xffffff, 1.5, 2000 ); - -var light = new THREE.PointLight( 0xffffff, 1.5, 2000 ); + var textureLoader = new THREE.TextureLoader(); -var textureLoader = new THREE.TextureLoader(); + var textureFlare0 = textureLoader.load( "textures/lensflare/lensflare0.png" ); + var textureFlare1 = textureLoader.load( "textures/lensflare/lensflare2.png" ); + var textureFlare2 = textureLoader.load( "textures/lensflare/lensflare3.png" ); -var textureFlare0 = textureLoader.load( "textures/lensflare/lensflare0.png" ); -var textureFlare1 = textureLoader.load( "textures/lensflare/lensflare2.png" ); -var textureFlare2 = textureLoader.load( "textures/lensflare/lensflare3.png" ); + var lensflare = new Lensflare(); -var lensflare = new THREE.Lensflare(); + lensflare.addElement( new LensflareElement( textureFlare0, 512, 0 ) ); + lensflare.addElement( new LensflareElement( textureFlare1, 512, 0 ) ); + lensflare.addElement( new LensflareElement( textureFlare2, 60, 0.6 ) ); -lensflare.addElement( new THREE.LensflareElement( textureFlare0, 512, 0 ) ); -lensflare.addElement( new THREE.LensflareElement( textureFlare1, 512, 0 ) ); -lensflare.addElement( new THREE.LensflareElement( textureFlare2, 60, 0.6 ) ); + light.add( lensflare ); + -light.add( lensflare ); - +

        例子

        +

        + [example:webgl_lensflares WebGL / lensflares]

        Constructor

        @@ -46,25 +47,20 @@

        Constructor

        LensflareElement( [param:Texture texture], [param:Float size], [param:Float distance], [param:Color color] )

        - [page:Texture texture] - THREE.Texture to use for the flare.
        - [page:Float size] - (optional) size in pixels
        - [page:Float distance] - (optional) (0-1) from light source (0 = at light source)
        - [page:Color color] - (optional) the [page:Color] of the lens flare + [page:Texture texture] - 用于光晕的THREE.Texture(贴图)
        + [page:Float size] - (可选)光晕尺寸(单位为像素)
        + [page:Float distance] - (可选)和光源的距离值在0到1之间(值为0时在光源的位置)
        + [page:Color color] - (可选)光晕的([page:Color])颜色

        -

        Properties

        -

        See the base [page:Mesh] class for common properties.

        - -

        [property:Boolean isLensflare]

        -

        - Used to check whether this or derived classes are lensflares. Default is *true*.

        - - You should not change this, as it used internally for optimisation. -

        +

        属性

        +

        请参阅其基类[page:Mesh]来了解共有属性。

        -

        Source

        +

        源代码

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/objects/Lensflare.js examples/js/objects/Lensflare.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/objects/Lensflare.js examples/jsm/objects/Lensflare.js] +

        diff --git a/docs/examples/zh/postprocessing/EffectComposer.html b/docs/examples/zh/postprocessing/EffectComposer.html index 4813edba14e9c5..4d92965cc1ba1f 100644 --- a/docs/examples/zh/postprocessing/EffectComposer.html +++ b/docs/examples/zh/postprocessing/EffectComposer.html @@ -9,13 +9,14 @@ -

        [name]

        +

        效果合成器([name])

        - TODO + 用于在three.js中实现后期处理效果。该类管理了产生最终视觉效果的后期处理过程链。 + 后期处理过程根据它们添加/插入的顺序来执行,最后一个过程会被自动渲染到屏幕上。

        -

        Examples

        +

        例子

        [example:webgl_postprocessing postprocessing]
        @@ -43,68 +44,68 @@

        Examples

        [example:webgl_postprocessing_unreal_bloom_selective postprocessing unreal bloom selective]

        -

        Constructor

        +

        构造函数

        [name]( [param:WebGLRenderer renderer], [param:WebGLRenderTarget renderTarget] )

        - [page:WebGLRenderer renderer] -- The renderer used to render the scene.
        - [page:WebGLRenderTarget renderTarget] -- (optional) A preconfigured render target internally used by [name]. + [page:WebGLRenderer renderer] -- 用于渲染场景的渲染器。
        + [page:WebGLRenderTarget renderTarget] -- (可选)一个预先配置的渲染目标,内部由 [name] 使用。

        -

        Properties

        +

        属性

        -

        [property:Boolean passes]

        +

        [property:Array passes]

        - An array representing the (ordered) chain of post-processing passes. + 一个用于表示后期处理过程链(包含顺序)的数组。

        [property:WebGLRendererTarget readBuffer]

        - A reference to the internal read buffer. Passes usually read the previous render result from this buffer. + 内部读缓冲区的引用。过程一般从该缓冲区读取先前的渲染结果。

        [property:WebGLRenderer renderer]

        - A reference to the internal renderer. + 内部渲染器的引用。

        [property:Boolean renderToScreen]

        - Whether the final pass is rendered to the screen (default framebuffer) or not. + 最终过程是否被渲染到屏幕(默认帧缓冲区)。

        [property:WebGLRendererTarget writeBuffer]

        - A reference to the internal write buffer. Passes usually write their result into this buffer. + 内部写缓冲区的引用。过程常将它们的渲染结果写入该缓冲区。

        -

        Methods

        +

        方法

        [method:void addPass]( [param:Pass pass] )

        - pass -- The pass to add to the pass chain.

        + pass -- 将被添加到过程链的过程

        - Adds the given pass to the pass chain. + 将传入的过程添加到过程链。

        [method:void insertPass]( [param:Pass pass], [param:Integer index] )

        - pass -- The pass to insert into the pass chain.
        - index -- Defines the position in the pass chain where the pass should be inserted.

        + pass -- 将被插入到过程链的过程。
        + index -- 定义过程链中过程应插入的位置。

        - Inserts the given pass into the pass chain at the given index. + 将传入的过程插入到过程链中所给定的索引处。

        [method:boolean isLastEnabledPass]( [param:Integer passIndex] )

        - passIndex -- The pass to check.

        + passIndex -- 被用于检查的过程

        - Returns true if the pass for the given index is the last enabled pass in the pass chain. - Used by [name] to determine when a pass should be rendered to screen. + 如果给定索引的过程在过程链中是最后一个启用的过程,则返回true。 + 由[name]所使用,来决定哪一个过程应当被渲染到屏幕上。

        [method:void render]( [param:Float deltaTime] )

        @@ -112,42 +113,46 @@

        [method:void render]( [param:Float deltaTime] )

        deltaTime -- The delta time value.

        - Executes all enabled post-processing passes in order to produce the final frame. + 执行所有启用的后期处理过程,来产生最终的帧,

        [method:void reset]( [param:WebGLRenderTarget renderTarget] )

        - [page:WebGLRenderTarget renderTarget] -- (optional) A preconfigured render target internally used by [name]..

        + [page:WebGLRenderTarget renderTarget] -- (可选)一个预先配置的渲染目标,内部由 [name] 使用。

        - Resets the internal state of the [name]. + 重置所有[name]的内部状态。

        [method:void setPixelRatio]( [param:Float pixelRatio] )

        - pixelRatio -- The device pixel ratio.

        + pixelRatio -- 设备像素比

        + + 设置设备的像素比。该值通常被用于HiDPI设备,以阻止模糊的输出。 + 因此,该方法语义类似于[page:WebGLRenderer.setPixelRatio]()。 - Sets device pixel ratio. This is usually used for HiDPI device to prevent bluring output. - Thus, the semantic of the method is similar to [page:WebGLRenderer.setPixelRatio]().

        [method:void setSize]( [param:Integer width], [param:Integer height] )

        - width -- The width of the [name].
        - height -- The height of the [name].

        + width -- [name]的宽度。
        + height -- [name]的高度。

        + + 考虑设备像素比,重新设置内部渲染缓冲和过程的大小为(width, height)。 + 因此,该方法语义类似于[page:WebGLRenderer.setSize]()。 - Resizes the internal render buffers and passes to (width, height) with device pixel ratio taken into account. - Thus, the semantic of the method is similar to [page:WebGLRenderer.setSize]().

        [method:void swapBuffers]()

        -

        Swaps the internal read/write buffers.

        +

        交换内部的读/写缓冲。

        -

        Source

        +

        源代码

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/postprocessing/EffectComposer.js examples/js/postprocessing/EffectComposer.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/postprocessing/EffectComposer.js examples/jsm/postprocessing/EffectComposer.js] +

        diff --git a/docs/examples/zh/renderers/CSS2DRenderer.html b/docs/examples/zh/renderers/CSS2DRenderer.html index 7cf3252b988abf..bcdc10307a26fd 100644 --- a/docs/examples/zh/renderers/CSS2DRenderer.html +++ b/docs/examples/zh/renderers/CSS2DRenderer.html @@ -8,58 +8,44 @@ -

        [name]

        +

        CSS 2D渲染器([name])

        -

        [name] is a simplified version of [page:CSS3DRenderer]. The only transformation that is supported is translation.

        - The renderer is very useful if you want to combine HTML based labels with 3D objects. Here too, the respective DOM elements are wrapped into an instance of *CSS2DObject* and added to the scene graph.
        +

        [name]是[page:CSS3DRenderer](CSS 3D渲染器)的简化版本,唯一支持的变换是位移。

        + 如果你希望将三维物体和基于HTML的标签相结合,则这一渲染器将十分有用。在这里,各个DOM元素也被包含到一个*CSS2DObject*实例中,并被添加到场景图中。

        - - -

        Examples

        +

        例子

        [example:css2d_label]
        [example:webgl_loader_pdb molecules]

        -

        Constructor

        +

        构造函数

        [name]()

        -

        Methods

        +

        方法

        [method:Object getSize]()

        - Returns an object containing the width and height of the renderer. + 返回一个包含有渲染器宽和高的对象。

        [method:null render]( [param:Scene scene], [param:Camera camera] )

        - Renders a [page:Scene scene] using a [page:Camera camera].
        + 使用[page:Camera camera]渲染[page:Scene scene]。

        [method:null setSize]([param:Number width], [param:Number height])

        - Resizes the renderer to (width, height). + 将渲染器的尺寸调整为(width, height).

        -

        Source

        +

        源代码

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CSS2DRenderer.js examples/js/renderers/CSS2DRenderer.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/CSS2DRenderer.js examples/jsm/renderers/CSS2DRenderer.js] +

        diff --git a/docs/examples/zh/renderers/CSS3DRenderer.html b/docs/examples/zh/renderers/CSS3DRenderer.html index 9e904461a982b7..aeaf2eca9141f4 100644 --- a/docs/examples/zh/renderers/CSS3DRenderer.html +++ b/docs/examples/zh/renderers/CSS3DRenderer.html @@ -8,38 +8,23 @@ -

        [name]

        - -

        [name] can be used to apply hierarchical 3D transformations to DOM elements - via the CSS3 [link:https://www.w3schools.com/cssref/css3_pr_transform.asp transform] property. - This renderer is particular interesting if you want to apply 3D effects to a website without - canvas based rendering. It can also be used in order to combine DOM elements with WebGL - content.

        - There are, however, some important limitations: +

        CSS 3D渲染器([name])

        + +

        + [name]用于通过CSS3的[link:https://www.w3schools.com/cssref/css3_pr_transform.asp transform]属性, + 将层级的3D变换应用到DOM元素上。 + 如果你希望不借助基于canvas的渲染来在你的网站上应用3D变换,那么这一渲染器十分有趣。 + 同时,它也可以将DOM元素与WebGL的内容相结合。 +

        + 然而,这一渲染器也有一些十分重要的限制:

          -
        • It's not possible to use the material system of *three.js*.
        • -
        • It's also not possible to use geometries.
        • +
        • 它不可能使用*three.js*中的材质系统。
        • +
        • 同时也不可能使用几何体。
        - So [name] is just focused on ordinary DOM elements. These elements are wrapped into special objects (*CSS3DObject* or *CSS3DSprite*) and then added to the scene graph. + 因此,[name]仅仅关注普通的DOM元素,这些元素被包含到了特殊的对象中(*CSS3DObject*或者*CSS3DSprite*),然后被加入到场景图中。

        - - -

        Examples

        +

        例子

        [example:css3d_molecules molecules]
        @@ -49,29 +34,31 @@

        Examples

        [example:css3d_sprites sprites]

        -

        Constructor

        +

        构造函数

        [name]()

        -

        Methods

        +

        方法

        [method:Object getSize]()

        - Returns an object containing the width and height of the renderer. + 返回一个包含有渲染器宽和高的对象。

        [method:null render]( [param:Scene scene], [param:PerspectiveCamera camera] )

        - Renders a [page:Scene scene] using a [page:PerspectiveCamera perspective camera].
        + 使用[page:PerspectiveCamera perspective camera]渲染[page:Scene scene]。

        [method:null setSize]([param:Number width], [param:Number height])

        - Resizes the renderer to (width, height). + 将渲染器尺寸重新调整为(width, height)。

        -

        Source

        +

        源代码

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CSS3DRenderer.js examples/js/renderers/CSS3DRenderer.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/CSS3DRenderer.js examples/jsm/renderers/CSS3DRenderer.js] +

        diff --git a/docs/examples/zh/renderers/SVGRenderer.html b/docs/examples/zh/renderers/SVGRenderer.html index 8c8209157ebbf3..0550f46cf1c4c6 100644 --- a/docs/examples/zh/renderers/SVGRenderer.html +++ b/docs/examples/zh/renderers/SVGRenderer.html @@ -8,100 +8,79 @@ -

        [name]

        +

        SVG渲染器([name])

        - [name] can be used to render geometric data using SVG. The produced vector graphics are particular useful in the following use cases: + [name]被用于使用SVG来渲染几何数据,所产生的矢量图形在以下几个方面十分有用:

          -
        • Animated logos or icons
        • -
        • Interactive 2D/3D diagrams or graphs
        • -
        • Interactive maps
        • -
        • Complex or animated user interfaces
        • +
        • 动画标志(logo)或者图标(icon)
        • +
        • 可交互的2D或3D图表或图形
        • +
        • 交互式地图
        • +
        • 复杂的或包含动画的用户界面

        - [name] has various advantages. It produces crystal-clear and sharp output which is independent of the actual viewport resolution.
        - SVG elements can be styled via CSS. And they have good accessibility since it's possible to add metadata like title or description (useful for search engines or screen readers). + [name]具有很多优势。它产生清晰并且锐利的图像输出,它和实际视口分辨率无关。
        + SVG元素可以通过CSS来控制样式;并且由于它可以添加诸如标题或者描述文字之类的元数据(对于搜索引擎或者屏幕阅读器十分有用),因此它具有十分良好的可访问性。

        - There are, however, some important limitations: + 然而,SVG也有一些十分重要的限制:

          -
        • No advanced shading
        • -
        • No texture support
        • -
        • No shadow support
        • +
        • 没有高级的着色器
        • +
        • 不支持纹理
        • +
        • 不支持阴影
        - - -

        Examples

        +

        例子

        [example:svg_lines lines]
        [example:svg_sandbox sandbox]

        -

        Constructor

        +

        构造函数

        [name]()

        -

        Properties

        - -

        [property:Number overdraw]

        -

        - Number of fractional pixels to enlarge polygons in order to prevent anti-aliasing gaps. Range is [0..1]. Default is *0.5*. -

        - -

        Methods

        +

        方法

        [method:null clear]()

        - Tells the renderer to clear its drawing surface. + 告诉渲染器来清除其绘图表面。

        [method:null render]( [param:Scene scene], [param:Camera camera] )

        - Renders a [page:Scene scene] using a [page:Camera camera]. + 使用[page:Camera camera]来渲染一个[page:Scene scene]。

        [method:null setClearColor]( [param:Color color], [param:number alpha] )

        - Sets the clearColor and the clearAlpha. + 设置clearColor(空白颜色)以及clearAlpha(空白Alpha)。

        [method:null setPrecision]( [param:Number precision] )

        - Sets the precision of the data used to create a path. + 设置用于创建路径的数据的精度。

        [method:null setQuality]()

        - Sets the render quality. Possible values are *low* and *high* (default). + 设置渲染质量。可能的值有*low*和*high*(默认值)。

        [method:null setSize]( [param:Number width], [param:Number height] )

        - Resizes the renderer to (width, height). + 改变渲染器尺寸为(width, height)。

        -

        Source

        +

        源代码

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/SVGRenderer.js examples/js/renderers/SVGRenderer.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/SVGRenderer.js examples/jsm/renderers/SVGRenderer.js] +

        diff --git a/docs/examples/zh/utils/BufferGeometryUtils.html b/docs/examples/zh/utils/BufferGeometryUtils.html index 5772efeaebcef9..595e9cf194abc0 100644 --- a/docs/examples/zh/utils/BufferGeometryUtils.html +++ b/docs/examples/zh/utils/BufferGeometryUtils.html @@ -1,80 +1,92 @@ - - - - - - - - -

        [name]

        + + + + + + + + +

        [name]

        -

        - A class containing utility functions for [page:BufferGeometry BufferGeometry] instances.

        -

        +

        + A class containing utility functions for [page:BufferGeometry BufferGeometry] instances. +

        -

        Methods

        +

        Methods

        -

        [method:null computeTangents]( [param:BufferGeometry geometry] )

        -

        - geometry -- A [page:BufferGeometry BufferGeometry] instance, which must have index, position, normal, and uv attributes.

        +

        [method:null computeTangents]( [param:BufferGeometry geometry] )

        +

        + geometry -- A [page:BufferGeometry BufferGeometry] instance, which must have index, position, normal, and uv attributes.

        - Calculates and adds tangent attribute to a geometry.

        + Calculates and adds tangent attribute to a geometry. -

        +

        -

        [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

        -

        - geometries -- Array of [page:BufferGeometry BufferGeometry] instances.
        - useGroups -- Whether groups should be generated for the merged geometry or not.

        +

        [method:BufferGeometry mergeBufferGeometries]( [param:Array geometries], [param:Boolean useGroups] )

        +

        + geometries -- Array of [page:BufferGeometry BufferGeometry] instances.
        + useGroups -- Whether groups should be generated for the merged geometry or not.

        - Merges a set of geometries into a single instance. All geometries must have compatible attributes. - If merge does not succeed, the method returns null.

        + Merges a set of geometries into a single instance. All geometries must have compatible attributes. + If merge does not succeed, the method returns null. -

        +

        -

        [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

        -

        - attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

        +

        [method:BufferAttribute mergeBufferAttributes]( [param:Array attributes] )

        +

        + attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

        - Merges a set of attributes into a single instance. All attributes must have compatible properties - and types, and [page:InterleavedBufferAttribute InterleavedBufferAttributes] are not supported. If merge does not succeed, the method - returns null. + Merges a set of attributes into a single instance. All attributes must have compatible properties + and types, and [page:InterleavedBufferAttribute InterleavedBufferAttributes] are not supported. If merge does not succeed, the method + returns null. -

        +

        -

        [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )

        -

        - attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

        +

        [method:InterleavedBufferAttribute interleaveAttributes]( [param:Array attributes] )

        +

        + attributes -- Array of [page:BufferAttribute BufferAttribute] instances.

        - Interleaves a set of attributes and returns a new array of corresponding attributes that share - a single InterleavedBuffer instance. All attributes must have compatible types. If merge does not - succeed, the method returns null. + Interleaves a set of attributes and returns a new array of corresponding attributes that share + a single InterleavedBuffer instance. All attributes must have compatible types. If merge does not + succeed, the method returns null. -

        +

        -

        [method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )

        -

        - geometry -- Instance of [page:BufferGeometry BufferGeometry] to estimate the memory use of.

        +

        [method:Number estimateBytesUsed]( [param:BufferGeometry geometry] )

        +

        + geometry -- Instance of [page:BufferGeometry BufferGeometry] to estimate the memory use of.

        - Returns the amount of bytes used by all attributes to represent the geometry. + Returns the amount of bytes used by all attributes to represent the geometry. -

        +

        -

        [method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [param:Number tolerance] )

        -

        - geometry -- Instance of [page:BufferGeometry BufferGeometry] to merge the vertices of.
        - tolerance -- The maximum allowable difference between vertex attributes to merge. Defaults to 1e-4.

        +

        [method:BufferGeometry mergeVertices]( [param:BufferGeometry geometry], [param:Number tolerance] )

        +

        + geometry -- Instance of [page:BufferGeometry BufferGeometry] to merge the vertices of.
        + tolerance -- The maximum allowable difference between vertex attributes to merge. Defaults to 1e-4.

        - Returns a new [page:BufferGeometry BufferGeometry] with vertices for which all similar vertex attributes - (within tolerance) are merged. + Returns a new [page:BufferGeometry BufferGeometry] with vertices for which all similar vertex attributes + (within tolerance) are merged. -

        +

        -

        Source

        +

        [method:BufferGeometry toTrianglesDrawMode]( [param:BufferGeometry geometry], [param:TrianglesDrawMode drawMode] )

        +

        + geometry -- Instance of [page:BufferGeometry BufferGeometry].
        + drawMode -- The draw mode of the given geometry.

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/BufferGeometryUtils.js examples/js/utils/BufferGeometryUtils.js] - + Returns a new indexed [page:BufferGeometry BufferGeometry] based on the [page:DrawModes THREE.TrianglesDrawMode] draw mode. This mode + corresponds to the *gl.TRIANGLES* WebGL primitive. + +

        + +

        Source

        + +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/BufferGeometryUtils.js examples/jsm/utils/BufferGeometryUtils.js] +

        + diff --git a/docs/examples/zh/utils/SceneUtils.html b/docs/examples/zh/utils/SceneUtils.html index 37e74b5c1a3726..c50671497eb146 100644 --- a/docs/examples/zh/utils/SceneUtils.html +++ b/docs/examples/zh/utils/SceneUtils.html @@ -28,6 +28,8 @@

        [method:Group createMultiMaterialObject]( [param:Geometry geometry], [param:

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/SceneUtils.js examples/js/utils/SceneUtils.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/SceneUtils.js examples/jsm/utils/SceneUtils.js] +

        diff --git a/docs/examples/zh/utils/SkeletonUtils.html b/docs/examples/zh/utils/SkeletonUtils.html index 5e272e6fcb9792..f9adec5a1e2835 100644 --- a/docs/examples/zh/utils/SkeletonUtils.html +++ b/docs/examples/zh/utils/SkeletonUtils.html @@ -55,6 +55,8 @@

        [method:AnimationClip retargetClip]( [param:SkeletonHelper target], [param:S

        Source

        - [link:https://github.com/mrdoob/three.js/blob/master/examples/js/utils/SkeletonUtils.js examples/js/utils/SkeletonUtils.js] +

        + [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/utils/SkeletonUtils.js examples/jsm/utils/SkeletonUtils.js] +

        diff --git a/docs/list.js b/docs/list.js index 2298f5b69494f9..9395b77bb56a02 100644 --- a/docs/list.js +++ b/docs/list.js @@ -10,6 +10,7 @@ var list = { "Browser support": "manual/en/introduction/Browser-support", "WebGL compatibility check": "manual/en/introduction/WebGL-compatibility-check", "How to run things locally": "manual/en/introduction/How-to-run-things-locally", + "Typescript setup": "manual/en/introduction/Typescript-setup", "How to use WebGL 2": "manual/en/introduction/How-to-use-WebGL2", "Drawing lines": "manual/en/introduction/Drawing-lines", "Creating text": "manual/en/introduction/Creating-text", @@ -76,7 +77,6 @@ var list = { "Animation": "api/en/constants/Animation", "Core": "api/en/constants/Core", "CustomBlendingEquation": "api/en/constants/CustomBlendingEquations", - "DrawModes": "api/en/constants/DrawModes", "Materials": "api/en/constants/Materials", "Renderer": "api/en/constants/Renderer", "Textures": "api/en/constants/Textures" @@ -111,7 +111,9 @@ var list = { "Extras": { "Earcut": "api/en/extras/Earcut", - "ShapeUtils": "api/en/extras/ShapeUtils" + "ImageUtils": "api/en/extras/ImageUtils", + "PMREMGenerator": "api/en/extras/PMREMGenerator", + "ShapeUtils": "api/en/extras/ShapeUtils", }, "Extras / Core": { @@ -193,17 +195,13 @@ var list = { "Box3Helper": "api/en/helpers/Box3Helper", "CameraHelper": "api/en/helpers/CameraHelper", "DirectionalLightHelper": "api/en/helpers/DirectionalLightHelper", - "FaceNormalsHelper": "api/en/helpers/FaceNormalsHelper", "GridHelper": "api/en/helpers/GridHelper", "PolarGridHelper": "api/en/helpers/PolarGridHelper", - "PositionalAudioHelper": "api/en/helpers/PositionalAudioHelper", "HemisphereLightHelper": "api/en/helpers/HemisphereLightHelper", "PlaneHelper": "api/en/helpers/PlaneHelper", "PointLightHelper": "api/en/helpers/PointLightHelper", - "RectAreaLightHelper": "api/en/helpers/RectAreaLightHelper", "SkeletonHelper": "api/en/helpers/SkeletonHelper", - "SpotLightHelper": "api/en/helpers/SpotLightHelper", - "VertexNormalsHelper": "api/en/helpers/VertexNormalsHelper" + "SpotLightHelper": "api/en/helpers/SpotLightHelper" }, "Lights": { @@ -217,8 +215,9 @@ var list = { }, "Lights / Shadows": { - "DirectionalLightShadow": "api/en/lights/shadows/DirectionalLightShadow", "LightShadow": "api/en/lights/shadows/LightShadow", + "PointLightShadow": "api/en/lights/shadows/PointLightShadow", + "DirectionalLightShadow": "api/en/lights/shadows/DirectionalLightShadow", "SpotLightShadow": "api/en/lights/shadows/SpotLightShadow" }, @@ -276,7 +275,7 @@ var list = { "Frustum": "api/en/math/Frustum", "Interpolant": "api/en/math/Interpolant", "Line3": "api/en/math/Line3", - "Math": "api/en/math/Math", + "MathUtils": "api/en/math/MathUtils", "Matrix3": "api/en/math/Matrix3", "Matrix4": "api/en/math/Matrix4", "Plane": "api/en/math/Plane", @@ -300,6 +299,7 @@ var list = { "Objects": { "Bone": "api/en/objects/Bone", "Group": "api/en/objects/Group", + "InstancedMesh": "api/en/objects/InstancedMesh", "Line": "api/en/objects/Line", "LineLoop": "api/en/objects/LineLoop", "LineSegments": "api/en/objects/LineSegments", @@ -315,7 +315,7 @@ var list = { "WebGLMultisampleRenderTarget": "api/en/renderers/WebGLMultisampleRenderTarget", "WebGLRenderer": "api/en/renderers/WebGLRenderer", "WebGLRenderTarget": "api/en/renderers/WebGLRenderTarget", - "WebGLRenderTargetCube": "api/en/renderers/WebGLRenderTargetCube" + "WebGLCubeRenderTarget": "api/en/renderers/WebGLCubeRenderTarget" }, "Renderers / Shaders": { @@ -353,7 +353,14 @@ var list = { }, "Controls": { - "OrbitControls": "examples/en/controls/OrbitControls" + "DeviceOrientationControls": "examples/en/controls/DeviceOrientationControls", + "DragControls": "examples/en/controls/DragControls", + "FirstPersonControls": "examples/en/controls/FirstPersonControls", + "FlyControls": "examples/en/controls/FlyControls", + "OrbitControls": "examples/en/controls/OrbitControls", + "PointerLockControls": "examples/en/controls/PointerLockControls", + "TrackballControls": "examples/en/controls/TrackballControls", + "TransformControls": "examples/en/controls/TransformControls" }, "Geometries": { @@ -362,8 +369,16 @@ var list = { "DecalGeometry": "examples/en/geometries/DecalGeometry" }, + "Helpers": { + "FaceNormalsHelper": "examples/en/helpers/FaceNormalsHelper", + "LightProbeHelper": "examples/en/helpers/LightProbeHelper", + "PositionalAudioHelper": "examples/en/helpers/PositionalAudioHelper", + "RectAreaLightHelper": "examples/en/helpers/RectAreaLightHelper", + "VertexNormalsHelper": "examples/en/helpers/VertexNormalsHelper", + "VertexTangentsHelper": "examples/en/helpers/VertexTangentsHelper" + }, + "Loaders": { - "BabylonLoader": "examples/en/loaders/BabylonLoader", "BasisTextureLoader": "examples/en/loaders/BasisTextureLoader", "DRACOLoader": "examples/en/loaders/DRACOLoader", "GLTFLoader": "examples/en/loaders/GLTFLoader", @@ -371,12 +386,12 @@ var list = { "MTLLoader": "examples/en/loaders/MTLLoader", "OBJLoader": "examples/en/loaders/OBJLoader", "OBJLoader2": "examples/en/loaders/OBJLoader2", - "LoaderSupport": "examples/en/loaders/LoaderSupport", + "OBJLoader2Parallel": "examples/en/loaders/OBJLoader2Parallel", "PCDLoader": "examples/en/loaders/PCDLoader", "PDBLoader": "examples/en/loaders/PDBLoader", + "PRWMLoader": "examples/en/loaders/PRWMLoader", "SVGLoader": "examples/en/loaders/SVGLoader", - "TGALoader": "examples/en/loaders/TGALoader", - "PRWMLoader": "examples/en/loaders/PRWMLoader" + "TGALoader": "examples/en/loaders/TGALoader" }, "Objects": { @@ -393,8 +408,9 @@ var list = { "ColladaExporter": "examples/en/exporters/ColladaExporter" }, - "Plugins": { - "LookupTable": "examples/en/Lut", + "Math": { + "LookupTable": "examples/en/math/Lut", + "MeshSurfaceSampler": "examples/en/math/MeshSurfaceSampler", }, "ConvexHull": { @@ -446,6 +462,7 @@ var list = { "浏览器支持": "manual/zh/introduction/Browser-support", "WebGL兼容性检查": "manual/zh/introduction/WebGL-compatibility-check", "如何在本地运行Three.js": "manual/zh/introduction/How-to-run-things-locally", + "Typescript setup": "manual/zh/introduction/Typescript-setup", "如何使用WebGL 2": "manual/zh/introduction/How-to-use-WebGL2", "画线": "manual/zh/introduction/Drawing-lines", "创建文字": "manual/zh/introduction/Creating-text", @@ -458,7 +475,7 @@ var list = { "如何更新场景": "manual/zh/introduction/How-to-update-things", "如何废置对象": "manual/zh/introduction/How-to-dispose-of-objects", "如何创建VR内容": "manual/zh/introduction/How-to-create-VR-content", - "How to use post-processing": "manual/zh/introduction/How-to-use-post-processing", + "如何使用后期处理": "manual/zh/introduction/How-to-use-post-processing", "矩阵变换": "manual/zh/introduction/Matrix-transformations", "动画系统": "manual/zh/introduction/Animation-system" }, @@ -512,7 +529,6 @@ var list = { "Animation": "api/zh/constants/Animation", "Core": "api/zh/constants/Core", "CustomBlendingEquation": "api/zh/constants/CustomBlendingEquations", - "DrawModes": "api/zh/constants/DrawModes", "Materials": "api/zh/constants/Materials", "Renderer": "api/zh/constants/Renderer", "Textures": "api/zh/constants/Textures" @@ -547,6 +563,8 @@ var list = { "附件": { "Earcut": "api/zh/extras/Earcut", + "ImageUtils": "api/zh/extras/ImageUtils", + "PMREMGenerator": "api/zh/extras/PMREMGenerator", "ShapeUtils": "api/zh/extras/ShapeUtils" }, @@ -629,17 +647,13 @@ var list = { "Box3Helper": "api/zh/helpers/Box3Helper", "CameraHelper": "api/zh/helpers/CameraHelper", "DirectionalLightHelper": "api/zh/helpers/DirectionalLightHelper", - "FaceNormalsHelper": "api/zh/helpers/FaceNormalsHelper", "GridHelper": "api/zh/helpers/GridHelper", "PolarGridHelper": "api/zh/helpers/PolarGridHelper", - "PositionalAudioHelper": "api/zh/helpers/PositionalAudioHelper", "HemisphereLightHelper": "api/zh/helpers/HemisphereLightHelper", "PlaneHelper": "api/zh/helpers/PlaneHelper", "PointLightHelper": "api/zh/helpers/PointLightHelper", - "RectAreaLightHelper": "api/zh/helpers/RectAreaLightHelper", "SkeletonHelper": "api/zh/helpers/SkeletonHelper", - "SpotLightHelper": "api/zh/helpers/SpotLightHelper", - "VertexNormalsHelper": "api/zh/helpers/VertexNormalsHelper" + "SpotLightHelper": "api/zh/helpers/SpotLightHelper" }, "灯光": { @@ -653,8 +667,9 @@ var list = { }, "灯光 / 阴影": { - "DirectionalLightShadow": "api/zh/lights/shadows/DirectionalLightShadow", "LightShadow": "api/zh/lights/shadows/LightShadow", + "PointLightShadow": "api/zh/lights/shadows/PointLightShadow", + "DirectionalLightShadow": "api/zh/lights/shadows/DirectionalLightShadow", "SpotLightShadow": "api/zh/lights/shadows/SpotLightShadow" }, @@ -712,7 +727,7 @@ var list = { "Frustum": "api/zh/math/Frustum", "Interpolant": "api/zh/math/Interpolant", "Line3": "api/zh/math/Line3", - "Math": "api/zh/math/Math", + "MathUtils": "api/zh/math/MathUtils", "Matrix3": "api/zh/math/Matrix3", "Matrix4": "api/zh/math/Matrix4", "Plane": "api/zh/math/Plane", @@ -736,6 +751,7 @@ var list = { "物体": { "Bone": "api/zh/objects/Bone", "Group": "api/zh/objects/Group", + "InstancedMesh": "api/zh/objects/InstancedMesh", "Line": "api/zh/objects/Line", "LineLoop": "api/zh/objects/LineLoop", "LineSegments": "api/zh/objects/LineSegments", @@ -751,7 +767,7 @@ var list = { "WebGLMultisampleRenderTarget": "api/zh/renderers/WebGLMultisampleRenderTarget", "WebGLRenderer": "api/zh/renderers/WebGLRenderer", "WebGLRenderTarget": "api/zh/renderers/WebGLRenderTarget", - "WebGLRenderTargetCube": "api/zh/renderers/WebGLRenderTargetCube" + "WebGLCubeRenderTarget": "api/zh/renderers/WebGLCubeRenderTarget" }, "渲染器 / 着色器": { @@ -789,7 +805,14 @@ var list = { }, "控制": { - "OrbitControls": "examples/zh/controls/OrbitControls" + "DeviceOrientationControls": "examples/zh/controls/DeviceOrientationControls", + "DragControls": "examples/zh/controls/DragControls", + "FirstPersonControls": "examples/zh/controls/FirstPersonControls", + "FlyControls": "examples/zh/controls/FlyControls", + "OrbitControls": "examples/zh/controls/OrbitControls", + "PointerLockControls": "examples/zh/controls/PointerLockControls", + "TrackballControls": "examples/zh/controls/TrackballControls", + "TransformControls": "examples/zh/controls/TransformControls" }, "几何体": { @@ -798,56 +821,67 @@ var list = { "DecalGeometry": "examples/zh/geometries/DecalGeometry" }, + "辅助对象": { + "FaceNormalsHelper": "examples/zh/helpers/FaceNormalsHelper", + "LightProbeHelper": "examples/zh/helpers/LightProbeHelper", + "PositionalAudioHelper": "examples/zh/helpers/PositionalAudioHelper", + "RectAreaLightHelper": "examples/zh/helpers/RectAreaLightHelper", + "VertexNormalsHelper": "examples/zh/helpers/VertexNormalsHelper", + "VertexTangentsHelper": "examples/zh/helpers/VertexTangentsHelper" + }, + "加载器": { - "BabylonLoader": "examples/zh/loaders/BabylonLoader", + "BasisTextureLoader": "examples/zh/loaders/BasisTextureLoader", + "DRACOLoader": "examples/zh/loaders/DRACOLoader", "GLTFLoader": "examples/zh/loaders/GLTFLoader", "MMDLoader": "examples/zh/loaders/MMDLoader", "MTLLoader": "examples/zh/loaders/MTLLoader", "OBJLoader": "examples/zh/loaders/OBJLoader", "OBJLoader2": "examples/zh/loaders/OBJLoader2", - "LoaderSupport": "examples/zh/loaders/LoaderSupport", "PCDLoader": "examples/zh/loaders/PCDLoader", "PDBLoader": "examples/zh/loaders/PDBLoader", + "PRWMLoader": "examples/zh/loaders/PRWMLoader", "SVGLoader": "examples/zh/loaders/SVGLoader", - "TGALoader": "examples/zh/loaders/TGALoader", - "PRWMLoader": "examples/zh/loaders/PRWMLoader" + "TGALoader": "examples/zh/loaders/TGALoader" }, "物体": { "Lensflare": "examples/zh/objects/Lensflare", }, - "Post-Processing": { + "后期处理": { "EffectComposer": "examples/zh/postprocessing/EffectComposer" }, "导出器": { "GLTFExporter": "examples/zh/exporters/GLTFExporter", - "PLYExporter": "examples/zh/exporters/PLYExporter" + "PLYExporter": "examples/zh/exporters/PLYExporter", + "ColladaExporter": "examples/zh/exporters/ColladaExporter" }, - "插件": { - "LookupTable": "examples/zh/Lut", + "数学库": { + "LookupTable": "examples/zh/math/Lut", + "MeshSurfaceSampler": "examples/zh/math/MeshSurfaceSampler", }, "QuickHull": { - "Face": "examples/zh/quickhull/Face", - "HalfEdge": "examples/zh/quickhull/HalfEdge", - "QuickHull": "examples/zh/quickhull/QuickHull", - "VertexNode": "examples/zh/quickhull/VertexNode", - "VertexList": "examples/zh/quickhull/VertexList" + "Face": "examples/zh/math/convexhull/Face", + "HalfEdge": "examples/zh/math/convexhull/HalfEdge", + "ConvexHull": "examples/zh/math/convexhull/ConvexHull", + "VertexNode": "examples/zh/math/convexhull/VertexNode", + "VertexList": "examples/zh/math/convexhull/VertexList" }, "渲染器": { "CSS2DRenderer": "examples/zh/renderers/CSS2DRenderer", "CSS3DRenderer": "examples/zh/renderers/CSS3DRenderer", "SVGRenderer": "examples/zh/renderers/SVGRenderer" - }, "实用工具": { "BufferGeometryUtils": "examples/zh/utils/BufferGeometryUtils", - "SceneUtils": "examples/zh/utils/SceneUtils" + "SceneUtils": "examples/zh/utils/SceneUtils", + "SkeletonUtils": "examples/zh/utils/SkeletonUtils" } }, diff --git a/docs/manual/en/introduction/Animation-system.html b/docs/manual/en/introduction/Animation-system.html index eaf6e104c1d022..7a3a6784decedc 100644 --- a/docs/manual/en/introduction/Animation-system.html +++ b/docs/manual/en/introduction/Animation-system.html @@ -36,7 +36,7 @@

        Animation Clips

        If you have successfully imported an animated 3D object (it doesn't matter if it has bones or morph targets or both) — for example exporting it from Blender with the - [link:https://github.com/KhronosGroup/glTF-Blender-Exporter glTF Blender exporter] and + [link:https://github.com/KhronosGroup/glTF-Blender-IO glTF Blender exporter] and loading it into a three.js scene using [page:GLTFLoader] — one of the response fields should be an array named "animations", containing the [page:AnimationClip AnimationClips] for this model (see a list of possible loaders below).

        @@ -113,7 +113,6 @@

        Supported Formats and Loaders

      • THREE.FBXLoader
      • [page:GLTFLoader THREE.GLTFLoader]
      • THREE.MMDLoader
      • -
      • THREE.SEA3DLoader

      diff --git a/docs/manual/en/introduction/Browser-support.html b/docs/manual/en/introduction/Browser-support.html index ea51237b4a488f..0b63f829920b6f 100644 --- a/docs/manual/en/introduction/Browser-support.html +++ b/docs/manual/en/introduction/Browser-support.html @@ -13,7 +13,7 @@

      [name]

      Overview

      - Three.js can use WebGL to render your scenes on all modern browsers. For older browsers, especially Internet Explorer 10 and below, you may have to fallback to one of the other [link:https://github.com/mrdoob/three.js/tree/master/examples/js/renderers renderers] (CSS2DRenderer, CSS3DRenderer, SVGRenderer). Additionally, you may have to include some polyfills, especially if you are using files from the [link:https://github.com/mrdoob/three.js/tree/master/examples /examples] folder. + Three.js can use WebGL to render your scenes on all modern browsers. For older browsers, especially Internet Explorer 10 and below, you may have to fallback to one of the other [link:https://github.com/mrdoob/three.js/tree/master/examples/jsm/renderers renderers] (CSS2DRenderer, CSS3DRenderer, SVGRenderer). Additionally, you may have to include some polyfills, especially if you are using files from the [link:https://github.com/mrdoob/three.js/tree/master/examples /examples] folder.

      Note: if you don't need to support these old browsers, then it is not recommended to use the other renderers as they are slower and support less features than the WebGLRenderer. @@ -52,9 +52,9 @@

      JavaScript Language Features or Web APIs Used in three.js

      Audio, AudioContext, AudioListener, etc. - WebVR API + WebXR Device API Source - WebVRManager, etc. + WebXRManager Blob @@ -64,7 +64,7 @@

      JavaScript Language Features or Web APIs Used in three.js

      Promise Examples - GLTFLoader, GLTFExporter, WebVR, VREffect, etc. + GLTFLoader, DRACOLoader, BasisTextureLoader, GLTFExporter, VRButton, ARButton, etc. Fetch diff --git a/docs/manual/en/introduction/Creating-a-scene.html b/docs/manual/en/introduction/Creating-a-scene.html index 8b21df630c4587..d797090b90c7a8 100644 --- a/docs/manual/en/introduction/Creating-a-scene.html +++ b/docs/manual/en/introduction/Creating-a-scene.html @@ -24,7 +24,7 @@

      Before we start

      <title>My first three.js app</title> <style> body { margin: 0; } - canvas { width: 100%; height: 100% } + canvas { display: block; } </style> </head> <body> @@ -72,7 +72,7 @@

      Creating the scene

      "That's all good, but where's that cube you promised?" Let's add it now.

      - var geometry = new THREE.BoxGeometry( 1, 1, 1 ); + var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); @@ -126,7 +126,7 @@

      The result

      <title>My first three.js app</title> <style> body { margin: 0; } - canvas { width: 100%; height: 100% } + canvas { display: block; } </style> </head> <body> @@ -139,7 +139,7 @@

      The result

      renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); - var geometry = new THREE.BoxGeometry( 1, 1, 1 ); + var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); diff --git a/docs/manual/en/introduction/Creating-text.html b/docs/manual/en/introduction/Creating-text.html index 77b98802492c28..223ae0f246bce7 100644 --- a/docs/manual/en/introduction/Creating-text.html +++ b/docs/manual/en/introduction/Creating-text.html @@ -76,14 +76,17 @@

      4. Procedural Text Geometry

      Examples

      - [example:webgl_geometry_text WebGL / geometry / text]
      - [example:webgl_shadowmap WebGL / shadowmap] + +

      + [example:webgl_geometry_text WebGL / geometry / text]
      + [example:webgl_shadowmap WebGL / shadowmap] +

      If Typeface is down, or you want to use a font that is not there, there's a tutorial with a python script for blender that allows you to export text to Three.js's JSON format: [link:http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html] -

      +

      diff --git a/docs/manual/en/introduction/Drawing-lines.html b/docs/manual/en/introduction/Drawing-lines.html index 8572d36f977a28..72ae6a13728ebd 100644 --- a/docs/manual/en/introduction/Drawing-lines.html +++ b/docs/manual/en/introduction/Drawing-lines.html @@ -34,15 +34,16 @@

      [name]

      - After material we will need a [page:Geometry] or [page:BufferGeometry] with some vertices - (it's recommended to use a BufferGeometry as it's more performant, however for simplicity we'll use a Geometry here): + After material we will need a geometry with some vertices:

      -var geometry = new THREE.Geometry(); -geometry.vertices.push(new THREE.Vector3( -10, 0, 0) ); -geometry.vertices.push(new THREE.Vector3( 0, 10, 0) ); -geometry.vertices.push(new THREE.Vector3( 10, 0, 0) ); +var points = []; +points.push( new THREE.Vector3( - 10, 0, 0 ) ); +points.push( new THREE.Vector3( 0, 10, 0 ) ); +points.push( new THREE.Vector3( 10, 0, 0 ) ); + +var geometry = new THREE.BufferGeometry().setFromPoints( points );

      Note that lines are drawn between each consecutive pair of vertices, but not between the first and last (the line is not closed.)

      diff --git a/docs/manual/en/introduction/FAQ.html b/docs/manual/en/introduction/FAQ.html index 6c105ec9c2e889..f2d5b75a5a6d87 100644 --- a/docs/manual/en/introduction/FAQ.html +++ b/docs/manual/en/introduction/FAQ.html @@ -22,7 +22,7 @@

      Which 3D model format is best supported?

      Why are there meta viewport tags in examples?

      -
      <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
      + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

      These tags control viewport size and scale for mobile browsers (where page content may be rendered at different size than visible viewport).

      diff --git a/docs/manual/en/introduction/How-to-create-VR-content.html b/docs/manual/en/introduction/How-to-create-VR-content.html index 45231e99e9470b..723f795dba50f9 100644 --- a/docs/manual/en/introduction/How-to-create-VR-content.html +++ b/docs/manual/en/introduction/How-to-create-VR-content.html @@ -20,30 +20,30 @@

      [name]

      Workflow

      - First, you have to include [link:https://github.com/mrdoob/three.js/blob/master/examples/js/vr/WebVR.js WebVR.js] + First, you have to include [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/VRButton.js VRButton.js] into your project.

      -import { WEBVR } from 'three/examples/jsm/vr/WebVR.js'; +import { VRButton } from 'three/examples/jsm/webxr/VRButton.js';

      - *WEBVR.createButton()* does two important things: It creates a button which indicates + *VRButton.createButton()* does two important things: It creates a button which indicates VR compatibility. Besides, it initiates a VR session if the user activates the button. The only thing you have to do is to add the following line of code to your app.

      -document.body.appendChild( WEBVR.createButton( renderer ) ); +document.body.appendChild( VRButton.createButton( renderer ) );

      - Next, you have to tell your instance of *WebGLRenderer* to enable VR rendering. + Next, you have to tell your instance of *WebGLRenderer* to enable XR rendering.

      -renderer.vr.enabled = true; +renderer.xr.enabled = true;

      @@ -65,17 +65,17 @@

      Next Steps

      Have a look at one of the official WebVR examples to see this workflow in action.

      - [example:webvr_ballshooter WebVR / ballshoter]
      - [example:webvr_cubes WebVR / cubes]
      - [example:webvr_dragging WebVR / dragging]
      - [example:webvr_lorenzattractor WebVR / lorenzattractor]
      - [example:webvr_panorama WebVR / panorama]
      - [example:webvr_paint WebVR / paint]
      - [example:webvr_rollercoaster WebVR / rollercoaster]
      - [example:webvr_sandbox WebVR / sandbox]
      - [example:webvr_sculpt WebVR / sculpt]
      - [example:webvr_vive_paint WebVR / vive / paint]
      - [example:webvr_vive_sculpt WebVR / vive / sculpt]
      + [example:webxr_vr_ballshooter WebXR / VR / ballshooter]
      + [example:webxr_vr_cubes WebXR / VR / cubes]
      + [example:webxr_vr_dragging WebXR / VR / dragging]
      + [example:webxr_vr_lorenzattractor WebXR / VR / lorenzattractor]
      + [example:webxr_vr_paint WebXR / VR / paint]
      + [example:webxr_vr_panorama_depth WebXR / VR / panorama_depth]
      + [example:webxr_vr_panorama WebXR / VR / panorama]
      + [example:webxr_vr_rollercoaster WebXR / VR / rollercoaster]
      + [example:webxr_vr_sandbox WebXR / VR / sandbox]
      + [example:webxr_vr_sculpt WebXR / VR / sculpt]
      + [example:webxr_vr_video WebXR / VR / video]

      diff --git a/docs/manual/en/introduction/How-to-dispose-of-objects.html b/docs/manual/en/introduction/How-to-dispose-of-objects.html index 2d010b13bbea08..9bf5dd76a3315f 100644 --- a/docs/manual/en/introduction/How-to-dispose-of-objects.html +++ b/docs/manual/en/introduction/How-to-dispose-of-objects.html @@ -92,11 +92,6 @@

      Does *three.js* provide information about the amount of cached objects?

      in your application, it's a good idea to debug this property in order to easily identify a memory leak.

      -

      - Internal resources for a texture are only allocated if the image has fully loaded. If you dispose a texture before the image was loaded, - nothing happens. No resources were allocated so there is also no need for clean up. -

      -

      What happens when you call *dispose()* on a texture but the image is not loaded yet?

      diff --git a/docs/manual/en/introduction/How-to-run-things-locally.html b/docs/manual/en/introduction/How-to-run-things-locally.html index f30bd5c61798d9..84b0b9fb247649 100644 --- a/docs/manual/en/introduction/How-to-run-things-locally.html +++ b/docs/manual/en/introduction/How-to-run-things-locally.html @@ -49,7 +49,14 @@

      Run a local server

      three.js application.

      -

      Node.js server

      +

      Servez

      +
      +

      + [link:https://greggman.github.io/servez Servez] is a simple server with a GUI. +

      +
      + +

      Node.js http-server

      Node.js has a simple HTTP server package. To install:

      npm install http-server -g @@ -123,8 +130,8 @@

      Lighttpd

      IIS

      -

      If you are using Microsoft IIS as web server. Please add a MIME type settings regarding .fbx externsion before loading.

      - File name externsion: fbx MIME Type: text/plain +

      If you are using Microsoft IIS as web server. Please add a MIME type settings regarding .fbx extension before loading.

      + File name extension: fbx MIME Type: text/plain

      By default, IIS blocks .fbx, .obj files downloads. You have to configure IIS to enable these kind of files can be download.

      diff --git a/docs/manual/en/introduction/How-to-update-things.html b/docs/manual/en/introduction/How-to-update-things.html index 2a7f0f5b32caff..f94b3a70f66c13 100644 --- a/docs/manual/en/introduction/How-to-update-things.html +++ b/docs/manual/en/introduction/How-to-update-things.html @@ -32,33 +32,31 @@

      [name]

      object.updateMatrix();
      -

      Geometries

      +

      BufferGeometry

      -

      [page:BufferGeometry]

      -
      -

      - BufferGeometries store information (such as vertex positions, face indices, normals, colors, - UVs, and any custom attributes) in [page:BufferAttribute buffers] - that is, - [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays typed arrays]. - This makes them generally faster than standard Geometries, at the cost of being somewhat harder to - work with. -

      -

      - With regards to updating BufferGeometries, the most important thing to understand is that - you cannot resize buffers (this is very costly, basically the equivalent to creating a new geometry). - You can however update the content of buffers. -

      -

      - This means that if you know an attribute of your BufferGeometry will grow, say the number of vertices, - you must pre-allocate a buffer large enough to hold any new vertices that may be created. Of - course, this also means that there will be a maximum size for your BufferGeometry - there is - no way to create a BufferGeometry that can efficiently be extended indefinitely. -

      -

      - We'll use the example of a line that gets extended at render time. We'll allocate space - in the buffer for 500 vertices but draw only two at first, using [page:BufferGeometry.drawRange]. -

      - +

      + BufferGeometries store information (such as vertex positions, face indices, normals, colors, + UVs, and any custom attributes) in [page:BufferAttribute buffers] - that is, + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays typed arrays]. + This makes them generally faster than standard Geometries, at the cost of being somewhat harder to + work with. +

      +

      + With regards to updating BufferGeometries, the most important thing to understand is that + you cannot resize buffers (this is very costly, basically the equivalent to creating a new geometry). + You can however update the content of buffers. +

      +

      + This means that if you know an attribute of your BufferGeometry will grow, say the number of vertices, + you must pre-allocate a buffer large enough to hold any new vertices that may be created. Of + course, this also means that there will be a maximum size for your BufferGeometry - there is + no way to create a BufferGeometry that can efficiently be extended indefinitely. +

      +

      + We'll use the example of a line that gets extended at render time. We'll allocate space + in the buffer for 500 vertices but draw only two at first, using [page:BufferGeometry.drawRange]. +

      + var MAX_POINTS = 500; // geometry @@ -66,23 +64,23 @@

      [page:BufferGeometry]

      // attributes var positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point -geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); +geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); // draw range var drawCount = 2; // draw the first 2 points, only geometry.setDrawRange( 0, drawCount ); // material -var material = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 2 } ); +var material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); // line var line = new THREE.Line( geometry, material ); scene.add( line ); -
      -

      - Next we'll randomly add points to the line using a pattern like: -

      - + +

      + Next we'll randomly add points to the line using a pattern like: +

      + var positions = line.geometry.attributes.position.array; var x, y, z, index; @@ -99,50 +97,52 @@

      [page:BufferGeometry]

      z += ( Math.random() - 0.5 ) * 30; } -
      -

      - If you want to change the number of points rendered after the first render, do this: -

      - + +

      + If you want to change the number of points rendered after the first render, do this: +

      + line.geometry.setDrawRange( 0, newValue ); - -

      - If you want to change the position data values after the first render, you need to - set the needsUpdate flag like so: -

      - + +

      + If you want to change the position data values after the first render, you need to + set the needsUpdate flag like so: +

      + line.geometry.attributes.position.needsUpdate = true; // required after the first render - +
      -

      - If you change the position data values after the initial render, you may need to - call `.computeBoundingSphere()` in order to recalculate the geometry's bounding sphere. -

      - +

      + If you change the position data values after the initial render, you may need to + call `.computeBoundingSphere()` in order to recalculate the geometry's bounding sphere. +

      + line.geometry.computeBoundingSphere(); - +
      -

      - [link:http://jsfiddle.net/w67tzfhx/ Here is a fiddle] showing an animated line which you can adapt to your use case. -

      +

      + [link:http://jsfiddle.net/w67tzfhx/ Here is a fiddle] showing an animated line which you can adapt to your use case. +

      -

      Examples:

      - [example:webgl_custom_attributes WebGL / custom / attributes]
      - [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles] +

      Examples

      +

      + [example:webgl_custom_attributes WebGL / custom / attributes]
      + [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles] +

      -
      +
      -

      [page:Geometry]

      -
      -

      - The following flags control updating of various geometry attributes. Set flags only - for attributes that you need to update, updates are costly. Once buffers - change, these flags reset automatically back to false. You need to keep setting them to - true if you want to keep updating buffers. Note that this applies only to [page:Geometry] - and not to [page:BufferGeometry]. -

      - +

      Geometry

      +
      +

      + The following flags control updating of various geometry attributes. Set flags only + for attributes that you need to update, updates are costly. Once buffers + change, these flags reset automatically back to false. You need to keep setting them to + true if you want to keep updating buffers. Note that this applies only to [page:Geometry] + and not to [page:BufferGeometry]. +

      + var geometry = new THREE.Geometry(); geometry.verticesNeedUpdate = true; geometry.elementsNeedUpdate = true; @@ -151,27 +151,20 @@

      [page:Geometry]

      geometry.normalsNeedUpdate = true; geometry.colorsNeedUpdate = true; geometry.tangentsNeedUpdate = true; -
      - -

      - In versions prior to [link:https://github.com/mrdoob/three.js/releases/tag/r66 r66] meshes - additionally need the dynamic flag enabled (to keep internal typed arrays): -

      +
      - - //removed after r66 - geometry.dynamic = true; - +

      + In versions prior to [link:https://github.com/mrdoob/three.js/releases/tag/r66 r66] meshes + additionally need the dynamic flag enabled (to keep internal typed arrays): +

      -

      Examples:

      - [example:webgl_geometry_dynamic WebGL / geometry / dynamic]
      -
      + + //removed after r66 + geometry.dynamic = true; +
      - - -

      Materials

      All uniforms values can be changed freely (e.g. colors, textures, opacity, etc), values are sent to the shader every frame.

      @@ -181,7 +174,6 @@

      Materials

      The following properties can't be easily changed at runtime (once the material is rendered at least once):

      • numbers and types of uniforms
      • -
      • numbers and types of lights
      • presence or not of
        • texture
        • @@ -209,9 +201,11 @@

          If you need to have different configurations of materials during runtime:If the number is large (e.g. each face could be potentially different), consider a different solution, such as using attributes / textures to drive different per-face look.

          -

          Examples:

          - [example:webgl_materials_cars WebGL / materials / cars]
          - [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof] +

          Examples

          +

          + [example:webgl_materials_car WebGL / materials / car]
          + [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof] +

      @@ -223,9 +217,11 @@

      Textures

      Render targets update automatically.

      -

      Examples:

      - [example:webgl_materials_video WebGL / materials / video]
      - [example:webgl_rtt WebGL / rtt] +

      Examples

      +

      + [example:webgl_materials_video WebGL / materials / video]
      + [example:webgl_rtt WebGL / rtt] +

      diff --git a/docs/manual/en/introduction/Loading-3D-models.html b/docs/manual/en/introduction/Loading-3D-models.html index 723d90df12a0f5..cd6e529b3b2451 100644 --- a/docs/manual/en/introduction/Loading-3D-models.html +++ b/docs/manual/en/introduction/Loading-3D-models.html @@ -15,7 +15,7 @@

      [name]

      3D models are available in hundreds of file formats, each with different purposes, assorted features, and varying complexity. Although - + three.js provides many loaders, choosing the right format and workflow will save time and frustration later on. Some formats are difficult to work with, inefficient for realtime experiences, or simply not @@ -149,6 +149,9 @@

      Troubleshooting

      scaled differently, and large models may not appear if the camera is inside the model. +
    • + Try to add and position a light source. The model may be hidden in the dark. +
    • Look for failed texture requests in the network tab, like C:\\Path\To\Model\texture.jpg. Use paths relative to your diff --git a/docs/manual/en/introduction/Matrix-transformations.html b/docs/manual/en/introduction/Matrix-transformations.html index 1f93a5abc5897f..077f7a29eaa42b 100644 --- a/docs/manual/en/introduction/Matrix-transformations.html +++ b/docs/manual/en/introduction/Matrix-transformations.html @@ -16,7 +16,9 @@

      [name]

      Convenience properties and *matrixAutoUpdate*

      - There are two ways to update an object's transformation: +

      + There are two ways to update an object's transformation: +

      1. Modify the object's *position*, *quaternion*, and *scale* properties, and let three.js recompute diff --git a/docs/manual/en/introduction/Typescript-setup.html b/docs/manual/en/introduction/Typescript-setup.html new file mode 100644 index 00000000000000..863ce5cf0a43d1 --- /dev/null +++ b/docs/manual/en/introduction/Typescript-setup.html @@ -0,0 +1,46 @@ + + + + + + + + + + +

        [name]

        + +

        + three.js is a JavaScript-based library. However, it's possible to use it in a TypeScript project, as the library + exposes [link:https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html Declaration Files] (*d.ts* files). +

        + +

        + A minimal configuration is required for the TypeScript compiler to + discover three.js types.
        + You will need to set the [link:https://www.typescriptlang.org/docs/handbook/module-resolution.html moduleResolution] + option to *node*, and the [link:https://www.typescriptlang.org/docs/handbook/compiler-options.html target] option to *es6* or newer. +

        + + + // Example of minimal `tsconfig.json` file + { + "compilerOptions": { + "target": "es6", + "moduleResolution": "node", + }, + "include": [ "./src/**/*.ts" ], + } + + +

        + Note: As of today, it's not yet possible to use three.js typings without using those two options. +

        + +

        + Note: It happens that some declarations are incorrect and/or missing. + Contributing to Declaration Files is really helpful for the community, making three.js + typings better and more accurate. +

        + + diff --git a/docs/manual/zh/introduction/Animation-system.html b/docs/manual/zh/introduction/Animation-system.html index 095a150b6010c0..4e592316999258 100644 --- a/docs/manual/zh/introduction/Animation-system.html +++ b/docs/manual/zh/introduction/Animation-system.html @@ -90,7 +90,6 @@

        支持的格式和加载器(Supported Formats and Loaders)

      2. THREE.FBXLoader
      3. [page:GLTFLoader THREE.GLTFLoader]
      4. THREE.MMDLoader
      5. -
      6. THREE.SEA3DLoader

    diff --git a/docs/manual/zh/introduction/Browser-support.html b/docs/manual/zh/introduction/Browser-support.html index dba7cbf7041c36..cdaebaa73f9d29 100644 --- a/docs/manual/zh/introduction/Browser-support.html +++ b/docs/manual/zh/introduction/Browser-support.html @@ -13,7 +13,7 @@

    浏览器支持([name])

    总览

    - 在所有现代浏览器中,Three.js可以使用WebGL来渲染场景。对于较旧的浏览器,特别是Internet Explorer 10或者更低版本浏览器,你将需要回落到其它[link:https://github.com/mrdoob/three.js/tree/master/examples/js/renderers renderers](CSS2DRenderer、CSS3DRenderer、SVGRenderer)。此外,你或许不得不包含一些额外的“填充物”来解决兼容性问题,特别是当你使用[link:https://github.com/mrdoob/three.js/tree/master/examples /examples]目录中的文件时。 + 在所有现代浏览器中,Three.js可以使用WebGL来渲染场景。对于较旧的浏览器,特别是Internet Explorer 10或者更低版本浏览器,你将需要回落到其它[link:https://github.com/mrdoob/three.js/tree/master/examples/jsm/renderers renderers](CSS2DRenderer、CSS3DRenderer、SVGRenderer)。此外,你或许不得不包含一些额外的“填充物”来解决兼容性问题,特别是当你使用[link:https://github.com/mrdoob/three.js/tree/master/examples /examples]目录中的文件时。

    注意:如果你并不需要支持较旧的浏览器,那就不推荐使用其他渲染器来进行渲染,因为与WebGLRenderer相比,其它渲染器渲染较慢,并且不支持WebGL的诸多特性。 @@ -54,9 +54,9 @@

    Audio, AudioContext, AudioListener, etc. - WebVR API + WebXR Device API Source - WebVRManager, etc. + WebXRManager Blob @@ -66,7 +66,7 @@

    Promise Examples - GLTFLoader, GLTFExporter, WebVR, VREffect, etc. + GLTFLoader, DRACOLoader, BasisTextureLoader, GLTFExporter, VRButton, ARButton, etc. Fetch diff --git a/docs/manual/zh/introduction/Creating-a-scene.html b/docs/manual/zh/introduction/Creating-a-scene.html index b8d63faa3d5a83..fb0cfd07b5d80e 100644 --- a/docs/manual/zh/introduction/Creating-a-scene.html +++ b/docs/manual/zh/introduction/Creating-a-scene.html @@ -24,7 +24,7 @@

    开始之前

    <title>My first three.js app</title> <style> body { margin: 0; } - canvas { width: 100%; height: 100% } + canvas { display: block; } </style> </head> <body> @@ -72,7 +72,7 @@

    创建一个场景

    “嗯,看起来很不错,那你说的那个立方体在哪儿?”接下来,我们就来添加立方体。

    - var geometry = new THREE.BoxGeometry( 1, 1, 1 ); + var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); @@ -119,7 +119,7 @@

    使立方体动起来

    结果

    祝贺你!你现在已经成功完成了你的第一个Three.js应用程序。虽然它很简单,但现在你已经有了一个入门的起点。

    -

    下面是完整的代码,运行或者修改代码从而有助于你更好的理解它是如何工作的。

    +

    下面是完整的代码,可在[link:https://jsfiddle.net/mkba0ecu/ live example]运行、编辑;运行或者修改代码有助于你更好的理解它是如何工作的。

    <html> @@ -127,7 +127,7 @@

    结果

    <title>My first three.js app</title> <style> body { margin: 0; } - canvas { width: 100%; height: 100% } + canvas { display: block; } </style> </head> <body> @@ -140,7 +140,7 @@

    结果

    renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); - var geometry = new THREE.BoxGeometry( 1, 1, 1 ); + var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); diff --git a/docs/manual/zh/introduction/Creating-text.html b/docs/manual/zh/introduction/Creating-text.html index 825f91cd5800c1..d21c93de6b913e 100644 --- a/docs/manual/zh/introduction/Creating-text.html +++ b/docs/manual/zh/introduction/Creating-text.html @@ -70,14 +70,15 @@

    4. three.js自带的文字几何体

    示例

    - [example:webgl_geometry_text WebGL / geometry / text]
    - [example:canvas_geometry_text canvas / geometry / text]
    - [example:webgl_shadowmap WebGL / shadowmap] +

    + [example:webgl_geometry_text WebGL / geometry / text]
    + [example:webgl_shadowmap WebGL / shadowmap] +

    如果Typeface已经关闭,或者没有你所想使用的字体,这有一个教程:[link:http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html]
    这是一个在blender上运行的python脚本,能够让你将文字导出为Three.js的JSON格式。 -

    +

    diff --git a/docs/manual/zh/introduction/Drawing-lines.html b/docs/manual/zh/introduction/Drawing-lines.html index 12e030549cfda0..7f37adf8ffa3de 100644 --- a/docs/manual/zh/introduction/Drawing-lines.html +++ b/docs/manual/zh/introduction/Drawing-lines.html @@ -37,14 +37,15 @@

    画线([name])

    定义好材质之后,我们需要一个带有一些顶点的[page:Geometry] 或者 [page:BufferGeometry]。 - (推荐使用BufferGeometry,因为它在性能上表现得会更好一些;但在这里,为了简单起见,我们使用Geometry):

    -var geometry = new THREE.Geometry(); -geometry.vertices.push(new THREE.Vector3( -10, 0, 0) ); -geometry.vertices.push(new THREE.Vector3( 0, 10, 0) ); -geometry.vertices.push(new THREE.Vector3( 10, 0, 0) ); +var points = []; +points.push( new THREE.Vector3( - 10, 0, 0 ) ); +points.push( new THREE.Vector3( 0, 10, 0 ) ); +points.push( new THREE.Vector3( 10, 0, 0 ) ); + +var geometry = new THREE.BufferGeometry().setFromPoints( points );

    注意,线是画在每一对连续的顶点之间的,而不是在第一个顶点和最后一个顶点之间绘制线条(线条并未闭合)。

    diff --git a/docs/manual/zh/introduction/FAQ.html b/docs/manual/zh/introduction/FAQ.html index b5e023d767bd9d..e4d93ea4ac6407 100644 --- a/docs/manual/zh/introduction/FAQ.html +++ b/docs/manual/zh/introduction/FAQ.html @@ -15,8 +15,8 @@

    哪一种三维物体格式能够得到最好地支持?

    推荐使用glTF(gl传输格式)来对三维物体进行导入和导出,由于glTF这种格式专注于在程序运行时呈现三维物体,因此它的传输效率非常高,且加载速度非常快。

    - - + +

    three.js同样也为其它广受欢迎的格式(例如FBX、Collada以及OBJ等)提供了载入工具。即便如此,你应当还是首先尝试着在你的项目中建立一个基于glTF的工作流程。 了解更多详细信息,请查看[link:#manual/introduction/Loading-3D-models loading 3D models]。

    @@ -24,7 +24,7 @@

    哪一种三维物体格式能够得到最好地支持?

    为什么在示例中会有一些和viewport相关的meta标签?

    -
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    + <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

    这些标签用于在移动端浏览器上控制视口的大小和缩放(页面内容可能会以与可视区域不同的大小来呈现)。

    diff --git a/docs/manual/zh/introduction/How-to-create-VR-content.html b/docs/manual/zh/introduction/How-to-create-VR-content.html index 123d3c7f77dddb..66384de35d0505 100644 --- a/docs/manual/zh/introduction/How-to-create-VR-content.html +++ b/docs/manual/zh/introduction/How-to-create-VR-content.html @@ -19,29 +19,29 @@

    如何创建VR内容([name])

    工作流程

    - 首先,你需要将[link:https://github.com/mrdoob/three.js/blob/master/examples/js/vr/WebVR.js WebVR.js] + 首先,你需要将[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/webxr/VRButton.js VRButton.js] 包含到你的项目中。

    -import { WEBVR } from 'three/examples/jsm/vr/WebVR.js'; +import { VRButton } from 'three/examples/jsm/webxr/VRButton.js'; -

    *WEBVR.createButton()*做了两件重要的事情:首先,它创建了一个按钮,指示了VR的兼容性; +

    *VRButton.createButton()*做了两件重要的事情:首先,它创建了一个按钮,指示了VR的兼容性; 此外,若用户激活了这个按钮,则它将开启一个VR会话。 你所要做的唯一一件事情,便是把下面的这一行代码加入到你的应用程序里。

    -document.body.appendChild( WEBVR.createButton( renderer ) ); +document.body.appendChild( VRButton.createButton( renderer ) );

    - 接下来,你需要告诉你的*WebGLRenderer*实例来启用VR渲染。 + 接下来,你需要告诉你的*WebGLRenderer*实例来启用XR渲染。

    -renderer.vr.enabled = true; +renderer.xr.enabled = true;

    @@ -65,17 +65,17 @@

    接下来的步骤

    请查看官方示例中与WebVR相关的示例,了解这一工作流程的实际使用、运行情况。

    - [example:webvr_ballshooter WebVR / ballshoter]
    - [example:webvr_cubes WebVR / cubes]
    - [example:webvr_dragging WebVR / dragging]
    - [example:webvr_lorenzattractor WebVR / lorenzattractor]
    - [example:webvr_panorama WebVR / panorama]
    - [example:webvr_paint WebVR / paint]
    - [example:webvr_rollercoaster WebVR / rollercoaster]
    - [example:webvr_sandbox WebVR / sandbox]
    - [example:webvr_sculpt WebVR / sculpt]
    - [example:webvr_vive_paint WebVR / vive / paint]
    - [example:webvr_vive_sculpt WebVR / vive / sculpt]
    + [example:webxr_vr_ballshooter WebXR / VR / ballshooter]
    + [example:webxr_vr_cubes WebXR / VR / cubes]
    + [example:webxr_vr_dragging WebXR / VR / dragging]
    + [example:webxr_vr_lorenzattractor WebXR / VR / lorenzattractor]
    + [example:webxr_vr_paint WebXR / VR / paint]
    + [example:webxr_vr_panorama_depth WebXR / VR / panorama_depth]
    + [example:webxr_vr_panorama WebXR / VR / panorama]
    + [example:webxr_vr_rollercoaster WebXR / VR / rollercoaster]
    + [example:webxr_vr_sandbox WebXR / VR / sandbox]
    + [example:webxr_vr_sculpt WebXR / VR / sculpt]
    + [example:webxr_vr_video WebXR / VR / video]

    diff --git a/docs/manual/zh/introduction/How-to-dispose-of-objects.html b/docs/manual/zh/introduction/How-to-dispose-of-objects.html index 8c3309fa2f1c5d..387319dbc04c24 100644 --- a/docs/manual/zh/introduction/How-to-dispose-of-objects.html +++ b/docs/manual/zh/introduction/How-to-dispose-of-objects.html @@ -92,11 +92,6 @@

    *three.js*是否会提供被缓存对象数量的相关信息?

    如果你在你的应用程序中注意到了性能问题,一个较好的方法便是调试该属性,以便轻松识别内存泄漏。

    -

    - 对于纹理的内部资源仅在图像完全被加载后才会分配。如果你在图像被加载之前废置纹理,什么都不会发生。 - 没有资源被分配,因此也没有必要进行清理。 -

    -

    当你在纹理还没有被加载时,在纹理上调用*dispose()*,会发生什么?

    diff --git a/docs/manual/zh/introduction/How-to-run-things-locally.html b/docs/manual/zh/introduction/How-to-run-things-locally.html index 2a5d27c0870fab..5e3967066c024f 100644 --- a/docs/manual/zh/introduction/How-to-run-things-locally.html +++ b/docs/manual/zh/introduction/How-to-run-things-locally.html @@ -116,6 +116,12 @@

    Lighttpd

    +

    IIS

    +
    +

    如果你正在使用Microsoft IIS来作为网站服务器,在服务器载入之前,请为.fbx扩展名增加MIME类型。

    + File name externsion: fbx MIME Type: text/plain +

    在默认情况下,IIS阻止 .fbx、 .obj 文件的下载,因此你必须对IIS进行配置,使得这些类型的文件可以被下载。

    +

    其它简单的替代方案你可以在Stack Overflow上找到:[link:http://stackoverflow.com/q/12905426/24874 click here]。 diff --git a/docs/manual/zh/introduction/How-to-update-things.html b/docs/manual/zh/introduction/How-to-update-things.html index 2ab83e97276aa7..4f05cbe0b1e5b8 100644 --- a/docs/manual/zh/introduction/How-to-update-things.html +++ b/docs/manual/zh/introduction/How-to-update-things.html @@ -32,29 +32,27 @@

    如何更新场景([name])

    object.updateMatrix();
    -

    几何形状(Geometries)

    +

    BufferGeometry

    -

    [page:BufferGeometry]

    -
    -

    - BufferGeometries 将信息(例如顶点位置,面索引,法线,颜色,uv和任何自定义属性)存储在[page:BufferAttribute buffers] —— 也就是, - [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays typed arrays]. - 这使得它们通常比标准Geometries更快,缺点是更难用。 -

    -

    - 关于更新BufferGeometries,最重要的是理解你不能调整 buffers 大小(这种操作开销很大,相当于创建了个新的geometry)。 - 但你可以更新 buffers的内容。 -

    -

    - 这意味着如果你知道BufferGeometry的一个属性会增长,比如顶点的数量, - 你必须预先分配足够大的buffer来容纳可能创建的任何新顶点。 - 当然,这也意味着BufferGeometry将有一个最大大小 —— 无法创建一个可以高效地无限扩展的BufferGeometry。 -

    -

    - 我们以在渲染时扩展的line来示例。我们将分配可容纳500个顶点的空间但起初仅绘制2个,使用 - 在500个顶点的缓冲区中,但首先只使用 [page:BufferGeometry.drawRange]。 -

    - +

    + BufferGeometries 将信息(例如顶点位置,面索引,法线,颜色,uv和任何自定义属性)存储在[page:BufferAttribute buffers] —— 也就是, + [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays typed arrays]. + 这使得它们通常比标准Geometries更快,缺点是更难用。 +

    +

    + 关于更新BufferGeometries,最重要的是理解你不能调整 buffers 大小(这种操作开销很大,相当于创建了个新的geometry)。 + 但你可以更新 buffers的内容。 +

    +

    + 这意味着如果你知道BufferGeometry的一个属性会增长,比如顶点的数量, + 你必须预先分配足够大的buffer来容纳可能创建的任何新顶点。 + 当然,这也意味着BufferGeometry将有一个最大大小 —— 无法创建一个可以高效地无限扩展的BufferGeometry。 +

    +

    + 我们以在渲染时扩展的line来示例。我们将分配可容纳500个顶点的空间但起初仅绘制2个,使用 + 在500个顶点的缓冲区中,但首先只使用 [page:BufferGeometry.drawRange]。 +

    + var MAX_POINTS = 500; // geometry @@ -62,23 +60,23 @@

    [page:BufferGeometry]

    // attributes var positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point -geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); +geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); // draw range var drawCount = 2; // draw the first 2 points, only geometry.setDrawRange( 0, drawCount ); // material -var material = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 2 } ); +var material = new THREE.LineBasicMaterial( { color: 0xff0000 } ); // line var line = new THREE.Line( geometry, material ); scene.add( line ); -
    -

    - 然后我们随机增加顶点到line中,以这样的一种方式: -

    - + +

    + 然后我们随机增加顶点到line中,以这样的一种方式: +

    + var positions = line.geometry.attributes.position.array; var x, y, z, index; @@ -95,39 +93,40 @@

    [page:BufferGeometry]

    z += ( Math.random() - 0.5 ) * 30; } -
    -

    - 如果要更改第一次渲染后渲染的点数,执行以下操作: -

    - + +

    + 如果要更改第一次渲染后渲染的点数,执行以下操作: +

    + line.geometry.setDrawRange( 0, newValue ); - -

    - 如果要在第一次渲染后更改position数值,则需要像这样设置needsUpdate标志: -

    - + +

    + 如果要在第一次渲染后更改position数值,则需要像这样设置needsUpdate标志: +

    + line.geometry.attributes.position.needsUpdate = true; // 需要加在第一次渲染之后 - - -

    - 这个fiddle展示了一个你可以参考的运动的line。 -

    +
    -

    例子:

    - [example:webgl_custom_attributes WebGL / custom / attributes]
    - [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles] +

    + 这个fiddle展示了一个你可以参考的运动的line。 +

    +

    例子

    +

    + [example:webgl_custom_attributes WebGL / custom / attributes]
    + [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles] +

    -
    +
    -

    [page:Geometry]

    -
    -

    - 以下标志控制各种geometry属性的更新。仅对于需要更新的属性设置标志,因为更新成本很高。 - 一旦buffers改变,这些标志位会自动重置为false。如果你想要持续更新buffers,你需要保持这些设置为true。 - 请注意这仅适用于[page:Geometry]而不是[page:BufferGeometry]。 -

    - +

    Geometry

    +
    +

    + 以下标志控制各种geometry属性的更新。仅对于需要更新的属性设置标志,因为更新成本很高。 + 一旦buffers改变,这些标志位会自动重置为false。如果你想要持续更新buffers,你需要保持这些设置为true。 + 请注意这仅适用于[page:Geometry]而不是[page:BufferGeometry]。 +

    + var geometry = new THREE.Geometry(); geometry.verticesNeedUpdate = true; geometry.elementsNeedUpdate = true; @@ -136,27 +135,19 @@

    [page:Geometry]

    geometry.normalsNeedUpdate = true; geometry.colorsNeedUpdate = true; geometry.tangentsNeedUpdate = true; -
    - -

    - 在早于[link:https://github.com/mrdoob/three.js/releases/tag/r66 r66]的版本中,meshes - 需要额外设定 dynamic 标志为true (为了维持内部的 typed arrays): -

    - - - //removed after r66 - geometry.dynamic = true; - +
    -

    例子:

    - [example:webgl_geometry_dynamic WebGL / geometry / dynamic]
    -
    +

    + 在早于[link:https://github.com/mrdoob/three.js/releases/tag/r66 r66]的版本中,meshes + 需要额外设定 dynamic 标志为true (为了维持内部的 typed arrays): +

    + + //removed after r66 + geometry.dynamic = true; +
    - - -

    材质(Materials)

    所有uniforms值都可以自由改变(比如 colors, textures, opacity 等等),这些数值在每帧都发给shader。

    @@ -166,7 +157,6 @@

    材质(Materials)

    在运行时无法轻松更改以下属性(一旦material被渲染了一次):

    • uniforms的数量和类型
    • -
    • lights的数量和类型
    • 是否存在
      • texture
      • @@ -194,9 +184,11 @@

        如果你需要在运行时使用不同的材料配置:

        如果数量很大(例如,每个面可能有所不同),请考虑不同的解决方案,例如使用属性/纹理来驱动不同的每个面部外观。

        -

        例子:

        - [example:webgl_materials_cars WebGL / materials / cars]
        - [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof] +

        例子

        +

        + [example:webgl_materials_car WebGL / materials / car]
        + [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof] +

    @@ -208,13 +200,13 @@

    纹理(Textures)

    渲染对象就会自动更新。

    -

    例子:

    - [example:webgl_materials_video WebGL / materials / video]
    - [example:webgl_rtt WebGL / rtt] - +

    例子

    +

    + [example:webgl_materials_video WebGL / materials / video]
    + [example:webgl_rtt WebGL / rtt] +

    -

    相机(Cameras)

    相机的位置和目标会自动更新。 如果你需要改变

    diff --git a/docs/manual/zh/introduction/How-to-use-WebGL2.html b/docs/manual/zh/introduction/How-to-use-WebGL2.html index 1f21819fb80082..a5faa4c912cd5c 100644 --- a/docs/manual/zh/introduction/How-to-use-WebGL2.html +++ b/docs/manual/zh/introduction/How-to-use-WebGL2.html @@ -46,9 +46,14 @@

    工作流程

    最终,three.js将在内部使用所给定的绘图环境来渲染,并自动将内置的材质的着色器代码转化为GLSL ES 3.00。

    +

    + 由于你是手动创建WebGL 2渲染上下文,因此还必须传入所有必需的上下文属性。 + 请注意:在上下文被创建后,将无法修改这些属性,因此将它们传递给WebGLRenderer将不会产生任何影响。 +

    + var canvas = document.createElement( 'canvas' ); -var context = canvas.getContext( 'webgl2' ); +var context = canvas.getContext( 'webgl2', { alpha: false } ); var renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } ); diff --git a/docs/manual/zh/introduction/How-to-use-post-processing.html b/docs/manual/zh/introduction/How-to-use-post-processing.html index 08a17e3b720696..f06ba492a8f484 100644 --- a/docs/manual/zh/introduction/How-to-use-post-processing.html +++ b/docs/manual/zh/introduction/How-to-use-post-processing.html @@ -8,24 +8,24 @@ -

    How to use post-processing

    +

    如何使用后期处理(How to use post-processing)

    - Many three.js applications render their 3D objects directly to the screen. Sometimes, however, you want to apply one or more graphical - effects like Depth-Of-Field, Bloom, Film Grain or various types of Anti-aliasing. Post-processing is a widely used approach - to implement such effects. First, the scene is rendered to a render target which represents a buffer in the video card's memory. - In the next step one ore more post-processing passes apply filters and effects to the image buffer before it is eventually rendered to - the screen. + 很多three.js应用程序是直接将三维物体渲染到屏幕上的。 + 有时,你或许希望应用一个或多个图形效果,例如景深、发光、胶片微粒或是各种类型的抗锯齿。 + 后期处理是一种被广泛使用、用于来实现这些效果的方式。 + 首先,场景被渲染到一个渲染目标上,渲染目标表示的是一块在显存中的缓冲区。 + 接下来,在图像最终被渲染到屏幕之前,一个或多个后期处理过程将滤镜和效果应用到图像缓冲区。

    - three.js provides a complete post-processing solution via [page:EffectComposer] to implement such a workflow. + three.js通过[page:EffectComposer](效果合成器),提供了一个完整的后期处理解决方案来实现这样的工作流程。

    -

    Workflow

    +

    工作流程

    - The first step in the process is to import all necessary files from the examples directory. The guide assumes your are using the official - [link:https://www.npmjs.com/package/three npm package] of three.js. For our basic demo in this guide we need the following files. + 首先,我们要做的是从示例(examples)文件夹导入所有必需的文件。本指南假设你正在使用three.js官方npm包([link:https://www.npmjs.com/package/three npm package])。 + 在本指南的基础示例中,我们需要下列文件。

    @@ -35,7 +35,7 @@

    Workflow

    - After all files are successfully imported, we can create our composer by passing in an instance of [page:WebGLRenderer]. + 当这些文件被成功导入后,我们便可以通过传入一个[page:WebGLRenderer]的实例,来创建我们的合成器了。

    @@ -43,8 +43,8 @@

    Workflow

    - When using a composer, it's necessary to change the application's animation loop. Instead of calling the render method of - [page:WebGLRenderer], we now use the respective counterpart of [page:EffectComposer]. + 在使用合成器时,我们需要对应用程序的动画循环进行更改。 + 现在我们不再调用[page:WebGLRenderer]的render方法,而是使用[page:EffectComposer]中对应的render方法。

    @@ -58,10 +58,10 @@

    Workflow

    - Our composer is now ready so it's possible to configure the chain of post-processing passes. These passes are responsible for creating - the final visual output of the application. They are processed in order of their addition/insertion. In our example, the instance of *RenderPass* - is executed first and then the instance of *GlitchPass*. The last enabled pass in the chain is automatically rendered to the screen. The setup - of the passes looks like so: + 我们的合成器已经准备好了,现在我们就可以来配置后期处理过程链了。 + 这些过程负责创建应用程序的最终视觉输出,它们按照添加/插入的顺序来进行处理。 + 在我们的示例中,首先执行的是*RenderPass*实例,然后是*GlitchPass*。在链中的最后一个过程将自动被渲染到屏幕上。 + 这些过程的设置类似这样:

    @@ -73,23 +73,23 @@

    Workflow

    - *RenderPass* is normally placed at the beginning of the chain in order to provide the rendered scene as an input for the next post-processing step. In our case, - *GlitchPass* is going to use these image data to apply a wild glitch effect. Check out this [link:https://threejs.org/examples/webgl_postprocessing_glitch live example] - to see it in action. + *RenderPass*通常位于过程链的开始,以便将渲染好的场景作为输入来提供给下一个后期处理步骤。 + 在我们的示例中,*GlitchPass*将会使用这些图像数据,来应用一个疯狂的故障效果。参见这个示例: + [link:https://threejs.org/examples/webgl_postprocessing_glitch live example]来看一看它的实际效果。

    -

    Built-in Passes

    +

    内置过程

    - You can use a wide range of pre-defined post-processing passes provided by the engine. They are located in the - [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing] directory. + 你可以使用由本引擎提供的各种预定义好的后期处理过程, + 它们位于[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing]目录中。

    -

    Custom Passes

    +

    自定义过程

    - Sometimes you want to write a custom post-processing shader and include it into the chain of post-processing passes. For this scenario, - you can utilize *ShaderPass*. After importing the file and your custom shader, you can use the following code to setup the pass. + 有时你或许想要自己写一个自定义后期处理着色器,并将其包含到后期处理过程链中。 + 对于这个需求,你可以使用*ShaderPass*。在引入该文件以及你的自定义着色期后,可以使用下列代码来设置该过程:

    @@ -103,9 +103,8 @@

    Custom Passes

    - The repository provides a file called [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader] which is a - good starting code for your own custom shader. *CopyShader* just copies the image contents of the [page:EffectComposer]'s read buffer - to its write buffer without applying any effects. + 本仓库中提供了一个名为[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader]的文件, + 这是你自定义自己的着色器的一个很好的起始代码。*CopyShader*仅仅是拷贝了读缓冲区中的图像内容到写缓冲区,不会应用任何效果。

    diff --git a/docs/manual/zh/introduction/Import-via-modules.html b/docs/manual/zh/introduction/Import-via-modules.html index edcb6ecca5866f..3c35362c551520 100644 --- a/docs/manual/zh/introduction/Import-via-modules.html +++ b/docs/manual/zh/introduction/Import-via-modules.html @@ -62,20 +62,19 @@

    导入这个模块

    ... -

    Importable Examples

    +

    可引入的示例

    - The core of three.js is focused on the most important components of a 3D engine. Many other components like loaders or controls are part of the - examples directory. three.js ensures that these files are kept in sync with the core but users have to import them separately if they are required - for a project. You can find in the [link:https://github.com/mrdoob/three.js/tree/master/examples/jsm examples/jsm] directory an ES6 - module version for almost all example files. If you install three.js via npm, you can import them like so: + three.js的核心专注于实现3D引擎中最为重要的组件。其他诸如加载器和控制器等组件,是示例文件夹中的一部分。 + three.js确保这些文件能够与核心保持同步,但如果在一个项目中这些组件是必要的,用户将必须分别地引入它们。 + 你可以在[link:https://github.com/mrdoob/three.js/tree/master/examples/jsm examples/jsm]文件夹中找到所有示例文件的ES6版本。 + 如果你是通过npm来安装three.js的,那么你可以使用类似下面的代码来引入它们:

    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

    - Note: When using code from the examples directory, it's important that all files match the version of - your three.js main file. For example, it's not acceptable to use *GLTFLoader* and *OrbitControls* from R96 together - with three.js R103. + 请注意:当你在使用来自示例(examples)文件夹中的代码时,其中的所有文件和你的three.js主文件版本相匹配是很重要的。 + 比如说,three.js的R103版本不能够接受和来自R96版本的*GLTFLoader*和*OrbitControls*一起使用。

    diff --git a/docs/manual/zh/introduction/Loading-3D-models.html b/docs/manual/zh/introduction/Loading-3D-models.html index 873cc7f00fd0a8..7c8be22506278e 100644 --- a/docs/manual/zh/introduction/Loading-3D-models.html +++ b/docs/manual/zh/introduction/Loading-3D-models.html @@ -14,7 +14,7 @@

    载入3D模型([name])

    目前,3D模型的格式有成千上万种可供选择,但每一种格式都具有不同的目的、用途以及复杂性。 - 虽然 + 虽然 three.js已经提供了多种导入工具, 但是选择正确的文件格式以及工作流程将可以节省很多时间,以及避免遭受很多挫折。某些格式难以使用,或者实时体验效率低下,或者目前尚未得到完全支持。

    @@ -133,6 +133,9 @@

    故障排除

    尝试将模型放大或缩小到原来的1000倍。许多模型的缩放比例各不相同,如果摄像机位于模型内,则大型模型将可能不会显示。
  • + 尝试添加一个光源并改变其位置。模型或许被隐藏在黑暗中。 +
  • +
  • 在网络面板中查找失败的纹理贴图请求,比如说C:\\Path\To\Model\texture.jpg。载入贴图时,请使用相对于模型文件路径,例如 images/texture.jpg —— 这或许需要在文本编辑器中来对模型文件进行修改。
  • diff --git a/docs/manual/zh/introduction/Matrix-transformations.html b/docs/manual/zh/introduction/Matrix-transformations.html index 9762bd44ef7e9b..874ad229aede47 100644 --- a/docs/manual/zh/introduction/Matrix-transformations.html +++ b/docs/manual/zh/introduction/Matrix-transformations.html @@ -17,7 +17,9 @@

    矩阵变换([name])

    便利的属性和*matrixAutoUpdate*(Convenience properties and *matrixAutoUpdate*)

    - 有两种方法可以更新对象的转换: +

    + 有两种方法可以更新对象的转换: +

    1. 修改对象的*position*,*quaternion*和*scale*属性,让three.js重新计算来自这些属性的对象矩阵: @@ -36,7 +38,7 @@

      便利的属性和*matrixAutoUpdate*(Convenience properties and *matrixAut

    2. - 直接修改对象的矩阵。 [page:Matrix4]类有各种修改矩阵的方法: + 直接修改对象的矩阵。 [page:Matrix4]类有各种修改矩阵的方法: object.matrix.setRotationFromQuaternion( quaternion ); object.matrix.setPosition( start_position ); @@ -57,7 +59,7 @@

      对象和世界矩阵(Object and world matrices)

      旋转和四元数(Rotation and Quaternion)

      - Three.js提供了两种表示3D旋转的方式:[page:Euler Euler angles](欧拉角)和[page:Quaternion Quaternions](四元数),以及两者之间的转换方法。 欧拉角有称为“万向节锁定”的问题,其中某些配置可能失去一定程度的自由度(防止物体绕一个轴旋转)。 因此,对象旋转 始终 存储在对象的[page:Object3D.quaternion quaternion]中。 + Three.js提供了两种表示3D旋转的方式:[page:Euler Euler angles](欧拉角)和[page:Quaternion Quaternions](四元数),以及两者之间的转换方法。 欧拉角有称为“万向节锁定”的问题,其中某些配置可能失去一定程度的自由度(防止物体绕一个轴旋转)。 因此,对象旋转 始终 存储在对象的[page:Object3D.quaternion quaternion]中。

      该库的早期版本包含*useQuaternion*属性,当设置为false时,将导致对象的[page:Object3D.matrix matrix]从欧拉角计算。这种做法已被弃用 - 作为代替,您应该使用[page:Object3D.setRotationFromEuler setRotationFromEuler]方法,该方法将更新四元数。 diff --git a/docs/manual/zh/introduction/Typescript-setup.html b/docs/manual/zh/introduction/Typescript-setup.html new file mode 100644 index 00000000000000..863ce5cf0a43d1 --- /dev/null +++ b/docs/manual/zh/introduction/Typescript-setup.html @@ -0,0 +1,46 @@ + + + + + + + + + + +

      [name]

      + +

      + three.js is a JavaScript-based library. However, it's possible to use it in a TypeScript project, as the library + exposes [link:https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html Declaration Files] (*d.ts* files). +

      + +

      + A minimal configuration is required for the TypeScript compiler to + discover three.js types.
      + You will need to set the [link:https://www.typescriptlang.org/docs/handbook/module-resolution.html moduleResolution] + option to *node*, and the [link:https://www.typescriptlang.org/docs/handbook/compiler-options.html target] option to *es6* or newer. +

      + + + // Example of minimal `tsconfig.json` file + { + "compilerOptions": { + "target": "es6", + "moduleResolution": "node", + }, + "include": [ "./src/**/*.ts" ], + } + + +

      + Note: As of today, it's not yet possible to use three.js typings without using those two options. +

      + +

      + Note: It happens that some declarations are incorrect and/or missing. + Contributing to Declaration Files is really helpful for the community, making three.js + typings better and more accurate. +

      + + diff --git a/docs/manual/zh/introduction/Useful-links.html b/docs/manual/zh/introduction/Useful-links.html index ad45affaa400f5..fe9446459a6cce 100644 --- a/docs/manual/zh/introduction/Useful-links.html +++ b/docs/manual/zh/introduction/Useful-links.html @@ -132,7 +132,7 @@

      WebGL参考

      较旧的链接

      - 这些链接是出于历史的目的而保留的,你或许可以发现它们仍然很有用,但是它们可能含有和three.js非常老旧的版本有关的信息。 + 这些链接是出于历史目的而保留的,你或许可以发现它们仍然很有用,它们可能含有和three.js较为早前版本的有关的信息。

        diff --git a/docs/page.css b/docs/page.css index 1495bd548e4365..f87dadce0475ba 100644 --- a/docs/page.css +++ b/docs/page.css @@ -1,4 +1,6 @@ :root { + color-scheme: light dark; + --color-blue: #049EF4; --text-color: #444; @@ -12,18 +14,30 @@ --icon-size: 20px; } +@media (prefers-color-scheme: dark) { + + :root { + --text-color: #bbb; + + --border-style: 1px solid #444; + } + +} + @font-face { font-family: 'Roboto Mono'; src: local('Roboto Mono'), local('RobotoMono-Regular'), url('../files/RobotoMono-Regular.woff2') format('woff2'); font-style: normal; font-weight: 400; } + @font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; src: local('Inter-Regular'), url("../files/Inter-Regular.woff2?v=3.6") format("woff2"); } + @font-face { font-family: 'Inter'; font-style: normal; @@ -47,6 +61,7 @@ body { padding-bottom: var(--page-padding); padding-right: var(--page-padding); padding-left: calc(var(--page-padding) + var(--panel-width)); + word-break: break-word; } a { diff --git a/docs/prettify/threejs.css b/docs/prettify/threejs.css index d578acffcf888b..fb88c2e375c556 100644 --- a/docs/prettify/threejs.css +++ b/docs/prettify/threejs.css @@ -13,3 +13,19 @@ pre.prettyprint, code.prettyprint { background-color: #F5F5F5; font-family: 'Roboto Mono', monospace; } + +@media (prefers-color-scheme: dark) { + + pre .tag, code .tag { color: #2194ce; } /* HTML tag */ + pre .atn, code .atn { color: #BB55FF; } /* HTML attribute name */ + pre .atv, code .atv { color: #30b030; } /* HTML attribute value */ + pre .str, code .str { color: #BB55FF; } /* string */ + pre .com, code .com { color: #666666; } /* comment */ + pre .lit, code .lit { color: #ff3399; } /* literal */ + pre .pln, code .pln { color: #aaaaaa; } /* plaintext */ + + pre.prettyprint, code.prettyprint { + background-color: #333333; + } + +} diff --git a/docs/scenes/bones-browser.html b/docs/scenes/bones-browser.html index 1f7ec7058e4c88..0df7f2b3389526 100644 --- a/docs/scenes/bones-browser.html +++ b/docs/scenes/bones-browser.html @@ -131,8 +131,8 @@ } - geometry.addAttribute( 'skinIndex', new Uint16BufferAttribute( skinIndices, 4 ) ); - geometry.addAttribute( 'skinWeight', new Float32BufferAttribute( skinWeights, 4 ) ); + geometry.setAttribute( 'skinIndex', new Uint16BufferAttribute( skinIndices, 4 ) ); + geometry.setAttribute( 'skinWeight', new Float32BufferAttribute( skinWeights, 4 ) ); return geometry; diff --git a/docs/scenes/geometry-browser.html b/docs/scenes/geometry-browser.html index 72aba0d5dc8e4c..7916c2104d00b9 100644 --- a/docs/scenes/geometry-browser.html +++ b/docs/scenes/geometry-browser.html @@ -1492,7 +1492,7 @@ var group = new Group(); var geometry = new BufferGeometry(); - geometry.addAttribute( 'position', new Float32BufferAttribute( [], 3 ) ); + geometry.setAttribute( 'position', new Float32BufferAttribute( [], 3 ) ); var lineMaterial = new LineBasicMaterial( { color: 0xffffff, transparent: true, opacity: 0.5 } ); var meshMaterial = new MeshPhongMaterial( { color: 0x156289, emissive: 0x072534, side: DoubleSide, flatShading: true } ); diff --git a/docs/scenes/material-browser.html b/docs/scenes/material-browser.html index 70b1cd8dfee665..b5f684f7f111b5 100644 --- a/docs/scenes/material-browser.html +++ b/docs/scenes/material-browser.html @@ -57,7 +57,6 @@ Scene, TextureLoader, TorusKnotBufferGeometry, - VertexColors, NoColors, WebGLRenderer } from "../../build/three.module.js"; @@ -85,13 +84,6 @@ }, - colors: { - - 'THREE.NoColors': NoColors, - 'THREE.VertexColors': VertexColors - - }, - blendingMode: { 'THREE.NoBlending': NoBlending, @@ -270,7 +262,7 @@ } - geometry.addAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); } @@ -294,7 +286,7 @@ return function () { - material.vertexColors = parseInt( material.vertexColors ); //Ensure number + material.vertexColors = material.vertexColors; material.side = parseInt( material.side ); //Ensure number material.needsUpdate = true; geometry.attributes.position.needsUpdate = true; @@ -397,7 +389,7 @@ folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) ); folder.add( material, 'wireframe' ); folder.add( material, 'wireframeLinewidth', 0, 10 ); - folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) ); + folder.add( material, 'vertexColors' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'fog' ); folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) ); @@ -446,7 +438,7 @@ folder.add( material, 'linewidth', 0, 10 ); folder.add( material, 'linecap', [ 'butt', 'round', 'square' ] ); folder.add( material, 'linejoin', [ 'round', 'bevel', 'miter' ] ); - folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) ); + folder.add( material, 'vertexColors' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'fog' ); } @@ -468,7 +460,7 @@ folder.add( material, 'wireframe' ); folder.add( material, 'wireframeLinewidth', 0, 10 ); - folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) ); + folder.add( material, 'vertexColors' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'fog' ); folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) ); @@ -517,7 +509,7 @@ folder.add( material, 'flatShading' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'wireframe' ); folder.add( material, 'wireframeLinewidth', 0, 10 ); - folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) ); + folder.add( material, 'vertexColors' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'fog' ); folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) ); folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) ); @@ -565,7 +557,7 @@ folder.add( material, 'flatShading' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'wireframe' ); folder.add( material, 'wireframeLinewidth', 0, 10 ); - folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) ); + folder.add( material, 'vertexColors' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'fog' ); folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) ); folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) ); @@ -595,12 +587,12 @@ folder.add( material, 'roughness', 0, 1 ); folder.add( material, 'metalness', 0, 1 ); folder.add( material, 'reflectivity', 0, 1 ); - folder.add( material, 'clearCoat', 0, 1 ).step( 0.01 ); - folder.add( material, 'clearCoatRoughness', 0, 1 ).step( 0.01 ); + folder.add( material, 'clearcoat', 0, 1 ).step( 0.01 ); + folder.add( material, 'clearcoatRoughness', 0, 1 ).step( 0.01 ); folder.add( material, 'flatShading' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'wireframe' ); folder.add( material, 'wireframeLinewidth', 0, 10 ); - folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) ); + folder.add( material, 'vertexColors' ).onChange( needsUpdate( material, geometry ) ); folder.add( material, 'fog' ); folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) ); folder.add( data, 'map', diffuseMapKeys ).onChange( updateTexture( material, 'map', diffuseMaps ) ); diff --git a/editor/css/dark.css b/editor/css/dark.css deleted file mode 100644 index ed99bf851de229..00000000000000 --- a/editor/css/dark.css +++ /dev/null @@ -1,300 +0,0 @@ -button { - color: #aaa; - background-color: #222; - border: 0px; - padding: 5px 8px; - text-transform: uppercase; - cursor: pointer; - outline: none; -} - - button:hover { - color: #ccc; - background-color: #444; - } - - button.selected { - color: #fff; - background-color: #08f; - } - -input, textarea { - background-color: #222; - border: 1px solid transparent; - color: #888; -} - -input.Number { - color: #08f!important; - font-size: 12px; - border: 0px; - padding: 2px; - cursor: col-resize; -} - -select { - color: #aaa; - background-color: #222; - border: 0px; - text-transform: uppercase; - cursor: pointer; - outline: none; -} - - select:hover { - color: #ccc; - background-color: #444; - } - -/* UI */ - -#viewport { - position: absolute; - top: 32px; - left: 0; - right: 300px; - bottom: 0; -} - - #viewport #info { - text-shadow: 1px 1px 0 rgba(0,0,0,0.25); - pointer-events: none; - } - -#script { - position: absolute; - top: 32px; - left: 0; - right: 300px; - bottom: 0; - opacity: 0.9; -} - -#player { - position: absolute; - top: 32px; - left: 0; - right: 300px; - bottom: 0; -} - -#menubar { - position: absolute; - width: 100%; - height: 32px; - background: #111; - padding: 0; - margin: 0; - right: 0; - top: 0; -} - - #menubar .menu { - float: left; - cursor: pointer; - padding-right: 8px; - } - - #menubar .menu.right { - float: right; - cursor: auto; - padding-right: 0; - text-align: right; - } - - #menubar .menu .title { - display: inline-block; - color: #888; - margin: 0; - padding: 8px; - line-height: 16px; - } - - #menubar .menu .options { - position: fixed; - display: none; - padding: 5px 0; - background: #111; - width: 150px; - max-height: calc(100% - 80px); - overflow: auto; - } - - #menubar .menu:hover .options { - display: block; - } - - #menubar .menu .options hr { - border-color: #222; - } - - #menubar .menu .options .option { - color: #888; - background-color: transparent; - padding: 5px 10px; - margin: 0 !important; - } - - #menubar .menu .options .option:hover { - color: #fff; - background-color: #08f; - } - - #menubar .menu .options .option:active { - background: transparent; - } - - #menubar .menu .options .inactive { - color: #444; - background-color: transparent; - padding: 5px 10px; - margin: 0 !important; - } - -#sidebar { - position: absolute; - right: 0; - top: 32px; - bottom: 0; - width: 300px; - background-color: #111; - overflow: auto; -} - - #sidebar * { - vertical-align: middle; - } - - #sidebar .Panel { - color: #888; - padding: 10px; - border-top: 1px solid #222; - } - - #sidebar .Panel.collapsed { - margin-bottom: 0; - } - - #sidebar .Panel.Material canvas { - border: solid 1px #5A5A5A; - } - - #sidebar .Row { - min-height: 20px; - margin-bottom: 10px; - } - -#tabs { - background-color: #1b1b1b; - border-top: 1px solid #222; -} - - #tabs span { - color: #555; - border-right: 1px solid #222; - padding: 10px; - } - - #tabs span.selected { - color: #888; - background-color: #111; - } - -#toolbar { - position: absolute; - left: calc(50% - 290px); /* ( ( 100% - 300px ) / 2.0 ) - 140px */ - width: 280px; - bottom: 16px; - height: 32px; - background-color: #111; - color: #333; -} - - #toolbar * { - vertical-align: middle; - } - - #toolbar .Panel { - padding: 4px; - color: #888; - } - - #toolbar button { - margin-right: 6px; - line-height: 14px; - height: 24px; - } - -.Outliner { - color: #888; - background: #222; - padding: 0; - width: 100%; - height: 140px; - font-size: 12px; - cursor: default; - overflow: auto; - outline: none; -} - - .Outliner .option { - padding: 4px; - white-space: nowrap; - } - - .Outliner .option:hover { - background-color: rgba(21,60,94,0.5); - } - - - .Outliner .option.active { - background-color: rgba(21,60,94,1); - } - -/* */ - -@media all and ( max-width: 600px ) { - - #menubar .menu .options { - max-height: calc(100% - 372px); - } - - #menubar .menu.right { - display: none; - } - - #viewport { - left: 0; - right: 0; - top: 32px; - height: calc(100% - 352px); - } - - #script { - left: 0; - right: 0; - top: 32px; - height: calc(100% - 352px); - } - - #player { - left: 0; - right: 0; - top: 32px; - height: calc(100% - 352px); - } - - #sidebar { - left: 0; - width: 100%; - top: calc(100% - 320px); - bottom: 0; - } - - #toolbar { - left: calc(50% - 140px); - width: 280px; - top: 68px; - } - -} diff --git a/editor/css/light.css b/editor/css/light.css deleted file mode 100644 index 13eb2a58faa95c..00000000000000 --- a/editor/css/light.css +++ /dev/null @@ -1,293 +0,0 @@ -button { - color: #555; - background-color: #ddd; - border: 0px; - padding: 5px 8px; - text-transform: uppercase; - cursor: pointer; - outline: none; -} - - button:hover { - background-color: #fff; - } - - button.selected { - background-color: #fff; - } - -input, textarea { - border: 1px solid transparent; - color: #444; -} - -input.Number { - color: #08f!important; - font-size: 12px; - border: 0px; - padding: 2px; - cursor: col-resize; -} - -select { - color: #666; - background-color: #ddd; - border: 0px; - text-transform: uppercase; - cursor: pointer; - outline: none; -} - - select:hover { - background-color: #fff; - } - -/* UI */ - -#viewport { - position: absolute; - top: 32px; - left: 0; - right: 300px; - bottom: 0; -} - - #viewport #info { - text-shadow: 1px 1px 0 rgba(0,0,0,0.25); - pointer-events: none; - } - -#script { - position: absolute; - top: 32px; - left: 0; - right: 300px; - bottom: 0; - opacity: 0.9; -} - -#player { - position: absolute; - top: 32px; - left: 0; - right: 300px; - bottom: 0; -} - -#menubar { - position: absolute; - width: 100%; - height: 32px; - background: #eee; - padding: 0; - margin: 0; - right: 0; - top: 0; -} - - #menubar .menu { - float: left; - cursor: pointer; - padding-right: 8px; - } - - #menubar .menu.right { - float: right; - cursor: auto; - padding-right: 0; - text-align: right; - } - - #menubar .menu .title { - display: inline-block; - color: #888; - margin: 0; - padding: 8px; - line-height: 16px; - } - - #menubar .menu .options { - position: fixed; - display: none; - padding: 5px 0; - background: #eee; - width: 150px; - max-height: calc(100% - 80px); - overflow: auto; - } - - #menubar .menu:hover .options { - display: block; - } - - #menubar .menu .options hr { - border-color: #ddd; - } - - #menubar .menu .options .option { - color: #666; - background-color: transparent; - padding: 5px 10px; - margin: 0 !important; - } - - #menubar .menu .options .option:hover { - color: #fff; - background-color: #08f; - } - - #menubar .menu .options .option:active { - color: #666; - background: transparent; - } - - #menubar .menu .options .inactive { - color: #bbb; - background-color: transparent; - padding: 5px 10px; - margin: 0 !important; - } - -#sidebar { - position: absolute; - right: 0; - top: 32px; - bottom: 0; - width: 300px; - background: #eee; - overflow: auto; -} - - #sidebar * { - vertical-align: middle; - } - - #sidebar .Panel { - color: #888; - padding: 10px; - border-top: 1px solid #ccc; - } - - #sidebar .Panel.collapsed { - margin-bottom: 0; - } - - #sidebar .Row { - min-height: 20px; - margin-bottom: 10px; - } - -#tabs { - background-color: #ddd; - border-top: 1px solid #ccc; -} - - #tabs span { - color: #aaa; - border-right: 1px solid #ccc; - padding: 10px; - } - - #tabs span.selected { - color: #888; - background-color: #eee; - } - -#toolbar { - position: absolute; - left: calc(50% - 290px); /* ( ( 100% - 300px ) / 2.0 ) - 140px */ - width: 280px; - bottom: 16px; - height: 32px; - background: #eee; - color: #333; -} - - #toolbar * { - vertical-align: middle; - } - - #toolbar .Panel { - padding: 4px; - color: #888; - } - - #toolbar button { - margin-right: 6px; - line-height: 14px; - height: 24px; - } - -.Outliner { - color: #444; - background-color: #fff; - padding: 0; - width: 100%; - height: 140px; - font-size: 12px; - cursor: default; - overflow: auto; - outline: none !important; -} - - .Outliner .option { - padding: 4px; - color: #666; - white-space: nowrap; - } - - .Outliner .option:hover { - background-color: rgba(0,0,0,0.02); - } - - .Outliner .option.active { - background-color: rgba(0,0,0,0.04); - } - -/* */ - -@media all and ( max-width: 600px ) { - - #menubar .menu .options { - max-height: calc(100% - 372px); - } - - #menubar .menu.right { - display: none; - } - - #viewport { - left: 0; - right: 0; - top: 32px; - height: calc(100% - 352px); - } - - #script { - left: 0; - right: 0; - top: 32px; - height: calc(100% - 352px); - } - - #player { - left: 0; - right: 0; - top: 32px; - height: calc(100% - 352px); - } - - #sidebar { - left: 0; - width: 100%; - top: calc(100% - 320px); - bottom: 0; - } - - #toolbar { - left: calc(50% - 140px); - width: 280px; - top: 68px; - } - -} diff --git a/editor/css/main.css b/editor/css/main.css index 85cc3b8cda4780..27f13d02c7fa83 100644 --- a/editor/css/main.css +++ b/editor/css/main.css @@ -1,3 +1,7 @@ +:root { + color-scheme: light dark; +} + body { font-family: Helvetica, Arial, sans-serif; font-size: 14px; @@ -41,6 +45,60 @@ textarea, input { outline: none; } /* osx */ user-select: none; } +.TabbedPanel { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + + /* No support for these yet */ + -o-user-select: none; + user-select: none; + position: relative; + display: block; + width: 100%; +} + +.TabbedPanel .Tabs { + position: relative; + display: block; + width: 100%; +} + +.TabbedPanel .Tabs .Tab { + padding: 10px; + vertical-align: middle; + text-transform: uppercase; +} + +.TabbedPanel .Tabs .Panels { + position: relative; + display: block; + width: 100%; + height: 100%; +} + +/* Listbox */ +.Listbox { + color: #444; + background-color: #fff; + padding: 0; + width: 100%; + min-height: 140px; + font-size: 12px; + cursor: default; + overflow: auto; +} + +.Listbox .ListboxItem { + padding: 6px; + color: #666; + white-space: nowrap; +} + +.Listbox .ListboxItem.active { + background-color: rgba(0, 0, 0, 0.04); +} + /* CodeMirror */ .CodeMirror { @@ -161,3 +219,454 @@ textarea, input { outline: none; } /* osx */ #outliner .Script:after { content: '{...}' /* ❮/❯ */ } + +/* */ + +button { + color: #555; + background-color: #ddd; + border: 0px; + padding: 5px 8px; + text-transform: uppercase; + cursor: pointer; + outline: none; +} + + button:hover { + background-color: #fff; + } + + button.selected { + background-color: #fff; + } + +input, textarea { + border: 1px solid transparent; + color: #444; +} + +input.Number { + color: #08f!important; + font-size: 12px; + border: 0px; + padding: 2px; + cursor: col-resize; +} + +select { + color: #666; + background-color: #ddd; + border: 0px; + text-transform: uppercase; + cursor: pointer; + outline: none; +} + + select:hover { + background-color: #fff; + } + +/* UI */ + +#viewport { + position: absolute; + top: 32px; + left: 0; + right: 300px; + bottom: 0; +} + + #viewport #info { + text-shadow: 1px 1px 0 rgba(0,0,0,0.25); + pointer-events: none; + } + +#script { + position: absolute; + top: 32px; + left: 0; + right: 300px; + bottom: 0; + opacity: 0.9; +} + +#player { + position: absolute; + top: 32px; + left: 0; + right: 300px; + bottom: 0; +} + +#menubar { + position: absolute; + width: 100%; + height: 32px; + background: #eee; + padding: 0; + margin: 0; + right: 0; + top: 0; +} + + #menubar .menu { + float: left; + cursor: pointer; + padding-right: 8px; + } + + #menubar .menu.right { + float: right; + cursor: auto; + padding-right: 0; + text-align: right; + } + + #menubar .menu .title { + display: inline-block; + color: #888; + margin: 0; + padding: 8px; + line-height: 16px; + } + + #menubar .menu .options { + position: fixed; + display: none; + padding: 5px 0; + background: #eee; + width: 150px; + max-height: calc(100% - 80px); + overflow: auto; + } + + #menubar .menu:hover .options { + display: block; + } + + #menubar .menu .options hr { + border-color: #ddd; + } + + #menubar .menu .options .option { + color: #666; + background-color: transparent; + padding: 5px 10px; + margin: 0 !important; + } + + #menubar .menu .options .option:hover { + color: #fff; + background-color: #08f; + } + + #menubar .menu .options .option:active { + color: #666; + background: transparent; + } + + #menubar .menu .options .inactive { + color: #bbb; + background-color: transparent; + padding: 5px 10px; + margin: 0 !important; + } + +#sidebar { + position: absolute; + right: 0; + top: 32px; + bottom: 0; + width: 300px; + background: #eee; + overflow: auto; +} + + #sidebar * { + vertical-align: middle; + } + + #sidebar .Panel { + color: #888; + padding: 10px; + border-top: 1px solid #ccc; + } + + #sidebar .Panel.collapsed { + margin-bottom: 0; + } + + #sidebar .Row { + min-height: 20px; + margin-bottom: 10px; + } + +#tabs { + background-color: #ddd; + border-top: 1px solid #ccc; +} + + #tabs span { + color: #aaa; + border-right: 1px solid #ccc; + padding: 10px; + } + + #tabs span.selected { + color: #888; + background-color: #eee; + } + +#toolbar { + position: absolute; + left: calc(50% - 290px); /* ( ( 100% - 300px ) / 2.0 ) - 140px */ + width: 280px; + bottom: 16px; + height: 32px; + background: #eee; + color: #333; +} + + #toolbar * { + vertical-align: middle; + } + + #toolbar .Panel { + padding: 4px; + color: #888; + } + + #toolbar button { + margin-right: 6px; + line-height: 14px; + height: 24px; + } + +.Outliner { + color: #444; + background-color: #fff; + padding: 0; + width: 100%; + height: 140px; + font-size: 12px; + cursor: default; + overflow: auto; + outline: none !important; +} + + .Outliner .option { + padding: 4px; + color: #666; + white-space: nowrap; + } + + .Outliner .option:hover { + background-color: rgba(0,0,0,0.02); + } + + .Outliner .option.active { + background-color: rgba(0,0,0,0.04); + } + + +.TabbedPanel .Tabs { + background-color: #ddd; + border-top: 1px solid #ccc; +} + + .TabbedPanel .Tab { + color: #aaa; + border-right: 1px solid #ccc; + } + + .TabbedPanel .Tab.selected { + color: #888; + background-color: #eee; + } + +.Listbox { + color: #444; + background-color: #fff; +} + +.Panel { + color: #888; +} + +/* */ + +@media all and ( max-width: 600px ) { + + #menubar .menu .options { + max-height: calc(100% - 372px); + } + + #menubar .menu.right { + display: none; + } + + #viewport { + left: 0; + right: 0; + top: 32px; + height: calc(100% - 352px); + } + + #script { + left: 0; + right: 0; + top: 32px; + height: calc(100% - 352px); + } + + #player { + left: 0; + right: 0; + top: 32px; + height: calc(100% - 352px); + } + + #sidebar { + left: 0; + width: 100%; + top: calc(100% - 320px); + bottom: 0; + } + + #toolbar { + left: calc(50% - 140px); + width: 280px; + top: 68px; + } + +} + +/* DARK MODE */ + +@media ( prefers-color-scheme: dark ) { + + button { + color: #aaa; + background-color: #222; + } + + button:hover { + color: #ccc; + background-color: #444; + } + + button.selected { + color: #fff; + background-color: #08f; + } + + input, textarea { + background-color: #222; + border: 1px solid transparent; + color: #888; + } + + select { + color: #aaa; + background-color: #222; + } + + select:hover { + color: #ccc; + background-color: #444; + } + + /* UI */ + + #menubar { + background: #111; + } + + #menubar .menu .options { + background: #111; + } + + #menubar .menu .options hr { + border-color: #222; + } + + #menubar .menu .options .option { + color: #888; + } + + #menubar .menu .options .inactive { + color: #444; + } + + #sidebar { + background-color: #111; + } + + #sidebar .Panel { + border-top: 1px solid #222; + } + + #sidebar .Panel.Material canvas { + border: solid 1px #5A5A5A; + } + + #tabs { + background-color: #1b1b1b; + border-top: 1px solid #222; + } + + #tabs span { + color: #555; + border-right: 1px solid #222; + } + + #tabs span.selected { + background-color: #111; + } + + #toolbar { + background-color: #111; + } + + .Outliner { + color: #888; + background: #222; + } + + .Outliner .option:hover { + background-color: rgba(21,60,94,0.5); + } + + .Outliner .option.active { + background-color: rgba(21,60,94,1); + } + + .TabbedPanel .Tabs { + background-color: #1b1b1b; + border-top: 1px solid #222; + } + + .TabbedPanel .Tab { + color: #555; + border-right: 1px solid #222; + } + + .TabbedPanel .Tab.selected { + color: #888; + background-color: #111; + } + + .Listbox { + color: #888; + background: #222; + } + + .Listbox .ListboxItem:hover { + background-color: rgba(21,60,94,0.5); + } + + .Listbox .ListboxItem.active { + background-color: rgba(21,60,94,1); + } + +} diff --git a/editor/index.html b/editor/index.html index 48bd5f0de0965b..50ebc3e2d8064c 100644 --- a/editor/index.html +++ b/editor/index.html @@ -7,52 +7,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -60,7 +19,6 @@ - @@ -68,6 +26,7 @@ + @@ -82,110 +41,39 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ' ); - - } - content = content.replace( '', includes.join( '\n\t\t' ) ); var editButton = ''; @@ -353,12 +392,13 @@ Menubar.File = function ( editor ) { '', ' var button = document.createElement( \'a\' );', ' button.href = \'https://threejs.org/editor/#file=\' + location.href.split( \'/\' ).slice( 0, - 1 ).join( \'/\' ) + \'/app.json\';', - ' button.style.cssText = \'position: absolute; bottom: 20px; right: 20px; padding: 12px 14px; color: #fff; border: 1px solid #fff; border-radius: 4px; text-decoration: none;\';', + ' button.style.cssText = \'position: absolute; bottom: 20px; right: 20px; padding: 10px 16px; color: #fff; border: 1px solid #fff; border-radius: 20px; text-decoration: none;\';', ' button.target = \'_blank\';', ' button.textContent = \'EDIT\';', ' document.body.appendChild( button );', '' ].join( '\n' ); + } content = content.replace( '\n\t\t\t/* edit button */\n', editButton ); @@ -371,21 +411,21 @@ Menubar.File = function ( editor ) { zip.file( 'js/app.js', content ); } ); - loader.load( '../build/three.min.js', function ( content ) { + loader.load( '../build/three.module.js', function ( content ) { - zip.file( 'js/three.min.js', content ); + zip.file( 'js/three.module.js', content ); } ); + loader.load( '../examples/jsm/webxr/VRButton.js', function ( content ) { - if ( vr ) { + zip.file( 'js/VRButton.js', content ); - loader.load( '../examples/js/vr/WebVR.js', function ( content ) { - - zip.file( 'js/WebVR.js', content ); + } ); + loader.load( '../examples/js/vr/HelioWebXRPolyfill.js', function ( content ) { - } ); + zip.file( 'js/HelioWebXRPolyfill.js', content ); - } + } ); } ); options.add( option ); @@ -418,3 +458,5 @@ Menubar.File = function ( editor ) { return container; }; + +export { MenubarFile }; diff --git a/editor/js/Menubar.Help.js b/editor/js/Menubar.Help.js index aab8f2703c866d..830d7f09a5b25a 100644 --- a/editor/js/Menubar.Help.js +++ b/editor/js/Menubar.Help.js @@ -2,37 +2,39 @@ * @author mrdoob / http://mrdoob.com/ */ -Menubar.Help = function ( editor ) { +import { UIPanel, UIRow } from './libs/ui.js'; + +var MenubarHelp = function ( editor ) { var strings = editor.strings; - var container = new UI.Panel(); + var container = new UIPanel(); container.setClass( 'menu' ); - var title = new UI.Panel(); + var title = new UIPanel(); title.setClass( 'title' ); title.setTextContent( strings.getKey( 'menubar/help' ) ); container.add( title ); - var options = new UI.Panel(); + var options = new UIPanel(); options.setClass( 'options' ); container.add( options ); // Source code - var option = new UI.Row(); + var option = new UIRow(); option.setClass( 'option' ); option.setTextContent( strings.getKey( 'menubar/help/source_code' ) ); option.onClick( function () { - window.open( 'https://github.com/mrdoob/three.js/tree/master/editor', '_blank' ) + window.open( 'https://github.com/mrdoob/three.js/tree/master/editor', '_blank' ); } ); options.add( option ); // About - var option = new UI.Row(); + var option = new UIRow(); option.setClass( 'option' ); option.setTextContent( strings.getKey( 'menubar/help/about' ) ); option.onClick( function () { @@ -45,3 +47,5 @@ Menubar.Help = function ( editor ) { return container; }; + +export { MenubarHelp }; diff --git a/editor/js/Menubar.Play.js b/editor/js/Menubar.Play.js index c23132a521278a..5ad0b70df164f2 100644 --- a/editor/js/Menubar.Play.js +++ b/editor/js/Menubar.Play.js @@ -2,17 +2,19 @@ * @author mrdoob / http://mrdoob.com/ */ -Menubar.Play = function ( editor ) { +import { UIPanel } from './libs/ui.js'; + +var MenubarPlay = function ( editor ) { var signals = editor.signals; var strings = editor.strings; - var container = new UI.Panel(); + var container = new UIPanel(); container.setClass( 'menu' ); var isPlaying = false; - var title = new UI.Panel(); + var title = new UIPanel(); title.setClass( 'title' ); title.setTextContent( strings.getKey( 'menubar/play' ) ); title.onClick( function () { @@ -37,3 +39,5 @@ Menubar.Play = function ( editor ) { return container; }; + +export { MenubarPlay }; diff --git a/editor/js/Menubar.Status.js b/editor/js/Menubar.Status.js index f1b6927fff4c28..020ca7669e5a43 100644 --- a/editor/js/Menubar.Status.js +++ b/editor/js/Menubar.Status.js @@ -2,14 +2,19 @@ * @author mrdoob / http://mrdoob.com/ */ -Menubar.Status = function ( editor ) { +import * as THREE from '../../build/three.module.js'; + +import { UIPanel, UIText } from './libs/ui.js'; +import { UIBoolean } from './libs/ui.three.js'; + +var MenubarStatus = function ( editor ) { var strings = editor.strings; - var container = new UI.Panel(); + var container = new UIPanel(); container.setClass( 'menu right' ); - var autosave = new UI.THREE.Boolean( editor.config.getKey( 'autosave' ), strings.getKey( 'menubar/status/autosave' ) ); + var autosave = new UIBoolean( editor.config.getKey( 'autosave' ), strings.getKey( 'menubar/status/autosave' ) ); autosave.text.setColor( '#888' ); autosave.onChange( function () { @@ -38,7 +43,7 @@ Menubar.Status = function ( editor ) { } ); - var version = new UI.Text( 'r' + THREE.REVISION ); + var version = new UIText( 'r' + THREE.REVISION ); version.setClass( 'title' ); version.setOpacity( 0.5 ); container.add( version ); @@ -46,3 +51,5 @@ Menubar.Status = function ( editor ) { return container; }; + +export { MenubarStatus }; diff --git a/editor/js/Menubar.View.js b/editor/js/Menubar.View.js index 3cb905c6d4a7ae..8a38d27d1afcd2 100644 --- a/editor/js/Menubar.View.js +++ b/editor/js/Menubar.View.js @@ -2,23 +2,25 @@ * @author mrdoob / http://mrdoob.com/ */ -Menubar.View = function ( editor ) { +import { UIPanel, UIRow } from './libs/ui.js'; - var container = new UI.Panel(); +var MenubarView = function ( editor ) { + + var container = new UIPanel(); container.setClass( 'menu' ); - var title = new UI.Panel(); + var title = new UIPanel(); title.setClass( 'title' ); title.setTextContent( 'View' ); container.add( title ); - var options = new UI.Panel(); + var options = new UIPanel(); options.setClass( 'options' ); container.add( options ); // VR mode - var option = new UI.Row(); + var option = new UIRow(); option.setClass( 'option' ); option.setTextContent( 'VR mode' ); option.onClick( function () { @@ -31,3 +33,5 @@ Menubar.View = function ( editor ) { return container; }; + +export { MenubarView }; diff --git a/editor/js/Menubar.js b/editor/js/Menubar.js index 0d1d033fc9847b..10501b36632748 100644 --- a/editor/js/Menubar.js +++ b/editor/js/Menubar.js @@ -2,21 +2,32 @@ * @author mrdoob / http://mrdoob.com/ */ +import { UIPanel } from './libs/ui.js'; + +import { MenubarAdd } from './Menubar.Add.js'; +import { MenubarEdit } from './Menubar.Edit.js'; +import { MenubarFile } from './Menubar.File.js'; +import { MenubarExamples } from './Menubar.Examples.js'; +import { MenubarHelp } from './Menubar.Help.js'; +import { MenubarPlay } from './Menubar.Play.js'; +import { MenubarStatus } from './Menubar.Status.js'; + var Menubar = function ( editor ) { - var container = new UI.Panel(); + var container = new UIPanel(); container.setId( 'menubar' ); - container.add( new Menubar.File( editor ) ); - container.add( new Menubar.Edit( editor ) ); - container.add( new Menubar.Add( editor ) ); - container.add( new Menubar.Play( editor ) ); - // container.add( new Menubar.View( editor ) ); - container.add( new Menubar.Examples( editor ) ); - container.add( new Menubar.Help( editor ) ); + container.add( new MenubarFile( editor ) ); + container.add( new MenubarEdit( editor ) ); + container.add( new MenubarAdd( editor ) ); + container.add( new MenubarPlay( editor ) ); + container.add( new MenubarExamples( editor ) ); + container.add( new MenubarHelp( editor ) ); - container.add( new Menubar.Status( editor ) ); + container.add( new MenubarStatus( editor ) ); return container; }; + +export { Menubar }; diff --git a/editor/js/Player.js b/editor/js/Player.js index a6fea7512738f3..6558ce98a4104b 100644 --- a/editor/js/Player.js +++ b/editor/js/Player.js @@ -2,11 +2,14 @@ * @author mrdoob / http://mrdoob.com/ */ -var Player = function ( editor ) { +import { UIPanel } from './libs/ui.js'; +import { APP } from './libs/app.js'; + +function Player( editor ) { var signals = editor.signals; - var container = new UI.Panel(); + var container = new UIPanel(); container.setId( 'player' ); container.setPosition( 'absolute' ); container.setDisplay( 'none' ); @@ -43,4 +46,6 @@ var Player = function ( editor ) { return container; -}; +} + +export { Player }; diff --git a/editor/js/Script.js b/editor/js/Script.js index 7a76d31011e8c3..c9f5fa68251a31 100644 --- a/editor/js/Script.js +++ b/editor/js/Script.js @@ -2,21 +2,26 @@ * @author mrdoob / http://mrdoob.com/ */ +import { UIElement, UIPanel, UIText } from './libs/ui.js'; + +import { SetScriptValueCommand } from './commands/SetScriptValueCommand.js'; +import { SetMaterialValueCommand } from './commands/SetMaterialValueCommand.js'; + var Script = function ( editor ) { var signals = editor.signals; - var container = new UI.Panel(); + var container = new UIPanel(); container.setId( 'script' ); container.setPosition( 'absolute' ); container.setBackgroundColor( '#272822' ); container.setDisplay( 'none' ); - var header = new UI.Panel(); + var header = new UIPanel(); header.setPadding( '10px' ); container.add( header ); - var title = new UI.Text().setColor( '#fff' ); + var title = new UIText().setColor( '#fff' ); header.add( title ); var buttonSVG = ( function () { @@ -32,7 +37,7 @@ var Script = function ( editor ) { } )(); - var close = new UI.Element( buttonSVG ); + var close = new UIElement( buttonSVG ); close.setPosition( 'absolute' ); close.setTop( '3px' ); close.setRight( '1px' ); @@ -320,13 +325,41 @@ var Script = function ( editor ) { } ); codemirror.setOption( 'extraKeys', { - 'Ctrl-Space': function ( cm ) { server.complete( cm ); }, - 'Ctrl-I': function ( cm ) { server.showType( cm ); }, - 'Ctrl-O': function ( cm ) { server.showDocs( cm ); }, - 'Alt-.': function ( cm ) { server.jumpToDef( cm ); }, - 'Alt-,': function ( cm ) { server.jumpBack( cm ); }, - 'Ctrl-Q': function ( cm ) { server.rename( cm ); }, - 'Ctrl-.': function ( cm ) { server.selectName( cm ); } + 'Ctrl-Space': function ( cm ) { + + server.complete( cm ); + + }, + 'Ctrl-I': function ( cm ) { + + server.showType( cm ); + + }, + 'Ctrl-O': function ( cm ) { + + server.showDocs( cm ); + + }, + 'Alt-.': function ( cm ) { + + server.jumpToDef( cm ); + + }, + 'Alt-,': function ( cm ) { + + server.jumpBack( cm ); + + }, + 'Ctrl-Q': function ( cm ) { + + server.rename( cm ); + + }, + 'Ctrl-.': function ( cm ) { + + server.selectName( cm ); + + } } ); codemirror.on( 'cursorActivity', function ( cm ) { @@ -429,3 +462,5 @@ var Script = function ( editor ) { return container; }; + +export { Script }; diff --git a/editor/js/Sidebar.Animation.js b/editor/js/Sidebar.Animation.js index 8369f3d2fb719f..66118d534db6f4 100644 --- a/editor/js/Sidebar.Animation.js +++ b/editor/js/Sidebar.Animation.js @@ -2,7 +2,9 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Animation = function ( editor ) { +import { UIPanel, UIDiv, UIBreak, UISelect, UIButton, UIText } from './libs/ui.js'; + +var SidebarAnimation = function ( editor ) { var signals = editor.signals; var mixer = editor.mixer; @@ -64,21 +66,23 @@ Sidebar.Animation = function ( editor ) { } - var container = new UI.Panel(); + var container = new UIPanel(); container.setDisplay( 'none' ); - container.add( new UI.Text( 'Animations' ).setTextTransform( 'uppercase' ) ); - container.add( new UI.Break() ); - container.add( new UI.Break() ); + container.add( new UIText( 'Animations' ).setTextTransform( 'uppercase' ) ); + container.add( new UIBreak() ); + container.add( new UIBreak() ); - var div = new UI.Div(); + var div = new UIDiv(); container.add( div ); - var animationsSelect = new UI.Select().setFontSize( '12px' ); + var animationsSelect = new UISelect().setFontSize( '12px' ); div.add( animationsSelect ); - div.add( new UI.Button( 'Play' ).setMarginLeft( '4px' ).onClick( playAction ) ); - div.add( new UI.Button( 'Stop' ).setMarginLeft( '4px' ).onClick( stopAction ) ); + div.add( new UIButton( 'Play' ).setMarginLeft( '4px' ).onClick( playAction ) ); + div.add( new UIButton( 'Stop' ).setMarginLeft( '4px' ).onClick( stopAction ) ); return container; }; + +export { SidebarAnimation }; diff --git a/editor/js/Sidebar.Geometry.BoxGeometry.js b/editor/js/Sidebar.Geometry.BoxGeometry.js index e158f673099b02..52b8de52c77f13 100644 --- a/editor/js/Sidebar.Geometry.BoxGeometry.js +++ b/editor/js/Sidebar.Geometry.BoxGeometry.js @@ -2,73 +2,77 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.BoxGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UINumber, UIInteger } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryBoxGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // width - var widthRow = new UI.Row(); - var width = new UI.Number( parameters.width ).onChange( update ); + var widthRow = new UIRow(); + var width = new UINumber( parameters.width ).onChange( update ); - widthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/box_geometry/width' ) ).setWidth( '90px' ) ); + widthRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/width' ) ).setWidth( '90px' ) ); widthRow.add( width ); container.add( widthRow ); // height - var heightRow = new UI.Row(); - var height = new UI.Number( parameters.height ).onChange( update ); + var heightRow = new UIRow(); + var height = new UINumber( parameters.height ).onChange( update ); - heightRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/box_geometry/height' ) ).setWidth( '90px' ) ); + heightRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/height' ) ).setWidth( '90px' ) ); heightRow.add( height ); container.add( heightRow ); // depth - var depthRow = new UI.Row(); - var depth = new UI.Number( parameters.depth ).onChange( update ); + var depthRow = new UIRow(); + var depth = new UINumber( parameters.depth ).onChange( update ); - depthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/box_geometry/depth' ) ).setWidth( '90px' ) ); + depthRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/depth' ) ).setWidth( '90px' ) ); depthRow.add( depth ); container.add( depthRow ); // widthSegments - var widthSegmentsRow = new UI.Row(); - var widthSegments = new UI.Integer( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update ); + var widthSegmentsRow = new UIRow(); + var widthSegments = new UIInteger( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update ); - widthSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/box_geometry/widthseg' ) ).setWidth( '90px' ) ); + widthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/widthseg' ) ).setWidth( '90px' ) ); widthSegmentsRow.add( widthSegments ); container.add( widthSegmentsRow ); // heightSegments - var heightSegmentsRow = new UI.Row(); - var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); + var heightSegmentsRow = new UIRow(); + var heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); - heightSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/box_geometry/heightseg' ) ).setWidth( '90px' ) ); + heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/heightseg' ) ).setWidth( '90px' ) ); heightSegmentsRow.add( heightSegments ); container.add( heightSegmentsRow ); // depthSegments - var depthSegmentsRow = new UI.Row(); - var depthSegments = new UI.Integer( parameters.depthSegments ).setRange( 1, Infinity ).onChange( update ); + var depthSegmentsRow = new UIRow(); + var depthSegments = new UIInteger( parameters.depthSegments ).setRange( 1, Infinity ).onChange( update ); - depthSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/box_geometry/depthseg' ) ).setWidth( '90px' ) ); + depthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/box_geometry/depthseg' ) ).setWidth( '90px' ) ); depthSegmentsRow.add( depthSegments ); container.add( depthSegmentsRow ); @@ -77,7 +81,7 @@ Sidebar.Geometry.BoxGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.BoxBufferGeometry( width.getValue(), height.getValue(), depth.getValue(), @@ -92,4 +96,4 @@ Sidebar.Geometry.BoxGeometry = function ( editor, object ) { }; -Sidebar.Geometry.BoxBufferGeometry = Sidebar.Geometry.BoxGeometry; +export { SidebarGeometryBoxGeometry }; diff --git a/editor/js/Sidebar.Geometry.BufferGeometry.js b/editor/js/Sidebar.Geometry.BufferGeometry.js index e93d846c825bdc..f0c32a8759f275 100644 --- a/editor/js/Sidebar.Geometry.BufferGeometry.js +++ b/editor/js/Sidebar.Geometry.BufferGeometry.js @@ -2,13 +2,15 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.BufferGeometry = function ( editor ) { +import { UIRow, UIText, UISpan, UIBreak } from './libs/ui.js'; + +var SidebarGeometryBufferGeometry = function ( editor ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Row(); + var container = new UIRow(); function update( object ) { @@ -22,19 +24,19 @@ Sidebar.Geometry.BufferGeometry = function ( editor ) { container.clear(); container.setDisplay( 'block' ); - var text = new UI.Text( strings.getKey( 'sidebar/geometry/buffer_geometry/attributes' ) ).setWidth( '90px' ); + var text = new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/attributes' ) ).setWidth( '90px' ); container.add( text ); - var container2 = new UI.Span().setDisplay( 'inline-block' ).setWidth( '160px' ); + var container2 = new UISpan().setDisplay( 'inline-block' ).setWidth( '160px' ); container.add( container2 ); var index = geometry.index; if ( index !== null ) { - container2.add( new UI.Text( strings.getKey( 'sidebar/geometry/buffer_geometry/index' ) ).setWidth( '80px' ) ); - container2.add( new UI.Text( ( index.count ).format() ).setFontSize( '12px' ) ); - container2.add( new UI.Break() ); + container2.add( new UIText( strings.getKey( 'sidebar/geometry/buffer_geometry/index' ) ).setWidth( '80px' ) ); + container2.add( new UIText( ( index.count ).format() ).setFontSize( '12px' ) ); + container2.add( new UIBreak() ); } @@ -44,9 +46,9 @@ Sidebar.Geometry.BufferGeometry = function ( editor ) { var attribute = attributes[ name ]; - container2.add( new UI.Text( name ).setWidth( '80px' ) ); - container2.add( new UI.Text( ( attribute.count ).format() + ' (' + attribute.itemSize + ')' ).setFontSize( '12px' ) ); - container2.add( new UI.Break() ); + container2.add( new UIText( name ).setWidth( '80px' ) ); + container2.add( new UIText( ( attribute.count ).format() + ' (' + attribute.itemSize + ')' ).setFontSize( '12px' ) ); + container2.add( new UIBreak() ); } @@ -64,3 +66,5 @@ Sidebar.Geometry.BufferGeometry = function ( editor ) { return container; }; + +export { SidebarGeometryBufferGeometry }; diff --git a/editor/js/Sidebar.Geometry.CircleGeometry.js b/editor/js/Sidebar.Geometry.CircleGeometry.js index ce3a52514d2cc0..23a109c44b9d67 100644 --- a/editor/js/Sidebar.Geometry.CircleGeometry.js +++ b/editor/js/Sidebar.Geometry.CircleGeometry.js @@ -2,53 +2,57 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.CircleGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryCircleGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/circle_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // segments - var segmentsRow = new UI.Row(); - var segments = new UI.Integer( parameters.segments ).setRange( 3, Infinity ).onChange( update ); + var segmentsRow = new UIRow(); + var segments = new UIInteger( parameters.segments ).setRange( 3, Infinity ).onChange( update ); - segmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/circle_geometry/segments' ) ).setWidth( '90px' ) ); + segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/segments' ) ).setWidth( '90px' ) ); segmentsRow.add( segments ); container.add( segmentsRow ); // thetaStart - var thetaStartRow = new UI.Row(); - var thetaStart = new UI.Number( parameters.thetaStart * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var thetaStartRow = new UIRow(); + var thetaStart = new UINumber( parameters.thetaStart * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - thetaStartRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/circle_geometry/thetastart' ) ).setWidth( '90px' ) ); + thetaStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/thetastart' ) ).setWidth( '90px' ) ); thetaStartRow.add( thetaStart ); container.add( thetaStartRow ); // thetaLength - var thetaLengthRow = new UI.Row(); - var thetaLength = new UI.Number( parameters.thetaLength * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var thetaLengthRow = new UIRow(); + var thetaLength = new UINumber( parameters.thetaLength * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - thetaLengthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/circle_geometry/thetalength' ) ).setWidth( '90px' ) ); + thetaLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/circle_geometry/thetalength' ) ).setWidth( '90px' ) ); thetaLengthRow.add( thetaLength ); container.add( thetaLengthRow ); @@ -57,11 +61,11 @@ Sidebar.Geometry.CircleGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.CircleBufferGeometry( radius.getValue(), segments.getValue(), - thetaStart.getValue() * THREE.Math.DEG2RAD, - thetaLength.getValue() * THREE.Math.DEG2RAD + thetaStart.getValue() * THREE.MathUtils.DEG2RAD, + thetaLength.getValue() * THREE.MathUtils.DEG2RAD ) ) ); } @@ -70,4 +74,4 @@ Sidebar.Geometry.CircleGeometry = function ( editor, object ) { }; -Sidebar.Geometry.CircleBufferGeometry = Sidebar.Geometry.CircleGeometry; +export { SidebarGeometryCircleGeometry }; diff --git a/editor/js/Sidebar.Geometry.CylinderGeometry.js b/editor/js/Sidebar.Geometry.CylinderGeometry.js index a4d64b6b47afde..82008389d048da 100644 --- a/editor/js/Sidebar.Geometry.CylinderGeometry.js +++ b/editor/js/Sidebar.Geometry.CylinderGeometry.js @@ -2,73 +2,77 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.CylinderGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UICheckbox, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryCylinderGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radiusTop - var radiusTopRow = new UI.Row(); - var radiusTop = new UI.Number( parameters.radiusTop ).onChange( update ); + var radiusTopRow = new UIRow(); + var radiusTop = new UINumber( parameters.radiusTop ).onChange( update ); - radiusTopRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiustop' ) ).setWidth( '90px' ) ); + radiusTopRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiustop' ) ).setWidth( '90px' ) ); radiusTopRow.add( radiusTop ); container.add( radiusTopRow ); // radiusBottom - var radiusBottomRow = new UI.Row(); - var radiusBottom = new UI.Number( parameters.radiusBottom ).onChange( update ); + var radiusBottomRow = new UIRow(); + var radiusBottom = new UINumber( parameters.radiusBottom ).onChange( update ); - radiusBottomRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiusbottom' ) ).setWidth( '90px' ) ); + radiusBottomRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radiusbottom' ) ).setWidth( '90px' ) ); radiusBottomRow.add( radiusBottom ); container.add( radiusBottomRow ); // height - var heightRow = new UI.Row(); - var height = new UI.Number( parameters.height ).onChange( update ); + var heightRow = new UIRow(); + var height = new UINumber( parameters.height ).onChange( update ); - heightRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/cylinder_geometry/height' ) ).setWidth( '90px' ) ); + heightRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/height' ) ).setWidth( '90px' ) ); heightRow.add( height ); container.add( heightRow ); // radialSegments - var radialSegmentsRow = new UI.Row(); - var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update ); + var radialSegmentsRow = new UIRow(); + var radialSegments = new UIInteger( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update ); - radialSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/cylinder_geometry/radialsegments' ) ).setWidth( '90px' ) ); + radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/radialsegments' ) ).setWidth( '90px' ) ); radialSegmentsRow.add( radialSegments ); container.add( radialSegmentsRow ); // heightSegments - var heightSegmentsRow = new UI.Row(); - var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); + var heightSegmentsRow = new UIRow(); + var heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); - heightSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/cylinder_geometry/heightsegments' ) ).setWidth( '90px' ) ); + heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/heightsegments' ) ).setWidth( '90px' ) ); heightSegmentsRow.add( heightSegments ); container.add( heightSegmentsRow ); // openEnded - var openEndedRow = new UI.Row(); - var openEnded = new UI.Checkbox( parameters.openEnded ).onChange( update ); + var openEndedRow = new UIRow(); + var openEnded = new UICheckbox( parameters.openEnded ).onChange( update ); - openEndedRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/cylinder_geometry/openended' ) ).setWidth( '90px' ) ); + openEndedRow.add( new UIText( strings.getKey( 'sidebar/geometry/cylinder_geometry/openended' ) ).setWidth( '90px' ) ); openEndedRow.add( openEnded ); container.add( openEndedRow ); @@ -77,7 +81,7 @@ Sidebar.Geometry.CylinderGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.CylinderBufferGeometry( radiusTop.getValue(), radiusBottom.getValue(), height.getValue(), @@ -92,4 +96,4 @@ Sidebar.Geometry.CylinderGeometry = function ( editor, object ) { }; -Sidebar.Geometry.CylinderBufferGeometry = Sidebar.Geometry.CylinderGeometry; +export { SidebarGeometryCylinderGeometry }; diff --git a/editor/js/Sidebar.Geometry.DodecahedronGeometry.js b/editor/js/Sidebar.Geometry.DodecahedronGeometry.js new file mode 100644 index 00000000000000..fd807a1b519c78 --- /dev/null +++ b/editor/js/Sidebar.Geometry.DodecahedronGeometry.js @@ -0,0 +1,55 @@ +/** + * @author mrdoob / http://mrdoob.com/ + */ + +import * as THREE from '../../build/three.module.js'; + +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; + +var SidebarGeometryDodecahedronGeometry = function ( editor, object ) { + + var strings = editor.strings; + + var container = new UIRow(); + + var geometry = object.geometry; + var parameters = geometry.parameters; + + // radius + + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); + + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( radius ); + + container.add( radiusRow ); + + // detail + + var detailRow = new UIRow(); + var detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update ); + + detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/dodecahedron_geometry/detail' ) ).setWidth( '90px' ) ); + detailRow.add( detail ); + + container.add( detailRow ); + + // + + function update() { + + editor.execute( new SetGeometryCommand( editor, object, new THREE.DodecahedronBufferGeometry( + radius.getValue(), + detail.getValue() + ) ) ); + + } + + return container; + +}; + +export { SidebarGeometryDodecahedronGeometry }; diff --git a/editor/js/Sidebar.Geometry.ExtrudeGeometry.js b/editor/js/Sidebar.Geometry.ExtrudeGeometry.js index 99f5e9a38f8689..969f5e5af125e4 100644 --- a/editor/js/Sidebar.Geometry.ExtrudeGeometry.js +++ b/editor/js/Sidebar.Geometry.ExtrudeGeometry.js @@ -2,13 +2,17 @@ * @author Temdog007 / http://github.com/Temdog007 */ -Sidebar.Geometry.ExtrudeGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UICheckbox, UIButton, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryExtrudeGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; @@ -24,40 +28,40 @@ Sidebar.Geometry.ExtrudeGeometry = function ( editor, object ) { // curveSegments - var curveSegmentsRow = new UI.Row(); - var curveSegments = new UI.Integer( options.curveSegments ).onChange( update ).setRange( 1, Infinity ); + var curveSegmentsRow = new UIRow(); + var curveSegments = new UIInteger( options.curveSegments ).onChange( update ).setRange( 1, Infinity ); - curveSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/curveSegments' ) ).setWidth( '90px' ) ); + curveSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/curveSegments' ) ).setWidth( '90px' ) ); curveSegmentsRow.add( curveSegments ); container.add( curveSegmentsRow ); // steps - var stepsRow = new UI.Row(); - var steps = new UI.Integer( options.steps ).onChange( update ).setRange( 1, Infinity ); + var stepsRow = new UIRow(); + var steps = new UIInteger( options.steps ).onChange( update ).setRange( 1, Infinity ); - stepsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/steps' ) ).setWidth( '90px' ) ); + stepsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/steps' ) ).setWidth( '90px' ) ); stepsRow.add( steps ); container.add( stepsRow ); // depth - var depthRow = new UI.Row(); - var depth = new UI.Number( options.depth ).onChange( update ).setRange( 1, Infinity ); + var depthRow = new UIRow(); + var depth = new UINumber( options.depth ).onChange( update ).setRange( 1, Infinity ); - depthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/depth' ) ).setWidth( '90px' ) ); + depthRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/depth' ) ).setWidth( '90px' ) ); depthRow.add( depth ); container.add( depthRow ); // enabled - var enabledRow = new UI.Row(); - var enabled = new UI.Checkbox( options.bevelEnabled ).onChange( update ); + var enabledRow = new UIRow(); + var enabled = new UICheckbox( options.bevelEnabled ).onChange( update ); - enabledRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelEnabled' ) ).setWidth( '90px' ) ); + enabledRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelEnabled' ) ).setWidth( '90px' ) ); enabledRow.add( enabled ); container.add( enabledRow ); @@ -66,54 +70,54 @@ Sidebar.Geometry.ExtrudeGeometry = function ( editor, object ) { // thickness - var thicknessRow = new UI.Row(); - var thickness = new UI.Number( options.bevelThickness ).onChange( update ); + var thicknessRow = new UIRow(); + var thickness = new UINumber( options.bevelThickness ).onChange( update ); - thicknessRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelThickness' ) ).setWidth( '90px' ) ); + thicknessRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelThickness' ) ).setWidth( '90px' ) ); thicknessRow.add( thickness ); container.add( thicknessRow ); // size - var sizeRow = new UI.Row(); - var size = new UI.Number( options.bevelSize ).onChange( update ); + var sizeRow = new UIRow(); + var size = new UINumber( options.bevelSize ).onChange( update ); - sizeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSize' ) ).setWidth( '90px' ) ); + sizeRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSize' ) ).setWidth( '90px' ) ); sizeRow.add( size ); container.add( sizeRow ); // offset - var offsetRow = new UI.Row(); - var offset = new UI.Number( options.bevelOffset ).onChange( update ); + var offsetRow = new UIRow(); + var offset = new UINumber( options.bevelOffset ).onChange( update ); - offsetRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelOffset' ) ).setWidth( '90px' ) ); + offsetRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelOffset' ) ).setWidth( '90px' ) ); offsetRow.add( offset ); container.add( offsetRow ); // segments - var segmentsRow = new UI.Row(); - var segments = new UI.Integer( options.bevelSegments ).onChange( update ).setRange( 0, Infinity ); + var segmentsRow = new UIRow(); + var segments = new UIInteger( options.bevelSegments ).onChange( update ).setRange( 0, Infinity ); - segmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSegments' ) ).setWidth( '90px' ) ); + segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/extrude_geometry/bevelSegments' ) ).setWidth( '90px' ) ); segmentsRow.add( segments ); container.add( segmentsRow ); } - var button = new UI.Button( strings.getKey( 'sidebar/geometry/extrude_geometry/shape' ) ).onClick( toShape ).setWidth( '90px' ).setMarginLeft( '90px' ); + var button = new UIButton( strings.getKey( 'sidebar/geometry/extrude_geometry/shape' ) ).onClick( toShape ).setWidth( '90px' ).setMarginLeft( '90px' ); container.add( button ); // function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.ExtrudeBufferGeometry( parameters.shapes, { curveSegments: curveSegments.getValue(), @@ -142,4 +146,4 @@ Sidebar.Geometry.ExtrudeGeometry = function ( editor, object ) { }; -Sidebar.Geometry.ExtrudeBufferGeometry = Sidebar.Geometry.ExtrudeGeometry; +export { SidebarGeometryExtrudeGeometry }; diff --git a/editor/js/Sidebar.Geometry.Geometry.js b/editor/js/Sidebar.Geometry.Geometry.js index 91435e938374ee..5c59a0e04f6e49 100644 --- a/editor/js/Sidebar.Geometry.Geometry.js +++ b/editor/js/Sidebar.Geometry.Geometry.js @@ -2,30 +2,32 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.Geometry = function ( editor ) { +import { UIRow, UIText } from './libs/ui.js'; + +var SidebarGeometryGeometry = function ( editor ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Row(); + var container = new UIRow(); // vertices - var verticesRow = new UI.Row(); - var vertices = new UI.Text(); + var verticesRow = new UIRow(); + var vertices = new UIText(); - verticesRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/geometry/vertices' ) ).setWidth( '90px' ) ); + verticesRow.add( new UIText( strings.getKey( 'sidebar/geometry/geometry/vertices' ) ).setWidth( '90px' ) ); verticesRow.add( vertices ); container.add( verticesRow ); // faces - var facesRow = new UI.Row(); - var faces = new UI.Text(); + var facesRow = new UIRow(); + var faces = new UIText(); - facesRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/geometry/faces' ) ).setWidth( '90px' ) ); + facesRow.add( new UIText( strings.getKey( 'sidebar/geometry/geometry/faces' ) ).setWidth( '90px' ) ); facesRow.add( faces ); container.add( facesRow ); @@ -60,3 +62,5 @@ Sidebar.Geometry.Geometry = function ( editor ) { return container; }; + +export { SidebarGeometryGeometry }; diff --git a/editor/js/Sidebar.Geometry.IcosahedronGeometry.js b/editor/js/Sidebar.Geometry.IcosahedronGeometry.js index 8309f5acfc2ae5..c5b0bc88da14a5 100644 --- a/editor/js/Sidebar.Geometry.IcosahedronGeometry.js +++ b/editor/js/Sidebar.Geometry.IcosahedronGeometry.js @@ -2,43 +2,48 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.IcosahedronGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; + +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; + +var SidebarGeometryIcosahedronGeometry = function ( editor, object ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/icosahedron_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/icosahedron_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // detail - var detailRow = new UI.Row(); - var detail = new UI.Integer( parameters.detail ).setRange( 0, Infinity ).onChange( update ); + var detailRow = new UIRow(); + var detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update ); - detailRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/icosahedron_geometry/detail' ) ).setWidth( '90px' ) ); + detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/icosahedron_geometry/detail' ) ).setWidth( '90px' ) ); detailRow.add( detail ); container.add( detailRow ); - // function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.IcosahedronBufferGeometry( radius.getValue(), detail.getValue() ) ) ); @@ -51,4 +56,4 @@ Sidebar.Geometry.IcosahedronGeometry = function ( editor, object ) { }; -Sidebar.Geometry.IcosahedronBufferGeometry = Sidebar.Geometry.IcosahedronGeometry; +export { SidebarGeometryIcosahedronGeometry }; diff --git a/editor/js/Sidebar.Geometry.LatheGeometry.js b/editor/js/Sidebar.Geometry.LatheGeometry.js index 93dbde8e9a026c..c0e97e98fc927d 100644 --- a/editor/js/Sidebar.Geometry.LatheGeometry.js +++ b/editor/js/Sidebar.Geometry.LatheGeometry.js @@ -2,60 +2,65 @@ * @author rfm1201 */ -Sidebar.Geometry.LatheGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; +import { UIPoints2 } from './libs/ui.three.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryLatheGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // segments - var segmentsRow = new UI.Row(); - var segments = new UI.Integer( parameters.segments ).onChange( update ); + var segmentsRow = new UIRow(); + var segments = new UIInteger( parameters.segments ).onChange( update ); - segmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/lathe_geometry/segments' ) ).setWidth( '90px' ) ); + segmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/segments' ) ).setWidth( '90px' ) ); segmentsRow.add( segments ); container.add( segmentsRow ); // phiStart - var phiStartRow = new UI.Row(); - var phiStart = new UI.Number( parameters.phiStart * 180 / Math.PI ).onChange( update ); + var phiStartRow = new UIRow(); + var phiStart = new UINumber( parameters.phiStart * 180 / Math.PI ).onChange( update ); - phiStartRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/lathe_geometry/phistart' ) ).setWidth( '90px' ) ); + phiStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/phistart' ) ).setWidth( '90px' ) ); phiStartRow.add( phiStart ); container.add( phiStartRow ); // phiLength - var phiLengthRow = new UI.Row(); - var phiLength = new UI.Number( parameters.phiLength * 180 / Math.PI ).onChange( update ); + var phiLengthRow = new UIRow(); + var phiLength = new UINumber( parameters.phiLength * 180 / Math.PI ).onChange( update ); - phiLengthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/lathe_geometry/philength' ) ).setWidth( '90px' ) ); + phiLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/philength' ) ).setWidth( '90px' ) ); phiLengthRow.add( phiLength ); container.add( phiLengthRow ); // points - var pointsRow = new UI.Row(); - pointsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/lathe_geometry/points' ) ).setWidth( '90px' ) ); + var pointsRow = new UIRow(); + pointsRow.add( new UIText( strings.getKey( 'sidebar/geometry/lathe_geometry/points' ) ).setWidth( '90px' ) ); - var points = new UI.Points2().setValue( parameters.points ).onChange( update ); + var points = new UIPoints2().setValue( parameters.points ).onChange( update ); pointsRow.add( points ); container.add( pointsRow ); function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.LatheBufferGeometry( points.getValue(), segments.getValue(), phiStart.getValue() / 180 * Math.PI, @@ -68,4 +73,4 @@ Sidebar.Geometry.LatheGeometry = function ( editor, object ) { }; -Sidebar.Geometry.LatheBufferGeometry = Sidebar.Geometry.LatheGeometry; +export { SidebarGeometryLatheGeometry }; diff --git a/editor/js/Sidebar.Geometry.Modifiers.js b/editor/js/Sidebar.Geometry.Modifiers.js index 141e2316ac2cda..b56fa3ddedb927 100644 --- a/editor/js/Sidebar.Geometry.Modifiers.js +++ b/editor/js/Sidebar.Geometry.Modifiers.js @@ -2,17 +2,19 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.Modifiers = function ( editor, object ) { +import { UIRow, UIButton } from './libs/ui.js'; + +var SidebarGeometryModifiers = function ( editor, object ) { var signals = editor.signals; - var container = new UI.Row().setPaddingLeft( '90px' ); + var container = new UIRow().setPaddingLeft( '90px' ); var geometry = object.geometry; // Compute Vertex Normals - var button = new UI.Button( 'Compute Vertex Normals' ); + var button = new UIButton( 'Compute Vertex Normals' ); button.onClick( function () { geometry.computeVertexNormals(); @@ -38,3 +40,5 @@ Sidebar.Geometry.Modifiers = function ( editor, object ) { return container; }; + +export { SidebarGeometryModifiers }; diff --git a/editor/js/Sidebar.Geometry.OctahedronGeometry.js b/editor/js/Sidebar.Geometry.OctahedronGeometry.js index 16d99f805dae20..d4b44007c71630 100644 --- a/editor/js/Sidebar.Geometry.OctahedronGeometry.js +++ b/editor/js/Sidebar.Geometry.OctahedronGeometry.js @@ -2,33 +2,39 @@ * @author Temdog007 / http://github.com/Temdog007 */ -Sidebar.Geometry.OctahedronGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; + +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; + +var SidebarGeometryOctahedronGeometry = function ( editor, object ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/octahedron_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/octahedron_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // detail - var detailRow = new UI.Row(); - var detail = new UI.Integer( parameters.detail ).setRange( 0, Infinity ).onChange( update ); + var detailRow = new UIRow(); + var detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update ); - detailRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/octahedron_geometry/detail' ) ).setWidth( '90px' ) ); + detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/octahedron_geometry/detail' ) ).setWidth( '90px' ) ); detailRow.add( detail ); container.add( detailRow ); @@ -38,7 +44,7 @@ Sidebar.Geometry.OctahedronGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.OctahedronBufferGeometry( radius.getValue(), detail.getValue() ) ) ); @@ -51,4 +57,4 @@ Sidebar.Geometry.OctahedronGeometry = function ( editor, object ) { }; -Sidebar.Geometry.OctahedronBufferGeometry = Sidebar.Geometry.OctahedronGeometry; +export { SidebarGeometryOctahedronGeometry }; diff --git a/editor/js/Sidebar.Geometry.PlaneGeometry.js b/editor/js/Sidebar.Geometry.PlaneGeometry.js index 0afbd984a59db0..657f20d0bf4b98 100644 --- a/editor/js/Sidebar.Geometry.PlaneGeometry.js +++ b/editor/js/Sidebar.Geometry.PlaneGeometry.js @@ -2,53 +2,57 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.PlaneGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryPlaneGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // width - var widthRow = new UI.Row(); - var width = new UI.Number( parameters.width ).onChange( update ); + var widthRow = new UIRow(); + var width = new UINumber( parameters.width ).onChange( update ); - widthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/plane_geometry/width' ) ).setWidth( '90px' ) ); + widthRow.add( new UIText( strings.getKey( 'sidebar/geometry/plane_geometry/width' ) ).setWidth( '90px' ) ); widthRow.add( width ); container.add( widthRow ); // height - var heightRow = new UI.Row(); - var height = new UI.Number( parameters.height ).onChange( update ); + var heightRow = new UIRow(); + var height = new UINumber( parameters.height ).onChange( update ); - heightRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/plane_geometry/height' ) ).setWidth( '90px' ) ); + heightRow.add( new UIText( strings.getKey( 'sidebar/geometry/plane_geometry/height' ) ).setWidth( '90px' ) ); heightRow.add( height ); container.add( heightRow ); // widthSegments - var widthSegmentsRow = new UI.Row(); - var widthSegments = new UI.Integer( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update ); + var widthSegmentsRow = new UIRow(); + var widthSegments = new UIInteger( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update ); - widthSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/plane_geometry/widthsegments' ) ).setWidth( '90px' ) ); + widthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/plane_geometry/widthsegments' ) ).setWidth( '90px' ) ); widthSegmentsRow.add( widthSegments ); container.add( widthSegmentsRow ); // heightSegments - var heightSegmentsRow = new UI.Row(); - var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); + var heightSegmentsRow = new UIRow(); + var heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); - heightSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/plane_geometry/heightsegments' ) ).setWidth( '90px' ) ); + heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/plane_geometry/heightsegments' ) ).setWidth( '90px' ) ); heightSegmentsRow.add( heightSegments ); container.add( heightSegmentsRow ); @@ -58,7 +62,7 @@ Sidebar.Geometry.PlaneGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.PlaneBufferGeometry( width.getValue(), height.getValue(), widthSegments.getValue(), @@ -71,4 +75,4 @@ Sidebar.Geometry.PlaneGeometry = function ( editor, object ) { }; -Sidebar.Geometry.PlaneBufferGeometry = Sidebar.Geometry.PlaneGeometry; +export { SidebarGeometryPlaneGeometry }; diff --git a/editor/js/Sidebar.Geometry.RingGeometry.js b/editor/js/Sidebar.Geometry.RingGeometry.js index f455a9b4ab548b..680b31f6319989 100644 --- a/editor/js/Sidebar.Geometry.RingGeometry.js +++ b/editor/js/Sidebar.Geometry.RingGeometry.js @@ -2,73 +2,77 @@ * @author Temdog007 / http://github.com/Temdog007 */ -Sidebar.Geometry.RingGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryRingGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // innerRadius - var innerRadiusRow = new UI.Row(); - var innerRadius = new UI.Number( parameters.innerRadius ).onChange( update ); + var innerRadiusRow = new UIRow(); + var innerRadius = new UINumber( parameters.innerRadius ).onChange( update ); - innerRadiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/ring_geometry/innerRadius' ) ).setWidth( '90px' ) ); + innerRadiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/ring_geometry/innerRadius' ) ).setWidth( '90px' ) ); innerRadiusRow.add( innerRadius ); container.add( innerRadiusRow ); // outerRadius - var outerRadiusRow = new UI.Row(); - var outerRadius = new UI.Number( parameters.outerRadius ).onChange( update ); + var outerRadiusRow = new UIRow(); + var outerRadius = new UINumber( parameters.outerRadius ).onChange( update ); - outerRadiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/ring_geometry/outerRadius' ) ).setWidth( '90px' ) ); + outerRadiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/ring_geometry/outerRadius' ) ).setWidth( '90px' ) ); outerRadiusRow.add( outerRadius ); container.add( outerRadiusRow ); // thetaSegments - var thetaSegmentsRow = new UI.Row(); - var thetaSegments = new UI.Integer( parameters.thetaSegments ).setRange( 3, Infinity ).onChange( update ); + var thetaSegmentsRow = new UIRow(); + var thetaSegments = new UIInteger( parameters.thetaSegments ).setRange( 3, Infinity ).onChange( update ); - thetaSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/ring_geometry/thetaSegments' ) ).setWidth( '90px' ) ); + thetaSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/ring_geometry/thetaSegments' ) ).setWidth( '90px' ) ); thetaSegmentsRow.add( thetaSegments ); container.add( thetaSegmentsRow ); // phiSegments - var phiSegmentsRow = new UI.Row(); - var phiSegments = new UI.Integer( parameters.phiSegments ).setRange( 3, Infinity ).onChange( update ); + var phiSegmentsRow = new UIRow(); + var phiSegments = new UIInteger( parameters.phiSegments ).setRange( 3, Infinity ).onChange( update ); - phiSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/ring_geometry/phiSegments' ) ).setWidth( '90px' ) ); + phiSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/ring_geometry/phiSegments' ) ).setWidth( '90px' ) ); phiSegmentsRow.add( phiSegments ); container.add( phiSegmentsRow ); // thetaStart - var thetaStartRow = new UI.Row(); - var thetaStart = new UI.Number( parameters.thetaStart * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var thetaStartRow = new UIRow(); + var thetaStart = new UINumber( parameters.thetaStart * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - thetaStartRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/ring_geometry/thetastart' ) ).setWidth( '90px' ) ); + thetaStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/ring_geometry/thetastart' ) ).setWidth( '90px' ) ); thetaStartRow.add( thetaStart ); container.add( thetaStartRow ); // thetaLength - var thetaLengthRow = new UI.Row(); - var thetaLength = new UI.Number( parameters.thetaLength * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var thetaLengthRow = new UIRow(); + var thetaLength = new UINumber( parameters.thetaLength * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - thetaLengthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/ring_geometry/thetalength' ) ).setWidth( '90px' ) ); + thetaLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/ring_geometry/thetalength' ) ).setWidth( '90px' ) ); thetaLengthRow.add( thetaLength ); container.add( thetaLengthRow ); @@ -77,13 +81,13 @@ Sidebar.Geometry.RingGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.RingBufferGeometry( innerRadius.getValue(), outerRadius.getValue(), thetaSegments.getValue(), phiSegments.getValue(), - thetaStart.getValue() * THREE.Math.DEG2RAD, - thetaLength.getValue() * THREE.Math.DEG2RAD + thetaStart.getValue() * THREE.MathUtils.DEG2RAD, + thetaLength.getValue() * THREE.MathUtils.DEG2RAD ) ) ); } @@ -92,4 +96,4 @@ Sidebar.Geometry.RingGeometry = function ( editor, object ) { }; -Sidebar.Geometry.RingBufferGeometry = Sidebar.Geometry.RingGeometry; +export { SidebarGeometryRingGeometry }; diff --git a/editor/js/Sidebar.Geometry.ShapeGeometry.js b/editor/js/Sidebar.Geometry.ShapeGeometry.js index 7c287bbca292dd..23e570d8676303 100644 --- a/editor/js/Sidebar.Geometry.ShapeGeometry.js +++ b/editor/js/Sidebar.Geometry.ShapeGeometry.js @@ -2,36 +2,40 @@ * @author Temdog007 / http://github.com/Temdog007 */ -Sidebar.Geometry.ShapeGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UIButton } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryShapeGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // curveSegments - var curveSegmentsRow = new UI.Row(); - var curveSegments = new UI.Integer( parameters.curveSegments || 12 ).onChange( changeShape ).setRange( 1, Infinity ); + var curveSegmentsRow = new UIRow(); + var curveSegments = new UIInteger( parameters.curveSegments || 12 ).onChange( changeShape ).setRange( 1, Infinity ); - curveSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/shape_geometry/curveSegments' ) ).setWidth( '90px' ) ); + curveSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/shape_geometry/curveSegments' ) ).setWidth( '90px' ) ); curveSegmentsRow.add( curveSegments ); container.add( curveSegmentsRow ); // to extrude - var button = new UI.Button( strings.getKey( 'sidebar/geometry/shape_geometry/extrude' ) ).onClick( toExtrude ).setWidth( '90px' ).setMarginLeft( '90px' ); + var button = new UIButton( strings.getKey( 'sidebar/geometry/shape_geometry/extrude' ) ).onClick( toExtrude ).setWidth( '90px' ).setMarginLeft( '90px' ); container.add( button ); // function changeShape() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.ShapeBufferGeometry( parameters.shapes, curveSegments.getValue() ) ) ); @@ -52,4 +56,4 @@ Sidebar.Geometry.ShapeGeometry = function ( editor, object ) { }; -Sidebar.Geometry.ShapeBufferGeometry = Sidebar.Geometry.ShapeGeometry; +export { SidebarGeometryShapeGeometry }; diff --git a/editor/js/Sidebar.Geometry.SphereGeometry.js b/editor/js/Sidebar.Geometry.SphereGeometry.js index 4baa21cf967cdf..d202af6cfce1d3 100644 --- a/editor/js/Sidebar.Geometry.SphereGeometry.js +++ b/editor/js/Sidebar.Geometry.SphereGeometry.js @@ -2,83 +2,87 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.SphereGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometrySphereGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/sphere_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/sphere_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // widthSegments - var widthSegmentsRow = new UI.Row(); - var widthSegments = new UI.Integer( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update ); + var widthSegmentsRow = new UIRow(); + var widthSegments = new UIInteger( parameters.widthSegments ).setRange( 1, Infinity ).onChange( update ); - widthSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/sphere_geometry/widthsegments' ) ).setWidth( '90px' ) ); + widthSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/sphere_geometry/widthsegments' ) ).setWidth( '90px' ) ); widthSegmentsRow.add( widthSegments ); container.add( widthSegmentsRow ); // heightSegments - var heightSegmentsRow = new UI.Row(); - var heightSegments = new UI.Integer( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); + var heightSegmentsRow = new UIRow(); + var heightSegments = new UIInteger( parameters.heightSegments ).setRange( 1, Infinity ).onChange( update ); - heightSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/sphere_geometry/heightsegments' ) ).setWidth( '90px' ) ); + heightSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/sphere_geometry/heightsegments' ) ).setWidth( '90px' ) ); heightSegmentsRow.add( heightSegments ); container.add( heightSegmentsRow ); // phiStart - var phiStartRow = new UI.Row(); - var phiStart = new UI.Number( parameters.phiStart * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var phiStartRow = new UIRow(); + var phiStart = new UINumber( parameters.phiStart * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - phiStartRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/sphere_geometry/phistart' ) ).setWidth( '90px' ) ); + phiStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/sphere_geometry/phistart' ) ).setWidth( '90px' ) ); phiStartRow.add( phiStart ); container.add( phiStartRow ); // phiLength - var phiLengthRow = new UI.Row(); - var phiLength = new UI.Number( parameters.phiLength * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var phiLengthRow = new UIRow(); + var phiLength = new UINumber( parameters.phiLength * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - phiLengthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/sphere_geometry/philength' ) ).setWidth( '90px' ) ); + phiLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/sphere_geometry/philength' ) ).setWidth( '90px' ) ); phiLengthRow.add( phiLength ); container.add( phiLengthRow ); // thetaStart - var thetaStartRow = new UI.Row(); - var thetaStart = new UI.Number( parameters.thetaStart * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var thetaStartRow = new UIRow(); + var thetaStart = new UINumber( parameters.thetaStart * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - thetaStartRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/sphere_geometry/thetastart' ) ).setWidth( '90px' ) ); + thetaStartRow.add( new UIText( strings.getKey( 'sidebar/geometry/sphere_geometry/thetastart' ) ).setWidth( '90px' ) ); thetaStartRow.add( thetaStart ); container.add( thetaStartRow ); // thetaLength - var thetaLengthRow = new UI.Row(); - var thetaLength = new UI.Number( parameters.thetaLength * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var thetaLengthRow = new UIRow(); + var thetaLength = new UINumber( parameters.thetaLength * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - thetaLengthRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/sphere_geometry/thetalength' ) ).setWidth( '90px' ) ); + thetaLengthRow.add( new UIText( strings.getKey( 'sidebar/geometry/sphere_geometry/thetalength' ) ).setWidth( '90px' ) ); thetaLengthRow.add( thetaLength ); container.add( thetaLengthRow ); @@ -88,14 +92,14 @@ Sidebar.Geometry.SphereGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.SphereBufferGeometry( radius.getValue(), widthSegments.getValue(), heightSegments.getValue(), - phiStart.getValue() * THREE.Math.DEG2RAD, - phiLength.getValue() * THREE.Math.DEG2RAD, - thetaStart.getValue() * THREE.Math.DEG2RAD, - thetaLength.getValue() * THREE.Math.DEG2RAD + phiStart.getValue() * THREE.MathUtils.DEG2RAD, + phiLength.getValue() * THREE.MathUtils.DEG2RAD, + thetaStart.getValue() * THREE.MathUtils.DEG2RAD, + thetaLength.getValue() * THREE.MathUtils.DEG2RAD ) ) ); } @@ -104,4 +108,4 @@ Sidebar.Geometry.SphereGeometry = function ( editor, object ) { }; -Sidebar.Geometry.SphereBufferGeometry = Sidebar.Geometry.SphereGeometry; +export { SidebarGeometrySphereGeometry }; diff --git a/editor/js/Sidebar.Geometry.TeapotBufferGeometry.js b/editor/js/Sidebar.Geometry.TeapotBufferGeometry.js index 1e2cf8a6c8e66a..95698778d76010 100644 --- a/editor/js/Sidebar.Geometry.TeapotBufferGeometry.js +++ b/editor/js/Sidebar.Geometry.TeapotBufferGeometry.js @@ -2,78 +2,82 @@ * @author tschw */ -Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) { +import { UIRow, UIText, UIInteger, UICheckbox, UINumber } from './libs/ui.js'; - var container = new UI.Row(); +import { TeapotBufferGeometry } from '../../examples/jsm/geometries/TeapotBufferGeometry.js'; + +var SidebarGeometryTeapotBufferGeometry = function ( signals, object ) { + + var container = new UIRow(); var parameters = object.geometry.parameters; // size - var sizeRow = new UI.Row(); - var size = new UI.Number( parameters.size ).onChange( update ); + var sizeRow = new UIRow(); + var size = new UINumber( parameters.size ).onChange( update ); - sizeRow.add( new UI.Text( 'Size' ).setWidth( '90px' ) ); + sizeRow.add( new UIText( 'Size' ).setWidth( '90px' ) ); sizeRow.add( size ); container.add( sizeRow ); // segments - var segmentsRow = new UI.Row(); - var segments = new UI.Integer( parameters.segments ).setRange( 1, Infinity ).onChange( update ); + var segmentsRow = new UIRow(); + var segments = new UIInteger( parameters.segments ).setRange( 1, Infinity ).onChange( update ); - segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) ); + segmentsRow.add( new UIText( 'Segments' ).setWidth( '90px' ) ); segmentsRow.add( segments ); container.add( segmentsRow ); // bottom - var bottomRow = new UI.Row(); - var bottom = new UI.Checkbox( parameters.bottom ).onChange( update ); + var bottomRow = new UIRow(); + var bottom = new UICheckbox( parameters.bottom ).onChange( update ); - bottomRow.add( new UI.Text( 'Bottom' ).setWidth( '90px' ) ); + bottomRow.add( new UIText( 'Bottom' ).setWidth( '90px' ) ); bottomRow.add( bottom ); container.add( bottomRow ); // lid - var lidRow = new UI.Row(); - var lid = new UI.Checkbox( parameters.lid ).onChange( update ); + var lidRow = new UIRow(); + var lid = new UICheckbox( parameters.lid ).onChange( update ); - lidRow.add( new UI.Text( 'Lid' ).setWidth( '90px' ) ); + lidRow.add( new UIText( 'Lid' ).setWidth( '90px' ) ); lidRow.add( lid ); container.add( lidRow ); // body - var bodyRow = new UI.Row(); - var body = new UI.Checkbox( parameters.body ).onChange( update ); + var bodyRow = new UIRow(); + var body = new UICheckbox( parameters.body ).onChange( update ); - bodyRow.add( new UI.Text( 'Body' ).setWidth( '90px' ) ); + bodyRow.add( new UIText( 'Body' ).setWidth( '90px' ) ); bodyRow.add( body ); container.add( bodyRow ); // fitted lid - var fitLidRow = new UI.Row(); - var fitLid = new UI.Checkbox( parameters.fitLid ).onChange( update ); + var fitLidRow = new UIRow(); + var fitLid = new UICheckbox( parameters.fitLid ).onChange( update ); - fitLidRow.add( new UI.Text( 'Fitted Lid' ).setWidth( '90px' ) ); + fitLidRow.add( new UIText( 'Fitted Lid' ).setWidth( '90px' ) ); fitLidRow.add( fitLid ); container.add( fitLidRow ); // blinn-sized - var blinnRow = new UI.Row(); - var blinn = new UI.Checkbox( parameters.blinn ).onChange( update ); + var blinnRow = new UIRow(); + var blinn = new UICheckbox( parameters.blinn ).onChange( update ); - blinnRow.add( new UI.Text( 'Blinn-scaled' ).setWidth( '90px' ) ); + blinnRow.add( new UIText( 'Blinn-scaled' ).setWidth( '90px' ) ); blinnRow.add( blinn ); container.add( blinnRow ); @@ -82,7 +86,7 @@ Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) { object.geometry.dispose(); - object.geometry = new THREE.TeapotBufferGeometry( + object.geometry = new TeapotBufferGeometry( size.getValue(), segments.getValue(), bottom.getValue(), @@ -101,3 +105,5 @@ Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) { return container; }; + +export { SidebarGeometryTeapotBufferGeometry }; diff --git a/editor/js/Sidebar.Geometry.TetrahedronGeometry.js b/editor/js/Sidebar.Geometry.TetrahedronGeometry.js index 51423a79cd9674..112b76a8b2e4ed 100644 --- a/editor/js/Sidebar.Geometry.TetrahedronGeometry.js +++ b/editor/js/Sidebar.Geometry.TetrahedronGeometry.js @@ -2,34 +2,39 @@ * @author Temdog007 / http://github.com/Temdog007 */ +import * as THREE from '../../build/three.module.js'; -Sidebar.Geometry.TetrahedronGeometry = function ( editor, object ) { +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; + +var SidebarGeometryTetrahedronGeometry = function ( editor, object ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tetrahedron_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/tetrahedron_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // detail - var detailRow = new UI.Row(); - var detail = new UI.Integer( parameters.detail ).setRange( 0, Infinity ).onChange( update ); + var detailRow = new UIRow(); + var detail = new UIInteger( parameters.detail ).setRange( 0, Infinity ).onChange( update ); - detailRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tetrahedron_geometry/detail' ) ).setWidth( '90px' ) ); + detailRow.add( new UIText( strings.getKey( 'sidebar/geometry/tetrahedron_geometry/detail' ) ).setWidth( '90px' ) ); detailRow.add( detail ); container.add( detailRow ); @@ -39,7 +44,7 @@ Sidebar.Geometry.TetrahedronGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.TetrahedronBufferGeometry( radius.getValue(), detail.getValue() ) ) ); @@ -52,4 +57,4 @@ Sidebar.Geometry.TetrahedronGeometry = function ( editor, object ) { }; -Sidebar.Geometry.TetrahedronBufferGeometry = Sidebar.Geometry.TetrahedronGeometry; +export { SidebarGeometryTetrahedronGeometry }; diff --git a/editor/js/Sidebar.Geometry.TorusGeometry.js b/editor/js/Sidebar.Geometry.TorusGeometry.js index ff196cefd10a84..dc311e42889237 100644 --- a/editor/js/Sidebar.Geometry.TorusGeometry.js +++ b/editor/js/Sidebar.Geometry.TorusGeometry.js @@ -2,63 +2,67 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.TorusGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryTorusGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torus_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/torus_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // tube - var tubeRow = new UI.Row(); - var tube = new UI.Number( parameters.tube ).onChange( update ); + var tubeRow = new UIRow(); + var tube = new UINumber( parameters.tube ).onChange( update ); - tubeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torus_geometry/tube' ) ).setWidth( '90px' ) ); + tubeRow.add( new UIText( strings.getKey( 'sidebar/geometry/torus_geometry/tube' ) ).setWidth( '90px' ) ); tubeRow.add( tube ); container.add( tubeRow ); // radialSegments - var radialSegmentsRow = new UI.Row(); - var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update ); + var radialSegmentsRow = new UIRow(); + var radialSegments = new UIInteger( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update ); - radialSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torus_geometry/radialsegments' ) ).setWidth( '90px' ) ); + radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/torus_geometry/radialsegments' ) ).setWidth( '90px' ) ); radialSegmentsRow.add( radialSegments ); container.add( radialSegmentsRow ); // tubularSegments - var tubularSegmentsRow = new UI.Row(); - var tubularSegments = new UI.Integer( parameters.tubularSegments ).setRange( 1, Infinity ).onChange( update ); + var tubularSegmentsRow = new UIRow(); + var tubularSegments = new UIInteger( parameters.tubularSegments ).setRange( 1, Infinity ).onChange( update ); - tubularSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torus_geometry/tubularsegments' ) ).setWidth( '90px' ) ); + tubularSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/torus_geometry/tubularsegments' ) ).setWidth( '90px' ) ); tubularSegmentsRow.add( tubularSegments ); container.add( tubularSegmentsRow ); // arc - var arcRow = new UI.Row(); - var arc = new UI.Number( parameters.arc * THREE.Math.RAD2DEG ).setStep( 10 ).onChange( update ); + var arcRow = new UIRow(); + var arc = new UINumber( parameters.arc * THREE.MathUtils.RAD2DEG ).setStep( 10 ).onChange( update ); - arcRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torus_geometry/arc' ) ).setWidth( '90px' ) ); + arcRow.add( new UIText( strings.getKey( 'sidebar/geometry/torus_geometry/arc' ) ).setWidth( '90px' ) ); arcRow.add( arc ); container.add( arcRow ); @@ -68,12 +72,12 @@ Sidebar.Geometry.TorusGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.TorusBufferGeometry( radius.getValue(), tube.getValue(), radialSegments.getValue(), tubularSegments.getValue(), - arc.getValue() * THREE.Math.DEG2RAD + arc.getValue() * THREE.MathUtils.DEG2RAD ) ) ); } @@ -82,4 +86,4 @@ Sidebar.Geometry.TorusGeometry = function ( editor, object ) { }; -Sidebar.Geometry.TorusBufferGeometry = Sidebar.Geometry.TorusGeometry; +export { SidebarGeometryTorusGeometry }; diff --git a/editor/js/Sidebar.Geometry.TorusKnotGeometry.js b/editor/js/Sidebar.Geometry.TorusKnotGeometry.js index dfdaf2aa9af1cc..7fa14fd1e1dc6c 100644 --- a/editor/js/Sidebar.Geometry.TorusKnotGeometry.js +++ b/editor/js/Sidebar.Geometry.TorusKnotGeometry.js @@ -2,73 +2,77 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UINumber } from './libs/ui.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryTorusKnotGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torusKnot_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/torusKnot_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // tube - var tubeRow = new UI.Row(); - var tube = new UI.Number( parameters.tube ).onChange( update ); + var tubeRow = new UIRow(); + var tube = new UINumber( parameters.tube ).onChange( update ); - tubeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torusKnot_geometry/tube' ) ).setWidth( '90px' ) ); + tubeRow.add( new UIText( strings.getKey( 'sidebar/geometry/torusKnot_geometry/tube' ) ).setWidth( '90px' ) ); tubeRow.add( tube ); container.add( tubeRow ); // tubularSegments - var tubularSegmentsRow = new UI.Row(); - var tubularSegments = new UI.Integer( parameters.tubularSegments ).setRange( 1, Infinity ).onChange( update ); + var tubularSegmentsRow = new UIRow(); + var tubularSegments = new UIInteger( parameters.tubularSegments ).setRange( 1, Infinity ).onChange( update ); - tubularSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torusKnot_geometry/tubularsegments' ) ).setWidth( '90px' ) ); + tubularSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/torusKnot_geometry/tubularsegments' ) ).setWidth( '90px' ) ); tubularSegmentsRow.add( tubularSegments ); container.add( tubularSegmentsRow ); // radialSegments - var radialSegmentsRow = new UI.Row(); - var radialSegments = new UI.Integer( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update ); + var radialSegmentsRow = new UIRow(); + var radialSegments = new UIInteger( parameters.radialSegments ).setRange( 1, Infinity ).onChange( update ); - radialSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torusKnot_geometry/radialsegments' ) ).setWidth( '90px' ) ); + radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/torusKnot_geometry/radialsegments' ) ).setWidth( '90px' ) ); radialSegmentsRow.add( radialSegments ); container.add( radialSegmentsRow ); // p - var pRow = new UI.Row(); - var p = new UI.Number( parameters.p ).onChange( update ); + var pRow = new UIRow(); + var p = new UINumber( parameters.p ).onChange( update ); - pRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torusKnot_geometry/p' ) ).setWidth( '90px' ) ); + pRow.add( new UIText( strings.getKey( 'sidebar/geometry/torusKnot_geometry/p' ) ).setWidth( '90px' ) ); pRow.add( p ); container.add( pRow ); // q - var qRow = new UI.Row(); - var q = new UI.Number( parameters.q ).onChange( update ); + var qRow = new UIRow(); + var q = new UINumber( parameters.q ).onChange( update ); - qRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/torusKnot_geometry/q' ) ).setWidth( '90px' ) ); + qRow.add( new UIText( strings.getKey( 'sidebar/geometry/torusKnot_geometry/q' ) ).setWidth( '90px' ) ); qRow.add( q ); container.add( qRow ); @@ -78,7 +82,7 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) { function update() { - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.TorusKnotBufferGeometry( radius.getValue(), tube.getValue(), tubularSegments.getValue(), @@ -93,4 +97,4 @@ Sidebar.Geometry.TorusKnotGeometry = function ( editor, object ) { }; -Sidebar.Geometry.TorusKnotBufferGeometry = Sidebar.Geometry.TorusKnotGeometry; +export { SidebarGeometryTorusKnotGeometry }; diff --git a/editor/js/Sidebar.Geometry.TubeGeometry.js b/editor/js/Sidebar.Geometry.TubeGeometry.js index 24405fa7ddcfa2..e06676cae966dc 100644 --- a/editor/js/Sidebar.Geometry.TubeGeometry.js +++ b/editor/js/Sidebar.Geometry.TubeGeometry.js @@ -2,82 +2,87 @@ * @author Temdog007 / http://github.com/Temdog007 */ -Sidebar.Geometry.TubeGeometry = function ( editor, object ) { +import * as THREE from '../../build/three.module.js'; - var strings = editor.strings; +import { UIRow, UIText, UIInteger, UISelect, UICheckbox, UINumber } from './libs/ui.js'; +import { UIPoints3 } from './libs/ui.three.js'; + +import { SetGeometryCommand } from './commands/SetGeometryCommand.js'; - var signals = editor.signals; +var SidebarGeometryTubeGeometry = function ( editor, object ) { + + var strings = editor.strings; - var container = new UI.Row(); + var container = new UIRow(); var geometry = object.geometry; var parameters = geometry.parameters; // points - var pointsRow = new UI.Row(); - pointsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/path' ) ).setWidth( '90px' ) ); + var pointsRow = new UIRow(); + pointsRow.add( new UIText( strings.getKey( 'sidebar/geometry/tube_geometry/path' ) ).setWidth( '90px' ) ); - var points = new UI.Points3().setValue( parameters.path.points ).onChange( update ); + var points = new UIPoints3().setValue( parameters.path.points ).onChange( update ); pointsRow.add( points ); container.add( pointsRow ); // radius - var radiusRow = new UI.Row(); - var radius = new UI.Number( parameters.radius ).onChange( update ); + var radiusRow = new UIRow(); + var radius = new UINumber( parameters.radius ).onChange( update ); - radiusRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/radius' ) ).setWidth( '90px' ) ); + radiusRow.add( new UIText( strings.getKey( 'sidebar/geometry/tube_geometry/radius' ) ).setWidth( '90px' ) ); radiusRow.add( radius ); container.add( radiusRow ); // tubularSegments - var tubularSegmentsRow = new UI.Row(); - var tubularSegments = new UI.Integer( parameters.tubularSegments ).onChange( update ); + var tubularSegmentsRow = new UIRow(); + var tubularSegments = new UIInteger( parameters.tubularSegments ).onChange( update ); - tubularSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/tubularsegments' ) ).setWidth( '90px' ) ); + tubularSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/tube_geometry/tubularsegments' ) ).setWidth( '90px' ) ); tubularSegmentsRow.add( tubularSegments ); container.add( tubularSegmentsRow ); // radialSegments - var radialSegmentsRow = new UI.Row(); - var radialSegments = new UI.Integer( parameters.radialSegments ).onChange( update ); + var radialSegmentsRow = new UIRow(); + var radialSegments = new UIInteger( parameters.radialSegments ).onChange( update ); - radialSegmentsRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/radialsegments' ) ).setWidth( '90px' ) ); + radialSegmentsRow.add( new UIText( strings.getKey( 'sidebar/geometry/tube_geometry/radialsegments' ) ).setWidth( '90px' ) ); radialSegmentsRow.add( radialSegments ); container.add( radialSegmentsRow ); // closed - var closedRow = new UI.Row(); - var closed = new UI.Checkbox( parameters.closed ).onChange( update ); + var closedRow = new UIRow(); + var closed = new UICheckbox( parameters.closed ).onChange( update ); - closedRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/closed' ) ).setWidth( '90px' ) ); + closedRow.add( new UIText( strings.getKey( 'sidebar/geometry/tube_geometry/closed' ) ).setWidth( '90px' ) ); closedRow.add( closed ); container.add( closedRow ); // curveType - var curveTypeRow = new UI.Row(); - var curveType = new UI.Select().setOptions( { centripetal: 'centripetal', chordal: 'chordal', catmullrom: 'catmullrom' } ).setValue( parameters.path.curveType ).onChange( update ); + var curveTypeRow = new UIRow(); + var curveType = new UISelect().setOptions( { centripetal: 'centripetal', chordal: 'chordal', catmullrom: 'catmullrom' } ).setValue( parameters.path.curveType ).onChange( update ); - curveTypeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/curvetype' ) ).setWidth( '90px' ), curveType ); + curveTypeRow.add( new UIText( strings.getKey( 'sidebar/geometry/tube_geometry/curvetype' ) ).setWidth( '90px' ), curveType ); container.add( curveTypeRow ); // tension - var tensionRow = new UI.Row().setDisplay( curveType.getValue() == 'catmullrom' ? '' : 'none' ); - var tension = new UI.Number( parameters.path.tension ).setStep( 0.01 ).onChange( update ); + var tensionRow = new UIRow().setDisplay( curveType.getValue() == 'catmullrom' ? '' : 'none' ); + var tension = new UINumber( parameters.path.tension ).setStep( 0.01 ).onChange( update ); - tensionRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/tube_geometry/tension' ) ).setWidth( '90px' ), tension ); + tensionRow.add( new UIText( strings.getKey( 'sidebar/geometry/tube_geometry/tension' ) ).setWidth( '90px' ), tension ); container.add( tensionRow ); @@ -87,7 +92,7 @@ Sidebar.Geometry.TubeGeometry = function ( editor, object ) { tensionRow.setDisplay( curveType.getValue() == 'catmullrom' ? '' : 'none' ); - editor.execute( new SetGeometryCommand( editor, object, new THREE[ geometry.type ]( + editor.execute( new SetGeometryCommand( editor, object, new THREE.TubeBufferGeometry( new THREE.CatmullRomCurve3( points.getValue(), closed.getValue(), curveType.getValue(), tension.getValue() ), tubularSegments.getValue(), radius.getValue(), @@ -101,4 +106,4 @@ Sidebar.Geometry.TubeGeometry = function ( editor, object ) { }; -Sidebar.Geometry.TubeBufferGeometry = Sidebar.Geometry.TubeGeometry; +export { SidebarGeometryTubeGeometry }; diff --git a/editor/js/Sidebar.Geometry.js b/editor/js/Sidebar.Geometry.js index ee9ecfcb1df6fc..9b8aae5223a819 100644 --- a/editor/js/Sidebar.Geometry.js +++ b/editor/js/Sidebar.Geometry.js @@ -2,21 +2,71 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Geometry = function ( editor ) { +import * as THREE from '../../build/three.module.js'; + +import { UIPanel, UIRow, UIText, UIInput, UIButton, UISpan } from './libs/ui.js'; + +import { SetGeometryValueCommand } from './commands/SetGeometryValueCommand.js'; + +import { SidebarGeometryGeometry } from './Sidebar.Geometry.Geometry.js'; +import { SidebarGeometryBufferGeometry } from './Sidebar.Geometry.BufferGeometry.js'; +import { SidebarGeometryModifiers } from './Sidebar.Geometry.Modifiers.js'; + +import { SidebarGeometryBoxGeometry } from './Sidebar.Geometry.BoxGeometry.js'; +import { SidebarGeometryCircleGeometry } from './Sidebar.Geometry.CircleGeometry.js'; +import { SidebarGeometryCylinderGeometry } from './Sidebar.Geometry.CylinderGeometry.js'; +import { SidebarGeometryDodecahedronGeometry } from './Sidebar.Geometry.DodecahedronGeometry.js'; +import { SidebarGeometryExtrudeGeometry } from './Sidebar.Geometry.ExtrudeGeometry.js'; +import { SidebarGeometryIcosahedronGeometry } from './Sidebar.Geometry.IcosahedronGeometry.js'; +import { SidebarGeometryLatheGeometry } from './Sidebar.Geometry.LatheGeometry.js'; +import { SidebarGeometryOctahedronGeometry } from './Sidebar.Geometry.OctahedronGeometry.js'; +import { SidebarGeometryPlaneGeometry } from './Sidebar.Geometry.PlaneGeometry.js'; +import { SidebarGeometryRingGeometry } from './Sidebar.Geometry.RingGeometry.js'; +import { SidebarGeometryShapeGeometry } from './Sidebar.Geometry.ShapeGeometry.js'; +import { SidebarGeometrySphereGeometry } from './Sidebar.Geometry.SphereGeometry.js'; +import { SidebarGeometryTeapotBufferGeometry } from './Sidebar.Geometry.TeapotBufferGeometry.js'; +import { SidebarGeometryTetrahedronGeometry } from './Sidebar.Geometry.TetrahedronGeometry.js'; +import { SidebarGeometryTorusGeometry } from './Sidebar.Geometry.TorusGeometry.js'; +import { SidebarGeometryTorusKnotGeometry } from './Sidebar.Geometry.TorusKnotGeometry.js'; +import { SidebarGeometryTubeGeometry } from './Sidebar.Geometry.TubeGeometry.js'; + +var geometryUIClasses = { + 'BoxBufferGeometry': SidebarGeometryBoxGeometry, + 'CircleBufferGeometry': SidebarGeometryCircleGeometry, + 'CylinderBufferGeometry': SidebarGeometryCylinderGeometry, + 'DodecahedronBufferGeometry': SidebarGeometryDodecahedronGeometry, + 'ExtrudeBufferGeometry': SidebarGeometryExtrudeGeometry, + 'IcosahedronBufferGeometry': SidebarGeometryIcosahedronGeometry, + 'LatheBufferGeometry': SidebarGeometryLatheGeometry, + 'OctahedronBufferGeometry': SidebarGeometryOctahedronGeometry, + 'PlaneBufferGeometry': SidebarGeometryPlaneGeometry, + 'RingBufferGeometry': SidebarGeometryRingGeometry, + 'ShapeBufferGeometry': SidebarGeometryShapeGeometry, + 'SphereBufferGeometry': SidebarGeometrySphereGeometry, + 'TeapotBufferGeometry': SidebarGeometryTeapotBufferGeometry, + 'TetrahedronBufferGeometry': SidebarGeometryTetrahedronGeometry, + 'TorusBufferGeometry': SidebarGeometryTorusGeometry, + 'TorusKnotBufferGeometry': SidebarGeometryTorusKnotGeometry, + 'TubeBufferGeometry': SidebarGeometryTubeGeometry +}; + +var SidebarGeometry = function ( editor ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Panel(); + var container = new UIPanel(); container.setBorderTop( '0' ); container.setDisplay( 'none' ); container.setPaddingTop( '20px' ); + var currentGeometryType = null; + // Actions /* - var objectActions = new UI.Select().setPosition( 'absolute' ).setRight( '8px' ).setFontSize( '11px' ); + var objectActions = new UISelect().setPosition( 'absolute' ).setRight( '8px' ).setFontSize( '11px' ); objectActions.setOptions( { 'Actions': 'Actions', @@ -88,27 +138,27 @@ Sidebar.Geometry = function ( editor ) { // type - var geometryTypeRow = new UI.Row(); - var geometryType = new UI.Text(); + var geometryTypeRow = new UIRow(); + var geometryType = new UIText(); - geometryTypeRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/type' ) ).setWidth( '90px' ) ); + geometryTypeRow.add( new UIText( strings.getKey( 'sidebar/geometry/type' ) ).setWidth( '90px' ) ); geometryTypeRow.add( geometryType ); container.add( geometryTypeRow ); // uuid - var geometryUUIDRow = new UI.Row(); - var geometryUUID = new UI.Input().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true ); - var geometryUUIDRenew = new UI.Button( strings.getKey( 'sidebar/geometry/new' ) ).setMarginLeft( '7px' ).onClick( function () { + var geometryUUIDRow = new UIRow(); + var geometryUUID = new UIInput().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true ); + var geometryUUIDRenew = new UIButton( strings.getKey( 'sidebar/geometry/new' ) ).setMarginLeft( '7px' ).onClick( function () { - geometryUUID.setValue( THREE.Math.generateUUID() ); + geometryUUID.setValue( THREE.MathUtils.generateUUID() ); editor.execute( new SetGeometryValueCommand( editor, editor.selected, 'uuid', geometryUUID.getValue() ) ); } ); - geometryUUIDRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/uuid' ) ).setWidth( '90px' ) ); + geometryUUIDRow.add( new UIText( strings.getKey( 'sidebar/geometry/uuid' ) ).setWidth( '90px' ) ); geometryUUIDRow.add( geometryUUID ); geometryUUIDRow.add( geometryUUIDRenew ); @@ -116,36 +166,36 @@ Sidebar.Geometry = function ( editor ) { // name - var geometryNameRow = new UI.Row(); - var geometryName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { + var geometryNameRow = new UIRow(); + var geometryName = new UIInput().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { editor.execute( new SetGeometryValueCommand( editor, editor.selected, 'name', geometryName.getValue() ) ); } ); - geometryNameRow.add( new UI.Text( strings.getKey( 'sidebar/geometry/name' ) ).setWidth( '90px' ) ); + geometryNameRow.add( new UIText( strings.getKey( 'sidebar/geometry/name' ) ).setWidth( '90px' ) ); geometryNameRow.add( geometryName ); container.add( geometryNameRow ); // parameters - var parameters = new UI.Span(); + var parameters = new UISpan(); container.add( parameters ); // geometry - container.add( new Sidebar.Geometry.Geometry( editor ) ); + container.add( new SidebarGeometryGeometry( editor ) ); // buffergeometry - container.add( new Sidebar.Geometry.BufferGeometry( editor ) ); + container.add( new SidebarGeometryBufferGeometry( editor ) ); // size - var geometryBoundingSphere = new UI.Text(); + var geometryBoundingSphere = new UIText(); - container.add( new UI.Text( strings.getKey( 'sidebar/geometry/bounds' ) ).setWidth( '90px' ) ); + container.add( new UIText( strings.getKey( 'sidebar/geometry/bounds' ) ).setWidth( '90px' ) ); container.add( geometryBoundingSphere ); // @@ -167,15 +217,21 @@ Sidebar.Geometry = function ( editor ) { // - parameters.clear(); + if ( currentGeometryType !== geometry.type ) { + + parameters.clear(); - if ( geometry.type === 'BufferGeometry' || geometry.type === 'Geometry' ) { + if ( geometry.type === 'BufferGeometry' || geometry.type === 'Geometry' ) { - parameters.add( new Sidebar.Geometry.Modifiers( editor, object ) ); + parameters.add( new SidebarGeometryModifiers( editor, object ) ); - } else if ( Sidebar.Geometry[ geometry.type ] !== undefined ) { + } else if ( geometryUIClasses[ geometry.type ] !== undefined ) { + + parameters.add( new geometryUIClasses[ geometry.type ]( editor, object ) ); + + } - parameters.add( new Sidebar.Geometry[ geometry.type ]( editor, object ) ); + currentGeometryType = geometry.type; } @@ -191,9 +247,18 @@ Sidebar.Geometry = function ( editor ) { } - signals.objectSelected.add( build ); + signals.objectSelected.add( function () { + + currentGeometryType = null; + + build(); + + } ); + signals.geometryChanged.add( build ); return container; }; + +export { SidebarGeometry }; diff --git a/editor/js/Sidebar.History.js b/editor/js/Sidebar.History.js index c6b92adb02ed7a..779ac220cd3982 100644 --- a/editor/js/Sidebar.History.js +++ b/editor/js/Sidebar.History.js @@ -3,7 +3,10 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ -Sidebar.History = function ( editor ) { +import { UIPanel, UIBreak, UIText } from './libs/ui.js'; +import { UIBoolean, UIOutliner } from './libs/ui.three.js'; + +var SidebarHistory = function ( editor ) { var strings = editor.strings; @@ -13,13 +16,13 @@ Sidebar.History = function ( editor ) { var history = editor.history; - var container = new UI.Panel(); + var container = new UIPanel(); - container.add( new UI.Text( strings.getKey( 'sidebar/history/history' ) ) ); + container.add( new UIText( strings.getKey( 'sidebar/history' ).toUpperCase() ) ); // - var persistent = new UI.THREE.Boolean( config.getKey( 'settings/history' ), strings.getKey( 'sidebar/history/persistent' ) ); + var persistent = new UIBoolean( config.getKey( 'settings/history' ), strings.getKey( 'sidebar/history/persistent' ) ); persistent.setPosition( 'absolute' ).setRight( '8px' ); persistent.onChange( function () { @@ -44,11 +47,11 @@ Sidebar.History = function ( editor ) { } ); container.add( persistent ); - container.add( new UI.Break(), new UI.Break() ); + container.add( new UIBreak(), new UIBreak() ); var ignoreObjectSelectedSignal = false; - var outliner = new UI.Outliner( editor ); + var outliner = new UIOutliner( editor ); outliner.onChange( function () { ignoreObjectSelectedSignal = true; @@ -65,7 +68,6 @@ Sidebar.History = function ( editor ) { var refreshUI = function () { var options = []; - var enumerator = 1; function buildOption( object ) { @@ -92,7 +94,7 @@ Sidebar.History = function ( editor ) { } )( history.undos ); - ( function addObjects( objects, pad ) { + ( function addObjects( objects ) { for ( var i = objects.length - 1; i >= 0; i -- ) { @@ -106,7 +108,7 @@ Sidebar.History = function ( editor ) { } - } )( history.redos, ' ' ); + } )( history.redos ); outliner.setOptions( options ); @@ -121,6 +123,8 @@ Sidebar.History = function ( editor ) { signals.historyChanged.add( refreshUI ); signals.historyChanged.add( function ( cmd ) { + if ( ignoreObjectSelectedSignal === true ) return; + outliner.setValue( cmd !== undefined ? cmd.id : null ); } ); @@ -129,3 +133,5 @@ Sidebar.History = function ( editor ) { return container; }; + +export { SidebarHistory }; diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index 5bd92126594453..b3856fa4f73ce5 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -2,7 +2,36 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Material = function ( editor ) { +import * as THREE from '../../build/three.module.js'; + +import { UIPanel, UIRow, UIInput, UIButton, UIColor, UICheckbox, UISelect, UIText, UINumber } from './libs/ui.js'; +import { UITexture } from './libs/ui.three.js'; + +import { SetMaterialCommand } from './commands/SetMaterialCommand.js'; +import { SetMaterialColorCommand } from './commands/SetMaterialColorCommand.js'; +import { SetMaterialMapCommand } from './commands/SetMaterialMapCommand.js'; +import { SetMaterialValueCommand } from './commands/SetMaterialValueCommand.js'; +import { SetMaterialVectorCommand } from './commands/SetMaterialVectorCommand.js'; + +var materialClasses = { + 'LineBasicMaterial': THREE.LineBasicMaterial, + 'LineDashedMaterial': THREE.LineDashedMaterial, + 'MeshBasicMaterial': THREE.MeshBasicMaterial, + 'MeshDepthMaterial': THREE.MeshDepthMaterial, + 'MeshNormalMaterial': THREE.MeshNormalMaterial, + 'MeshLambertMaterial': THREE.MeshLambertMaterial, + 'MeshMatcapMaterial': THREE.MeshMatcapMaterial, + 'MeshPhongMaterial': THREE.MeshPhongMaterial, + 'MeshToonMaterial': THREE.MeshToonMaterial, + 'MeshStandardMaterial': THREE.MeshStandardMaterial, + 'MeshPhysicalMaterial': THREE.MeshPhysicalMaterial, + 'RawShaderMaterial': THREE.RawShaderMaterial, + 'ShaderMaterial': THREE.ShaderMaterial, + 'ShadowMaterial': THREE.ShadowMaterial, + 'SpriteMaterial': THREE.SpriteMaterial +}; + +var SidebarMaterial = function ( editor ) { var strings = editor.strings; @@ -12,70 +41,29 @@ Sidebar.Material = function ( editor ) { var currentMaterialSlot = 0; - var container = new UI.Panel(); + var epsilon = 0.01 - Number.EPSILON; + + var container = new UIPanel(); container.setBorderTop( '0' ); container.setDisplay( 'none' ); container.setPaddingTop( '20px' ); - // New / Copy / Paste - - var copiedMaterial; - - var managerRow = new UI.Row(); - // Current material slot - var materialSlotRow = new UI.Row(); + var materialSlotRow = new UIRow(); - materialSlotRow.add( new UI.Text( 'Slot' ).setWidth( '90px' ) ); + materialSlotRow.add( new UIText( 'Slot' ).setWidth( '90px' ) ); - var materialSlotSelect = new UI.Select().setWidth( '170px' ).setFontSize( '12px' ).onChange( update ); + var materialSlotSelect = new UISelect().setWidth( '170px' ).setFontSize( '12px' ).onChange( update ); materialSlotSelect.setOptions( { 0: '' } ).setValue( 0 ); materialSlotRow.add( materialSlotSelect ); container.add( materialSlotRow ); - managerRow.add( new UI.Text( '' ).setWidth( '90px' ) ); - - managerRow.add( new UI.Button( strings.getKey( 'sidebar/material/new' ) ).onClick( function () { - - var material = new THREE[ materialClass.getValue() ](); - editor.execute( new SetMaterialCommand( editor, currentObject, material, currentMaterialSlot ), 'New Material: ' + materialClass.getValue() ); - update(); - - } ) ); - - managerRow.add( new UI.Button( strings.getKey( 'sidebar/material/copy' ) ).setMarginLeft( '4px' ).onClick( function () { - - copiedMaterial = currentObject.material; - - if ( Array.isArray( copiedMaterial ) ) { - - if ( copiedMaterial.length === 0 ) return; - - copiedMaterial = copiedMaterial[ currentMaterialSlot ]; - - } - - } ) ); - - managerRow.add( new UI.Button( strings.getKey( 'sidebar/material/paste' ) ).setMarginLeft( '4px' ).onClick( function () { - - if ( copiedMaterial === undefined ) return; - - editor.execute( new SetMaterialCommand( editor, currentObject, copiedMaterial, currentMaterialSlot ), 'Pasted Material: ' + materialClass.getValue() ); - refreshUI(); - update(); - - } ) ); - - container.add( managerRow ); - - // type - var materialClassRow = new UI.Row(); - var materialClass = new UI.Select().setOptions( { + var materialClassRow = new UIRow(); + var materialClass = new UISelect().setOptions( { 'LineBasicMaterial': 'LineBasicMaterial', 'LineDashedMaterial': 'LineDashedMaterial', @@ -95,23 +83,23 @@ Sidebar.Material = function ( editor ) { } ).setWidth( '150px' ).setFontSize( '12px' ).onChange( update ); - materialClassRow.add( new UI.Text( strings.getKey( 'sidebar/material/type' ) ).setWidth( '90px' ) ); + materialClassRow.add( new UIText( strings.getKey( 'sidebar/material/type' ) ).setWidth( '90px' ) ); materialClassRow.add( materialClass ); container.add( materialClassRow ); // uuid - var materialUUIDRow = new UI.Row(); - var materialUUID = new UI.Input().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true ); - var materialUUIDRenew = new UI.Button( strings.getKey( 'sidebar/material/new' ) ).setMarginLeft( '7px' ).onClick( function () { + var materialUUIDRow = new UIRow(); + var materialUUID = new UIInput().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true ); + var materialUUIDRenew = new UIButton( strings.getKey( 'sidebar/material/new' ) ).setMarginLeft( '7px' ).onClick( function () { - materialUUID.setValue( THREE.Math.generateUUID() ); + materialUUID.setValue( THREE.MathUtils.generateUUID() ); update(); } ); - materialUUIDRow.add( new UI.Text( strings.getKey( 'sidebar/material/uuid' ) ).setWidth( '90px' ) ); + materialUUIDRow.add( new UIText( strings.getKey( 'sidebar/material/uuid' ) ).setWidth( '90px' ) ); materialUUIDRow.add( materialUUID ); materialUUIDRow.add( materialUUIDRenew ); @@ -119,24 +107,24 @@ Sidebar.Material = function ( editor ) { // name - var materialNameRow = new UI.Row(); - var materialName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { + var materialNameRow = new UIRow(); + var materialName = new UIInput().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { editor.execute( new SetMaterialValueCommand( editor, editor.selected, 'name', materialName.getValue(), currentMaterialSlot ) ); } ); - materialNameRow.add( new UI.Text( strings.getKey( 'sidebar/material/name' ) ).setWidth( '90px' ) ); + materialNameRow.add( new UIText( strings.getKey( 'sidebar/material/name' ) ).setWidth( '90px' ) ); materialNameRow.add( materialName ); container.add( materialNameRow ); // program - var materialProgramRow = new UI.Row(); - materialProgramRow.add( new UI.Text( strings.getKey( 'sidebar/material/program' ) ).setWidth( '90px' ) ); + var materialProgramRow = new UIRow(); + materialProgramRow.add( new UIText( strings.getKey( 'sidebar/material/program' ) ).setWidth( '90px' ) ); - var materialProgramInfo = new UI.Button( strings.getKey( 'sidebar/material/info' ) ); + var materialProgramInfo = new UIButton( strings.getKey( 'sidebar/material/info' ) ); materialProgramInfo.setMarginLeft( '4px' ); materialProgramInfo.onClick( function () { @@ -145,7 +133,7 @@ Sidebar.Material = function ( editor ) { } ); materialProgramRow.add( materialProgramInfo ); - var materialProgramVertex = new UI.Button( strings.getKey( 'sidebar/material/vertex' ) ); + var materialProgramVertex = new UIButton( strings.getKey( 'sidebar/material/vertex' ) ); materialProgramVertex.setMarginLeft( '4px' ); materialProgramVertex.onClick( function () { @@ -154,7 +142,7 @@ Sidebar.Material = function ( editor ) { } ); materialProgramRow.add( materialProgramVertex ); - var materialProgramFragment = new UI.Button( strings.getKey( 'sidebar/material/fragment' ) ); + var materialProgramFragment = new UIButton( strings.getKey( 'sidebar/material/fragment' ) ); materialProgramFragment.setMarginLeft( '4px' ); materialProgramFragment.onClick( function () { @@ -167,131 +155,149 @@ Sidebar.Material = function ( editor ) { // color - var materialColorRow = new UI.Row(); - var materialColor = new UI.Color().onChange( update ); + var materialColorRow = new UIRow(); + var materialColor = new UIColor().onChange( update ); - materialColorRow.add( new UI.Text( strings.getKey( 'sidebar/material/color' ) ).setWidth( '90px' ) ); + materialColorRow.add( new UIText( strings.getKey( 'sidebar/material/color' ) ).setWidth( '90px' ) ); materialColorRow.add( materialColor ); container.add( materialColorRow ); // roughness - var materialRoughnessRow = new UI.Row(); - var materialRoughness = new UI.Number( 0.5 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); + var materialRoughnessRow = new UIRow(); + var materialRoughness = new UINumber( 0.5 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); - materialRoughnessRow.add( new UI.Text( strings.getKey( 'sidebar/material/roughness' ) ).setWidth( '90px' ) ); + materialRoughnessRow.add( new UIText( strings.getKey( 'sidebar/material/roughness' ) ).setWidth( '90px' ) ); materialRoughnessRow.add( materialRoughness ); container.add( materialRoughnessRow ); // metalness - var materialMetalnessRow = new UI.Row(); - var materialMetalness = new UI.Number( 0.5 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); + var materialMetalnessRow = new UIRow(); + var materialMetalness = new UINumber( 0.5 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); - materialMetalnessRow.add( new UI.Text( strings.getKey( 'sidebar/material/metalness' ) ).setWidth( '90px' ) ); + materialMetalnessRow.add( new UIText( strings.getKey( 'sidebar/material/metalness' ) ).setWidth( '90px' ) ); materialMetalnessRow.add( materialMetalness ); container.add( materialMetalnessRow ); + /* + // sheen + + var materialSheenRow = new UIRow(); + var materialSheenEnabled = new UICheckbox( false ).onChange( update ); + var materialSheen = new UIColor().setHexValue( 0x000000 ).onChange( update ); + + materialSheenRow.add( new UIText( strings.getKey( 'sidebar/material/sheen' ) ).setWidth( '90px' ) ) + materialSheenRow.add( materialSheenEnabled ); + materialSheenRow.add( materialSheen ); + + container.add( materialSheenRow ); + */ + // emissive - var materialEmissiveRow = new UI.Row(); - var materialEmissive = new UI.Color().setHexValue( 0x000000 ).onChange( update ); + var materialEmissiveRow = new UIRow(); + var materialEmissive = new UIColor().setHexValue( 0x000000 ).onChange( update ); - materialEmissiveRow.add( new UI.Text( strings.getKey( 'sidebar/material/emissive' ) ).setWidth( '90px' ) ); + materialEmissiveRow.add( new UIText( strings.getKey( 'sidebar/material/emissive' ) ).setWidth( '90px' ) ); materialEmissiveRow.add( materialEmissive ); container.add( materialEmissiveRow ); // specular - var materialSpecularRow = new UI.Row(); - var materialSpecular = new UI.Color().setHexValue( 0x111111 ).onChange( update ); + var materialSpecularRow = new UIRow(); + var materialSpecular = new UIColor().setHexValue( 0x111111 ).onChange( update ); - materialSpecularRow.add( new UI.Text( strings.getKey( 'sidebar/material/specular' ) ).setWidth( '90px' ) ); + materialSpecularRow.add( new UIText( strings.getKey( 'sidebar/material/specular' ) ).setWidth( '90px' ) ); materialSpecularRow.add( materialSpecular ); container.add( materialSpecularRow ); // shininess - var materialShininessRow = new UI.Row(); - var materialShininess = new UI.Number( 30 ).onChange( update ); + var materialShininessRow = new UIRow(); + var materialShininess = new UINumber( 30 ).onChange( update ); - materialShininessRow.add( new UI.Text( strings.getKey( 'sidebar/material/shininess' ) ).setWidth( '90px' ) ); + materialShininessRow.add( new UIText( strings.getKey( 'sidebar/material/shininess' ) ).setWidth( '90px' ) ); materialShininessRow.add( materialShininess ); container.add( materialShininessRow ); - // clearCoat + // clearcoat - var materialClearCoatRow = new UI.Row(); - var materialClearCoat = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); + var materialClearcoatRow = new UIRow(); + var materialClearcoat = new UINumber( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); - materialClearCoatRow.add( new UI.Text( strings.getKey( 'sidebar/material/clearcoat' ) ).setWidth( '90px' ) ); - materialClearCoatRow.add( materialClearCoat ); + materialClearcoatRow.add( new UIText( strings.getKey( 'sidebar/material/clearcoat' ) ).setWidth( '90px' ) ); + materialClearcoatRow.add( materialClearcoat ); - container.add( materialClearCoatRow ); + container.add( materialClearcoatRow ); - // clearCoatRoughness + // clearcoatRoughness - var materialClearCoatRoughnessRow = new UI.Row(); - var materialClearCoatRoughness = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); + var materialClearcoatRoughnessRow = new UIRow(); + var materialClearcoatRoughness = new UINumber( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); - materialClearCoatRoughnessRow.add( new UI.Text( strings.getKey( 'sidebar/material/clearcoatroughness' ) ).setWidth( '90px' ) ); - materialClearCoatRoughnessRow.add( materialClearCoatRoughness ); + materialClearcoatRoughnessRow.add( new UIText( strings.getKey( 'sidebar/material/clearcoatroughness' ) ).setWidth( '90px' ) ); + materialClearcoatRoughnessRow.add( materialClearcoatRoughness ); - container.add( materialClearCoatRoughnessRow ); + container.add( materialClearcoatRoughnessRow ); // vertex colors - var materialVertexColorsRow = new UI.Row(); - var materialVertexColors = new UI.Select().setOptions( { - - 0: strings.getKey( 'sidebar/material/vertexcolors/no' ), - 1: strings.getKey( 'sidebar/material/vertexcolors/face' ), - 2: strings.getKey( 'sidebar/material/vertexcolors/vertex' ) + var materialVertexColorsRow = new UIRow(); + var materialVertexColors = new UICheckbox( false ).onChange( update ); - } ).onChange( update ); - - materialVertexColorsRow.add( new UI.Text( strings.getKey( 'sidebar/material/vertexcolors' ) ).setWidth( '90px' ) ); + materialVertexColorsRow.add( new UIText( strings.getKey( 'sidebar/material/vertexcolors' ) ).setWidth( '90px' ) ); materialVertexColorsRow.add( materialVertexColors ); container.add( materialVertexColorsRow ); + // vertex tangents + + var materialVertexTangentsRow = new UIRow(); + var materialVertexTangents = new UICheckbox( false ).onChange( update ); + + materialVertexTangentsRow.add( new UIText( strings.getKey( 'sidebar/material/vertextangents' ) ).setWidth( '90px' ) ); + materialVertexTangentsRow.add( materialVertexTangents ); + + container.add( materialVertexTangentsRow ); + // depth packing - var materialDepthPackingRow = new UI.Row(); - var materialDepthPacking = new UI.Select().setOptions( { + var materialDepthPackingRow = new UIRow(); + var materialDepthPacking = new UISelect().setOptions( { [ THREE.BasicDepthPacking ]: 'BasicDepthPacking', [ THREE.RGBADepthPacking ]: 'RGBADepthPacking' } ); materialDepthPacking.onChange( update ); - materialDepthPackingRow.add( new UI.Text( strings.getKey( 'sidebar/material/depthPacking' ) ).setWidth( '90px' ) ); + materialDepthPackingRow.add( new UIText( strings.getKey( 'sidebar/material/depthPacking' ) ).setWidth( '90px' ) ); materialDepthPackingRow.add( materialDepthPacking ); container.add( materialDepthPackingRow ); // skinning - var materialSkinningRow = new UI.Row(); - var materialSkinning = new UI.Checkbox( false ).onChange( update ); + var materialSkinningRow = new UIRow(); + var materialSkinning = new UICheckbox( false ).onChange( update ); - materialSkinningRow.add( new UI.Text( strings.getKey( 'sidebar/material/skinning' ) ).setWidth( '90px' ) ); + materialSkinningRow.add( new UIText( strings.getKey( 'sidebar/material/skinning' ) ).setWidth( '90px' ) ); materialSkinningRow.add( materialSkinning ); container.add( materialSkinningRow ); // map - var materialMapRow = new UI.Row(); - var materialMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialMap = new UI.Texture().onChange( updateMaterial ); + var materialMapRow = new UIRow(); + var materialMapEnabled = new UICheckbox( false ).onChange( update ); + var materialMap = new UITexture().onChange( updateMaterial ); - materialMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/map' ) ).setWidth( '90px' ) ); + materialMapRow.add( new UIText( strings.getKey( 'sidebar/material/map' ) ).setWidth( '90px' ) ); materialMapRow.add( materialMapEnabled ); materialMapRow.add( materialMap ); @@ -299,11 +305,11 @@ Sidebar.Material = function ( editor ) { // matcap map - var materialMatcapMapRow = new UI.Row(); - var materialMatcapMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialMatcapMap = new UI.Texture().onChange( update ); + var materialMatcapMapRow = new UIRow(); + var materialMatcapMapEnabled = new UICheckbox( false ).onChange( update ); + var materialMatcapMap = new UITexture().onChange( update ); - materialMatcapMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/matcap' ) ).setWidth( '90px' ) ); + materialMatcapMapRow.add( new UIText( strings.getKey( 'sidebar/material/matcap' ) ).setWidth( '90px' ) ); materialMatcapMapRow.add( materialMatcapMapEnabled ); materialMatcapMapRow.add( materialMatcapMap ); @@ -311,11 +317,11 @@ Sidebar.Material = function ( editor ) { // alpha map - var materialAlphaMapRow = new UI.Row(); - var materialAlphaMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialAlphaMap = new UI.Texture().onChange( update ); + var materialAlphaMapRow = new UIRow(); + var materialAlphaMapEnabled = new UICheckbox( false ).onChange( update ); + var materialAlphaMap = new UITexture().onChange( update ); - materialAlphaMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/alphamap' ) ).setWidth( '90px' ) ); + materialAlphaMapRow.add( new UIText( strings.getKey( 'sidebar/material/alphamap' ) ).setWidth( '90px' ) ); materialAlphaMapRow.add( materialAlphaMapEnabled ); materialAlphaMapRow.add( materialAlphaMap ); @@ -323,12 +329,12 @@ Sidebar.Material = function ( editor ) { // bump map - var materialBumpMapRow = new UI.Row(); - var materialBumpMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialBumpMap = new UI.Texture().onChange( update ); - var materialBumpScale = new UI.Number( 1 ).setWidth( '30px' ).onChange( update ); + var materialBumpMapRow = new UIRow(); + var materialBumpMapEnabled = new UICheckbox( false ).onChange( update ); + var materialBumpMap = new UITexture().onChange( update ); + var materialBumpScale = new UINumber( 1 ).setWidth( '30px' ).onChange( update ); - materialBumpMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/bumpmap' ) ).setWidth( '90px' ) ); + materialBumpMapRow.add( new UIText( strings.getKey( 'sidebar/material/bumpmap' ) ).setWidth( '90px' ) ); materialBumpMapRow.add( materialBumpMapEnabled ); materialBumpMapRow.add( materialBumpMap ); materialBumpMapRow.add( materialBumpScale ); @@ -337,13 +343,13 @@ Sidebar.Material = function ( editor ) { // normal map - var materialNormalMapRow = new UI.Row(); - var materialNormalMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialNormalMap = new UI.Texture().onChange( update ); - var materialNormalScaleX = new UI.Number( 1 ).setWidth( '30px' ).onChange( update ); - var materialNormalScaleY = new UI.Number( 1 ).setWidth( '30px' ).onChange( update ); + var materialNormalMapRow = new UIRow(); + var materialNormalMapEnabled = new UICheckbox( false ).onChange( update ); + var materialNormalMap = new UITexture().onChange( update ); + var materialNormalScaleX = new UINumber( 1 ).setWidth( '30px' ).onChange( update ); + var materialNormalScaleY = new UINumber( 1 ).setWidth( '30px' ).onChange( update ); - materialNormalMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/normalmap' ) ).setWidth( '90px' ) ); + materialNormalMapRow.add( new UIText( strings.getKey( 'sidebar/material/normalmap' ) ).setWidth( '90px' ) ); materialNormalMapRow.add( materialNormalMapEnabled ); materialNormalMapRow.add( materialNormalMap ); materialNormalMapRow.add( materialNormalScaleX ); @@ -353,28 +359,28 @@ Sidebar.Material = function ( editor ) { // clearcoat normal map - var materialClearCoatNormalMapRow = new UI.Row(); - var materialClearCoatNormalMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialClearCoatNormalMap = new UI.Texture().onChange( update ); - var materialClearCoatNormalScaleX = new UI.Number( 1 ).setWidth( '30px' ).onChange( update ); - var materialClearCoatNormalScaleY = new UI.Number( 1 ).setWidth( '30px' ).onChange( update ); + var materialClearcoatNormalMapRow = new UIRow(); + var materialClearcoatNormalMapEnabled = new UICheckbox( false ).onChange( update ); + var materialClearcoatNormalMap = new UITexture().onChange( update ); + var materialClearcoatNormalScaleX = new UINumber( 1 ).setWidth( '30px' ).onChange( update ); + var materialClearcoatNormalScaleY = new UINumber( 1 ).setWidth( '30px' ).onChange( update ); - materialClearCoatNormalMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/clearcoatnormalmap' ) ).setWidth( '90px' ) ); - materialClearCoatNormalMapRow.add( materialClearCoatNormalMapEnabled ); - materialClearCoatNormalMapRow.add( materialClearCoatNormalMap ); - materialClearCoatNormalMapRow.add( materialClearCoatNormalScaleX ); - materialClearCoatNormalMapRow.add( materialClearCoatNormalScaleY ); + materialClearcoatNormalMapRow.add( new UIText( strings.getKey( 'sidebar/material/clearcoatnormalmap' ) ).setWidth( '90px' ) ); + materialClearcoatNormalMapRow.add( materialClearcoatNormalMapEnabled ); + materialClearcoatNormalMapRow.add( materialClearcoatNormalMap ); + materialClearcoatNormalMapRow.add( materialClearcoatNormalScaleX ); + materialClearcoatNormalMapRow.add( materialClearcoatNormalScaleY ); - container.add( materialClearCoatNormalMapRow ); + container.add( materialClearcoatNormalMapRow ); // displacement map - var materialDisplacementMapRow = new UI.Row(); - var materialDisplacementMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialDisplacementMap = new UI.Texture().onChange( update ); - var materialDisplacementScale = new UI.Number( 1 ).setWidth( '30px' ).onChange( update ); + var materialDisplacementMapRow = new UIRow(); + var materialDisplacementMapEnabled = new UICheckbox( false ).onChange( update ); + var materialDisplacementMap = new UITexture().onChange( update ); + var materialDisplacementScale = new UINumber( 1 ).setWidth( '30px' ).onChange( update ); - materialDisplacementMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/displacemap' ) ).setWidth( '90px' ) ); + materialDisplacementMapRow.add( new UIText( strings.getKey( 'sidebar/material/displacemap' ) ).setWidth( '90px' ) ); materialDisplacementMapRow.add( materialDisplacementMapEnabled ); materialDisplacementMapRow.add( materialDisplacementMap ); materialDisplacementMapRow.add( materialDisplacementScale ); @@ -383,11 +389,11 @@ Sidebar.Material = function ( editor ) { // roughness map - var materialRoughnessMapRow = new UI.Row(); - var materialRoughnessMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialRoughnessMap = new UI.Texture().onChange( update ); + var materialRoughnessMapRow = new UIRow(); + var materialRoughnessMapEnabled = new UICheckbox( false ).onChange( update ); + var materialRoughnessMap = new UITexture().onChange( update ); - materialRoughnessMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/roughmap' ) ).setWidth( '90px' ) ); + materialRoughnessMapRow.add( new UIText( strings.getKey( 'sidebar/material/roughmap' ) ).setWidth( '90px' ) ); materialRoughnessMapRow.add( materialRoughnessMapEnabled ); materialRoughnessMapRow.add( materialRoughnessMap ); @@ -395,11 +401,11 @@ Sidebar.Material = function ( editor ) { // metalness map - var materialMetalnessMapRow = new UI.Row(); - var materialMetalnessMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialMetalnessMap = new UI.Texture().onChange( update ); + var materialMetalnessMapRow = new UIRow(); + var materialMetalnessMapEnabled = new UICheckbox( false ).onChange( update ); + var materialMetalnessMap = new UITexture().onChange( update ); - materialMetalnessMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/metalmap' ) ).setWidth( '90px' ) ); + materialMetalnessMapRow.add( new UIText( strings.getKey( 'sidebar/material/metalmap' ) ).setWidth( '90px' ) ); materialMetalnessMapRow.add( materialMetalnessMapEnabled ); materialMetalnessMapRow.add( materialMetalnessMap ); @@ -407,11 +413,11 @@ Sidebar.Material = function ( editor ) { // specular map - var materialSpecularMapRow = new UI.Row(); - var materialSpecularMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialSpecularMap = new UI.Texture().onChange( update ); + var materialSpecularMapRow = new UIRow(); + var materialSpecularMapEnabled = new UICheckbox( false ).onChange( update ); + var materialSpecularMap = new UITexture().onChange( update ); - materialSpecularMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/specularmap' ) ).setWidth( '90px' ) ); + materialSpecularMapRow.add( new UIText( strings.getKey( 'sidebar/material/specularmap' ) ).setWidth( '90px' ) ); materialSpecularMapRow.add( materialSpecularMapEnabled ); materialSpecularMapRow.add( materialSpecularMap ); @@ -419,12 +425,12 @@ Sidebar.Material = function ( editor ) { // env map - var materialEnvMapRow = new UI.Row(); - var materialEnvMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialEnvMap = new UI.Texture( THREE.SphericalReflectionMapping ).onChange( updateMaterial ); - var materialReflectivity = new UI.Number( 1 ).setWidth( '30px' ).onChange( update ); + var materialEnvMapRow = new UIRow(); + var materialEnvMapEnabled = new UICheckbox( false ).onChange( update ); + var materialEnvMap = new UITexture( THREE.SphericalReflectionMapping ).onChange( updateMaterial ); + var materialReflectivity = new UINumber( 1 ).setWidth( '30px' ).onChange( update ); - materialEnvMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/envmap' ) ).setWidth( '90px' ) ); + materialEnvMapRow.add( new UIText( strings.getKey( 'sidebar/material/envmap' ) ).setWidth( '90px' ) ); materialEnvMapRow.add( materialEnvMapEnabled ); materialEnvMapRow.add( materialEnvMap ); materialEnvMapRow.add( materialReflectivity ); @@ -433,11 +439,11 @@ Sidebar.Material = function ( editor ) { // light map - var materialLightMapRow = new UI.Row(); - var materialLightMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialLightMap = new UI.Texture().onChange( update ); + var materialLightMapRow = new UIRow(); + var materialLightMapEnabled = new UICheckbox( false ).onChange( update ); + var materialLightMap = new UITexture().onChange( update ); - materialLightMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/lightmap' ) ).setWidth( '90px' ) ); + materialLightMapRow.add( new UIText( strings.getKey( 'sidebar/material/lightmap' ) ).setWidth( '90px' ) ); materialLightMapRow.add( materialLightMapEnabled ); materialLightMapRow.add( materialLightMap ); @@ -445,12 +451,12 @@ Sidebar.Material = function ( editor ) { // ambient occlusion map - var materialAOMapRow = new UI.Row(); - var materialAOMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialAOMap = new UI.Texture().onChange( update ); - var materialAOScale = new UI.Number( 1 ).setRange( 0, 1 ).setWidth( '30px' ).onChange( update ); + var materialAOMapRow = new UIRow(); + var materialAOMapEnabled = new UICheckbox( false ).onChange( update ); + var materialAOMap = new UITexture().onChange( update ); + var materialAOScale = new UINumber( 1 ).setRange( 0, 1 ).setWidth( '30px' ).onChange( update ); - materialAOMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/aomap' ) ).setWidth( '90px' ) ); + materialAOMapRow.add( new UIText( strings.getKey( 'sidebar/material/aomap' ) ).setWidth( '90px' ) ); materialAOMapRow.add( materialAOMapEnabled ); materialAOMapRow.add( materialAOMap ); materialAOMapRow.add( materialAOScale ); @@ -459,11 +465,11 @@ Sidebar.Material = function ( editor ) { // emissive map - var materialEmissiveMapRow = new UI.Row(); - var materialEmissiveMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialEmissiveMap = new UI.Texture().onChange( updateMaterial ); + var materialEmissiveMapRow = new UIRow(); + var materialEmissiveMapEnabled = new UICheckbox( false ).onChange( update ); + var materialEmissiveMap = new UITexture().onChange( updateMaterial ); - materialEmissiveMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/emissivemap' ) ).setWidth( '90px' ) ); + materialEmissiveMapRow.add( new UIText( strings.getKey( 'sidebar/material/emissivemap' ) ).setWidth( '90px' ) ); materialEmissiveMapRow.add( materialEmissiveMapEnabled ); materialEmissiveMapRow.add( materialEmissiveMap ); @@ -471,11 +477,11 @@ Sidebar.Material = function ( editor ) { // gradient map - var materialGradientMapRow = new UI.Row(); - var materialGradientMapEnabled = new UI.Checkbox( false ).onChange( update ); - var materialGradientMap = new UI.Texture().onChange( update ); + var materialGradientMapRow = new UIRow(); + var materialGradientMapEnabled = new UICheckbox( false ).onChange( update ); + var materialGradientMap = new UITexture().onChange( update ); - materialGradientMapRow.add( new UI.Text( strings.getKey( 'sidebar/material/gradientmap' ) ).setWidth( '90px' ) ); + materialGradientMapRow.add( new UIText( strings.getKey( 'sidebar/material/gradientmap' ) ).setWidth( '90px' ) ); materialGradientMapRow.add( materialGradientMapEnabled ); materialGradientMapRow.add( materialGradientMap ); @@ -483,8 +489,8 @@ Sidebar.Material = function ( editor ) { // side - var materialSideRow = new UI.Row(); - var materialSide = new UI.Select().setOptions( { + var materialSideRow = new UIRow(); + var materialSide = new UISelect().setOptions( { 0: strings.getKey( 'sidebar/material/side/front' ), 1: strings.getKey( 'sidebar/material/side/back' ), @@ -492,25 +498,25 @@ Sidebar.Material = function ( editor ) { } ).setWidth( '150px' ).setFontSize( '12px' ).onChange( update ); - materialSideRow.add( new UI.Text( strings.getKey( 'sidebar/material/side' ) ).setWidth( '90px' ) ); + materialSideRow.add( new UIText( strings.getKey( 'sidebar/material/side' ) ).setWidth( '90px' ) ); materialSideRow.add( materialSide ); container.add( materialSideRow ); // shading - var materialShadingRow = new UI.Row(); - var materialShading = new UI.Checkbox( false ).setLeft( '100px' ).onChange( update ); + var materialShadingRow = new UIRow(); + var materialShading = new UICheckbox( false ).setLeft( '100px' ).onChange( update ); - materialShadingRow.add( new UI.Text( strings.getKey( 'sidebar/material/flatshaded' ) ).setWidth( '90px' ) ); + materialShadingRow.add( new UIText( strings.getKey( 'sidebar/material/flatshaded' ) ).setWidth( '90px' ) ); materialShadingRow.add( materialShading ); container.add( materialShadingRow ); // blending - var materialBlendingRow = new UI.Row(); - var materialBlending = new UI.Select().setOptions( { + var materialBlendingRow = new UIRow(); + var materialBlending = new UISelect().setOptions( { 0: strings.getKey( 'sidebar/material/blending/no' ), 1: strings.getKey( 'sidebar/material/blending/normal' ), @@ -521,50 +527,48 @@ Sidebar.Material = function ( editor ) { } ).setWidth( '150px' ).setFontSize( '12px' ).onChange( update ); - materialBlendingRow.add( new UI.Text( strings.getKey( 'sidebar/material/blending' ) ).setWidth( '90px' ) ); + materialBlendingRow.add( new UIText( strings.getKey( 'sidebar/material/blending' ) ).setWidth( '90px' ) ); materialBlendingRow.add( materialBlending ); container.add( materialBlendingRow ); // opacity - var materialOpacityRow = new UI.Row(); - var materialOpacity = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); + var materialOpacityRow = new UIRow(); + var materialOpacity = new UINumber( 1 ).setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); - materialOpacityRow.add( new UI.Text( strings.getKey( 'sidebar/material/opacity' ) ).setWidth( '90px' ) ); + materialOpacityRow.add( new UIText( strings.getKey( 'sidebar/material/opacity' ) ).setWidth( '90px' ) ); materialOpacityRow.add( materialOpacity ); container.add( materialOpacityRow ); // transparent - var materialTransparentRow = new UI.Row(); - var materialTransparent = new UI.Checkbox().setLeft( '100px' ).onChange( update ); + var materialTransparentRow = new UIRow(); + var materialTransparent = new UICheckbox().setLeft( '100px' ).onChange( update ); - materialTransparentRow.add( new UI.Text( strings.getKey( 'sidebar/material/transparent' ) ).setWidth( '90px' ) ); + materialTransparentRow.add( new UIText( strings.getKey( 'sidebar/material/transparent' ) ).setWidth( '90px' ) ); materialTransparentRow.add( materialTransparent ); container.add( materialTransparentRow ); // alpha test - var materialAlphaTestRow = new UI.Row(); - var materialAlphaTest = new UI.Number().setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); + var materialAlphaTestRow = new UIRow(); + var materialAlphaTest = new UINumber().setWidth( '60px' ).setRange( 0, 1 ).onChange( update ); - materialAlphaTestRow.add( new UI.Text( strings.getKey( 'sidebar/material/alphatest' ) ).setWidth( '90px' ) ); + materialAlphaTestRow.add( new UIText( strings.getKey( 'sidebar/material/alphatest' ) ).setWidth( '90px' ) ); materialAlphaTestRow.add( materialAlphaTest ); container.add( materialAlphaTestRow ); // wireframe - var materialWireframeRow = new UI.Row(); - var materialWireframe = new UI.Checkbox( false ).onChange( update ); - var materialWireframeLinewidth = new UI.Number( 1 ).setWidth( '60px' ).setRange( 0, 100 ).onChange( update ); + var materialWireframeRow = new UIRow(); + var materialWireframe = new UICheckbox( false ).onChange( update ); - materialWireframeRow.add( new UI.Text( strings.getKey( 'sidebar/material/wireframe' ) ).setWidth( '90px' ) ); + materialWireframeRow.add( new UIText( strings.getKey( 'sidebar/material/wireframe' ) ).setWidth( '90px' ) ); materialWireframeRow.add( materialWireframe ); - materialWireframeRow.add( materialWireframeLinewidth ); container.add( materialWireframeRow ); @@ -601,15 +605,28 @@ Sidebar.Material = function ( editor ) { if ( material.type !== materialClass.getValue() ) { - material = new THREE[ materialClass.getValue() ](); + material = new materialClasses[ materialClass.getValue() ](); - if ( material.type == "RawShaderMaterial" ) { + if ( material.type === "RawShaderMaterial" ) { material.vertexShader = vertexShaderVariables + material.vertexShader; } + if ( Array.isArray( currentObject.material ) ) { + + // don't remove the entire multi-material. just the material of the selected slot + + editor.removeMaterial( currentObject.material[ currentMaterialSlot ] ); + + } else { + + editor.removeMaterial( currentObject.material ); + + } + editor.execute( new SetMaterialCommand( editor, currentObject, material, currentMaterialSlot ), 'New Material: ' + materialClass.getValue() ); + editor.addMaterial( material ); // TODO Copy other references in the scene graph // keeping name and UUID then. // Also there should be means to create a unique @@ -624,18 +641,36 @@ Sidebar.Material = function ( editor ) { } - if ( material.roughness !== undefined && Math.abs( material.roughness - materialRoughness.getValue() ) >= 0.01 ) { + if ( material.roughness !== undefined && Math.abs( material.roughness - materialRoughness.getValue() ) >= epsilon ) { editor.execute( new SetMaterialValueCommand( editor, currentObject, 'roughness', materialRoughness.getValue(), currentMaterialSlot ) ); } - if ( material.metalness !== undefined && Math.abs( material.metalness - materialMetalness.getValue() ) >= 0.01 ) { + if ( material.metalness !== undefined && Math.abs( material.metalness - materialMetalness.getValue() ) >= epsilon ) { editor.execute( new SetMaterialValueCommand( editor, currentObject, 'metalness', materialMetalness.getValue(), currentMaterialSlot ) ); } + /* + if ( material.sheen !== undefined ) { + + var sheenEnabled = materialSheenEnabled.getValue() === true; + + var sheen = sheenEnabled ? new Color(materialSheen.getHexValue()) : null; + + editor.execute( new SetMaterialValueCommand( editor, currentObject, 'sheen', sheen, currentMaterialSlot ) ); + + } + + if ( material.sheen !== undefined && material.sheen !== null && material.sheen.getHex() !== materialSheen.getHexValue() ) { + + editor.execute( new SetMaterialColorCommand( editor, currentObject, 'sheen', materialSheen.getHexValue(), currentMaterialSlot ) ); + + } + */ + if ( material.emissive !== undefined && material.emissive.getHex() !== materialEmissive.getHexValue() ) { editor.execute( new SetMaterialColorCommand( editor, currentObject, 'emissive', materialEmissive.getHexValue(), currentMaterialSlot ) ); @@ -648,27 +683,27 @@ Sidebar.Material = function ( editor ) { } - if ( material.shininess !== undefined && Math.abs( material.shininess - materialShininess.getValue() ) >= 0.01 ) { + if ( material.shininess !== undefined && Math.abs( material.shininess - materialShininess.getValue() ) >= epsilon ) { editor.execute( new SetMaterialValueCommand( editor, currentObject, 'shininess', materialShininess.getValue(), currentMaterialSlot ) ); } - if ( material.clearCoat !== undefined && Math.abs( material.clearCoat - materialClearCoat.getValue() ) >= 0.01 ) { + if ( material.clearcoat !== undefined && Math.abs( material.clearcoat - materialClearcoat.getValue() ) >= epsilon ) { - editor.execute( new SetMaterialValueCommand( editor, currentObject, 'clearCoat', materialClearCoat.getValue(), currentMaterialSlot ) ); + editor.execute( new SetMaterialValueCommand( editor, currentObject, 'clearcoat', materialClearcoat.getValue(), currentMaterialSlot ) ); } - if ( material.clearCoatRoughness !== undefined && Math.abs( material.clearCoatRoughness - materialClearCoatRoughness.getValue() ) >= 0.01 ) { + if ( material.clearcoatRoughness !== undefined && Math.abs( material.clearcoatRoughness - materialClearcoatRoughness.getValue() ) >= epsilon ) { - editor.execute( new SetMaterialValueCommand( editor, currentObject, 'clearCoatRoughness', materialClearCoatRoughness.getValue(), currentMaterialSlot ) ); + editor.execute( new SetMaterialValueCommand( editor, currentObject, 'clearcoatRoughness', materialClearcoatRoughness.getValue(), currentMaterialSlot ) ); } if ( material.vertexColors !== undefined ) { - var vertexColors = parseInt( materialVertexColors.getValue() ); + var vertexColors = materialVertexColors.getValue(); if ( material.vertexColors !== vertexColors ) { @@ -817,34 +852,34 @@ Sidebar.Material = function ( editor ) { } - if ( material.clearCoatNormalMap !== undefined ) { + if ( material.clearcoatNormalMap !== undefined ) { - var clearCoatNormalMapEnabled = materialClearCoatNormalMapEnabled.getValue() === true; + var clearcoatNormalMapEnabled = materialClearcoatNormalMapEnabled.getValue() === true; if ( objectHasUvs ) { - var clearCoatNormalMap = clearCoatNormalMapEnabled ? materialClearCoatNormalMap.getValue() : null; + var clearcoatNormalMap = clearcoatNormalMapEnabled ? materialClearcoatNormalMap.getValue() : null; - if ( material.clearCoatNormalMap !== clearCoatNormalMap ) { + if ( material.clearcoatNormalMap !== clearcoatNormalMap ) { - editor.execute( new SetMaterialMapCommand( editor, currentObject, 'clearCoatNormalMap', clearCoatNormalMap, currentMaterialSlot ) ); + editor.execute( new SetMaterialMapCommand( editor, currentObject, 'clearcoatNormalMap', clearcoatNormalMap, currentMaterialSlot ) ); } - if ( material.clearCoatNormalScale.x !== materialClearCoatNormalScaleX.getValue() || - material.clearCoatNormalScale.y !== materialClearCoatNormalScaleY.getValue() ) { + if ( material.clearcoatNormalScale.x !== materialClearcoatNormalScaleX.getValue() || + material.clearcoatNormalScale.y !== materialClearcoatNormalScaleY.getValue() ) { var value = [ - materialClearCoatNormalScaleX.getValue(), - materialClearCoatNormalScaleY.getValue() + materialClearcoatNormalScaleX.getValue(), + materialClearcoatNormalScaleY.getValue() ]; - editor.execute( new SetMaterialVectorCommand( editor, currentObject, 'clearCoatNormalScale', value, currentMaterialSlot ) ); + editor.execute( new SetMaterialVectorCommand( editor, currentObject, 'clearcoatNormalScale', value, currentMaterialSlot ) ); } } else { - if ( clearCoatNormalMapEnabled ) textureWarning = true; + if ( clearcoatNormalMapEnabled ) textureWarning = true; } @@ -1083,7 +1118,7 @@ Sidebar.Material = function ( editor ) { } - if ( material.opacity !== undefined && Math.abs( material.opacity - materialOpacity.getValue() ) >= 0.01 ) { + if ( material.opacity !== undefined && Math.abs( material.opacity - materialOpacity.getValue() ) >= epsilon ) { editor.execute( new SetMaterialValueCommand( editor, currentObject, 'opacity', materialOpacity.getValue(), currentMaterialSlot ) ); @@ -1095,7 +1130,7 @@ Sidebar.Material = function ( editor ) { } - if ( material.alphaTest !== undefined && Math.abs( material.alphaTest - materialAlphaTest.getValue() ) >= 0.01 ) { + if ( material.alphaTest !== undefined && Math.abs( material.alphaTest - materialAlphaTest.getValue() ) >= epsilon ) { editor.execute( new SetMaterialValueCommand( editor, currentObject, 'alphaTest', materialAlphaTest.getValue(), currentMaterialSlot ) ); @@ -1107,12 +1142,6 @@ Sidebar.Material = function ( editor ) { } - if ( material.wireframeLinewidth !== undefined && Math.abs( material.wireframeLinewidth - materialWireframeLinewidth.getValue() ) >= 0.01 ) { - - editor.execute( new SetMaterialValueCommand( editor, currentObject, 'wireframeLinewidth', materialWireframeLinewidth.getValue(), currentMaterialSlot ) ); - - } - refreshUI(); } @@ -1157,12 +1186,14 @@ Sidebar.Material = function ( editor ) { 'roughness': materialRoughnessRow, 'metalness': materialMetalnessRow, 'emissive': materialEmissiveRow, + // 'sheen': materialSheenRow, 'specular': materialSpecularRow, 'shininess': materialShininessRow, - 'clearCoat': materialClearCoatRow, - 'clearCoatRoughness': materialClearCoatRoughnessRow, + 'clearcoat': materialClearcoatRow, + 'clearcoatRoughness': materialClearcoatRoughnessRow, 'vertexShader': materialProgramRow, 'vertexColors': materialVertexColorsRow, + 'vertexTangents': materialVertexTangentsRow, 'depthPacking': materialDepthPackingRow, 'skinning': materialSkinningRow, 'map': materialMapRow, @@ -1170,6 +1201,7 @@ Sidebar.Material = function ( editor ) { 'alphaMap': materialAlphaMapRow, 'bumpMap': materialBumpMapRow, 'normalMap': materialNormalMapRow, + 'clearcoatNormalMap': materialClearcoatNormalMapRow, 'displacementMap': materialDisplacementMapRow, 'roughnessMap': materialRoughnessMapRow, 'metalnessMap': materialMetalnessMapRow, @@ -1269,6 +1301,15 @@ Sidebar.Material = function ( editor ) { } + /* + if ( material.sheen !== undefined && material.sheen !== null ) { + + materialSheenEnabled.setValue( true ); + materialSheen.setHexValue( material.sheen.getHexString() ); + + } + */ + if ( material.emissive !== undefined ) { materialEmissive.setHexValue( material.emissive.getHexString() ); @@ -1287,15 +1328,15 @@ Sidebar.Material = function ( editor ) { } - if ( material.clearCoat !== undefined ) { + if ( material.clearcoat !== undefined ) { - materialClearCoat.setValue( material.clearCoat ); + materialClearcoat.setValue( material.clearcoat ); } - if ( material.clearCoatRoughness !== undefined ) { + if ( material.clearcoatRoughness !== undefined ) { - materialClearCoatRoughness.setValue( material.clearCoatRoughness ); + materialClearcoatRoughness.setValue( material.clearcoatRoughness ); } @@ -1382,18 +1423,18 @@ Sidebar.Material = function ( editor ) { } - if ( material.clearCoatNormalMap !== undefined ) { + if ( material.clearcoatNormalMap !== undefined ) { - materialClearCoatNormalMapEnabled.setValue( material.clearCoatNormalMap !== null ); + materialClearcoatNormalMapEnabled.setValue( material.clearcoatNormalMap !== null ); - if ( material.clearCoatNormalMap !== null || resetTextureSelectors ) { + if ( material.clearcoatNormalMap !== null || resetTextureSelectors ) { - materialClearCoatNormalMap.setValue( material.clearCoatNormalMap ); + materialClearcoatNormalMap.setValue( material.clearcoatNormalMap ); } - materialClearCoatNormalScaleX.setValue( material.clearCoatNormalScale.x ); - materialClearCoatNormalScaleY.setValue( material.clearCoatNormalScale.y ); + materialClearcoatNormalScaleX.setValue( material.clearcoatNormalScale.x ); + materialClearcoatNormalScaleY.setValue( material.clearcoatNormalScale.y ); } @@ -1557,12 +1598,6 @@ Sidebar.Material = function ( editor ) { } - if ( material.wireframeLinewidth !== undefined ) { - - materialWireframeLinewidth.setValue( material.wireframeLinewidth ); - - } - setRowVisibility(); } @@ -1617,3 +1652,5 @@ Sidebar.Material = function ( editor ) { return container; }; + +export { SidebarMaterial }; diff --git a/editor/js/Sidebar.Object.js b/editor/js/Sidebar.Object.js index d1d2ca029f9c63..ae9bc430a35158 100644 --- a/editor/js/Sidebar.Object.js +++ b/editor/js/Sidebar.Object.js @@ -2,13 +2,25 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Object = function ( editor ) { +import * as THREE from '../../build/three.module.js'; + +import { UIPanel, UIRow, UIInput, UIButton, UIColor, UICheckbox, UIInteger, UITextArea, UIText, UINumber } from './libs/ui.js'; +import { UIBoolean } from './libs/ui.three.js'; + +import { SetUuidCommand } from './commands/SetUuidCommand.js'; +import { SetValueCommand } from './commands/SetValueCommand.js'; +import { SetPositionCommand } from './commands/SetPositionCommand.js'; +import { SetRotationCommand } from './commands/SetRotationCommand.js'; +import { SetScaleCommand } from './commands/SetScaleCommand.js'; +import { SetColorCommand } from './commands/SetColorCommand.js'; + +var SidebarObject = function ( editor ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Panel(); + var container = new UIPanel(); container.setBorderTop( '0' ); container.setPaddingTop( '20px' ); container.setDisplay( 'none' ); @@ -37,15 +49,15 @@ Sidebar.Object = function ( editor ) { switch ( this.getValue() ) { case 'Reset Position': - editor.execute( new SetPositionCommand( editor, object, new THREE.Vector3( 0, 0, 0 ) ) ); + editor.execute( new SetPositionCommand( editor, object, new Vector3( 0, 0, 0 ) ) ); break; case 'Reset Rotation': - editor.execute( new SetRotationCommand( editor, object, new THREE.Euler( 0, 0, 0 ) ) ); + editor.execute( new SetRotationCommand( editor, object, new Euler( 0, 0, 0 ) ) ); break; case 'Reset Scale': - editor.execute( new SetScaleCommand( editor, object, new THREE.Vector3( 1, 1, 1 ) ) ); + editor.execute( new SetScaleCommand( editor, object, new Vector3( 1, 1, 1 ) ) ); break; } @@ -58,27 +70,27 @@ Sidebar.Object = function ( editor ) { // type - var objectTypeRow = new UI.Row(); - var objectType = new UI.Text(); + var objectTypeRow = new UIRow(); + var objectType = new UIText(); - objectTypeRow.add( new UI.Text( strings.getKey( 'sidebar/object/type' ) ).setWidth( '90px' ) ); + objectTypeRow.add( new UIText( strings.getKey( 'sidebar/object/type' ) ).setWidth( '90px' ) ); objectTypeRow.add( objectType ); container.add( objectTypeRow ); // uuid - var objectUUIDRow = new UI.Row(); - var objectUUID = new UI.Input().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true ); - var objectUUIDRenew = new UI.Button( strings.getKey( 'sidebar/object/new' ) ).setMarginLeft( '7px' ).onClick( function () { + var objectUUIDRow = new UIRow(); + var objectUUID = new UIInput().setWidth( '102px' ).setFontSize( '12px' ).setDisabled( true ); + var objectUUIDRenew = new UIButton( strings.getKey( 'sidebar/object/new' ) ).setMarginLeft( '7px' ).onClick( function () { - objectUUID.setValue( THREE.Math.generateUUID() ); + objectUUID.setValue( THREE.MathUtils.generateUUID() ); editor.execute( new SetUuidCommand( editor, editor.selected, objectUUID.getValue() ) ); } ); - objectUUIDRow.add( new UI.Text( strings.getKey( 'sidebar/object/uuid' ) ).setWidth( '90px' ) ); + objectUUIDRow.add( new UIText( strings.getKey( 'sidebar/object/uuid' ) ).setWidth( '90px' ) ); objectUUIDRow.add( objectUUID ); objectUUIDRow.add( objectUUIDRenew ); @@ -86,51 +98,51 @@ Sidebar.Object = function ( editor ) { // name - var objectNameRow = new UI.Row(); - var objectName = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { + var objectNameRow = new UIRow(); + var objectName = new UIInput().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () { editor.execute( new SetValueCommand( editor, editor.selected, 'name', objectName.getValue() ) ); } ); - objectNameRow.add( new UI.Text( strings.getKey( 'sidebar/object/name' ) ).setWidth( '90px' ) ); + objectNameRow.add( new UIText( strings.getKey( 'sidebar/object/name' ) ).setWidth( '90px' ) ); objectNameRow.add( objectName ); container.add( objectNameRow ); // position - var objectPositionRow = new UI.Row(); - var objectPositionX = new UI.Number().setPrecision( 3 ).setWidth( '50px' ).onChange( update ); - var objectPositionY = new UI.Number().setPrecision( 3 ).setWidth( '50px' ).onChange( update ); - var objectPositionZ = new UI.Number().setPrecision( 3 ).setWidth( '50px' ).onChange( update ); + var objectPositionRow = new UIRow(); + var objectPositionX = new UINumber().setPrecision( 3 ).setWidth( '50px' ).onChange( update ); + var objectPositionY = new UINumber().setPrecision( 3 ).setWidth( '50px' ).onChange( update ); + var objectPositionZ = new UINumber().setPrecision( 3 ).setWidth( '50px' ).onChange( update ); - objectPositionRow.add( new UI.Text( strings.getKey( 'sidebar/object/position' ) ).setWidth( '90px' ) ); + objectPositionRow.add( new UIText( strings.getKey( 'sidebar/object/position' ) ).setWidth( '90px' ) ); objectPositionRow.add( objectPositionX, objectPositionY, objectPositionZ ); container.add( objectPositionRow ); // rotation - var objectRotationRow = new UI.Row(); - var objectRotationX = new UI.Number().setStep( 10 ).setUnit( '°' ).setWidth( '50px' ).onChange( update ); - var objectRotationY = new UI.Number().setStep( 10 ).setUnit( '°' ).setWidth( '50px' ).onChange( update ); - var objectRotationZ = new UI.Number().setStep( 10 ).setUnit( '°' ).setWidth( '50px' ).onChange( update ); + var objectRotationRow = new UIRow(); + var objectRotationX = new UINumber().setStep( 10 ).setNudge( 0.1 ).setUnit( '°' ).setWidth( '50px' ).onChange( update ); + var objectRotationY = new UINumber().setStep( 10 ).setNudge( 0.1 ).setUnit( '°' ).setWidth( '50px' ).onChange( update ); + var objectRotationZ = new UINumber().setStep( 10 ).setNudge( 0.1 ).setUnit( '°' ).setWidth( '50px' ).onChange( update ); - objectRotationRow.add( new UI.Text( strings.getKey( 'sidebar/object/rotation' ) ).setWidth( '90px' ) ); + objectRotationRow.add( new UIText( strings.getKey( 'sidebar/object/rotation' ) ).setWidth( '90px' ) ); objectRotationRow.add( objectRotationX, objectRotationY, objectRotationZ ); container.add( objectRotationRow ); // scale - var objectScaleRow = new UI.Row(); - var objectScaleLock = new UI.Checkbox( true ).setPosition( 'absolute' ).setLeft( '75px' ); - var objectScaleX = new UI.Number( 1 ).setPrecision( 3 ).setRange( 0.001, Infinity ).setWidth( '50px' ).onChange( updateScaleX ); - var objectScaleY = new UI.Number( 1 ).setPrecision( 3 ).setRange( 0.001, Infinity ).setWidth( '50px' ).onChange( updateScaleY ); - var objectScaleZ = new UI.Number( 1 ).setPrecision( 3 ).setRange( 0.001, Infinity ).setWidth( '50px' ).onChange( updateScaleZ ); + var objectScaleRow = new UIRow(); + var objectScaleLock = new UICheckbox( true ).setPosition( 'absolute' ).setLeft( '75px' ); + var objectScaleX = new UINumber( 1 ).setPrecision( 3 ).setRange( 0.001, Infinity ).setWidth( '50px' ).onChange( updateScaleX ); + var objectScaleY = new UINumber( 1 ).setPrecision( 3 ).setRange( 0.001, Infinity ).setWidth( '50px' ).onChange( updateScaleY ); + var objectScaleZ = new UINumber( 1 ).setPrecision( 3 ).setRange( 0.001, Infinity ).setWidth( '50px' ).onChange( updateScaleZ ); - objectScaleRow.add( new UI.Text( strings.getKey( 'sidebar/object/scale' ) ).setWidth( '90px' ) ); + objectScaleRow.add( new UIText( strings.getKey( 'sidebar/object/scale' ) ).setWidth( '90px' ) ); objectScaleRow.add( objectScaleLock ); objectScaleRow.add( objectScaleX, objectScaleY, objectScaleZ ); @@ -138,197 +150,195 @@ Sidebar.Object = function ( editor ) { // fov - var objectFovRow = new UI.Row(); - var objectFov = new UI.Number().onChange( update ); + var objectFovRow = new UIRow(); + var objectFov = new UINumber().onChange( update ); - objectFovRow.add( new UI.Text( strings.getKey( 'sidebar/object/fov' ) ).setWidth( '90px' ) ); + objectFovRow.add( new UIText( strings.getKey( 'sidebar/object/fov' ) ).setWidth( '90px' ) ); objectFovRow.add( objectFov ); container.add( objectFovRow ); // left - var objectLeftRow = new UI.Row(); - var objectLeft = new UI.Number().onChange( update ); + var objectLeftRow = new UIRow(); + var objectLeft = new UINumber().onChange( update ); - objectLeftRow.add( new UI.Text( strings.getKey( 'sidebar/object/left' ) ).setWidth( '90px' ) ); + objectLeftRow.add( new UIText( strings.getKey( 'sidebar/object/left' ) ).setWidth( '90px' ) ); objectLeftRow.add( objectLeft ); container.add( objectLeftRow ); // right - var objectRightRow = new UI.Row(); - var objectRight = new UI.Number().onChange( update ); + var objectRightRow = new UIRow(); + var objectRight = new UINumber().onChange( update ); - objectRightRow.add( new UI.Text( strings.getKey( 'sidebar/object/right' ) ).setWidth( '90px' ) ); + objectRightRow.add( new UIText( strings.getKey( 'sidebar/object/right' ) ).setWidth( '90px' ) ); objectRightRow.add( objectRight ); container.add( objectRightRow ); // top - var objectTopRow = new UI.Row(); - var objectTop = new UI.Number().onChange( update ); + var objectTopRow = new UIRow(); + var objectTop = new UINumber().onChange( update ); - objectTopRow.add( new UI.Text( strings.getKey( 'sidebar/object/top' ) ).setWidth( '90px' ) ); + objectTopRow.add( new UIText( strings.getKey( 'sidebar/object/top' ) ).setWidth( '90px' ) ); objectTopRow.add( objectTop ); container.add( objectTopRow ); // bottom - var objectBottomRow = new UI.Row(); - var objectBottom = new UI.Number().onChange( update ); + var objectBottomRow = new UIRow(); + var objectBottom = new UINumber().onChange( update ); - objectBottomRow.add( new UI.Text( strings.getKey( 'sidebar/object/bottom' ) ).setWidth( '90px' ) ); + objectBottomRow.add( new UIText( strings.getKey( 'sidebar/object/bottom' ) ).setWidth( '90px' ) ); objectBottomRow.add( objectBottom ); container.add( objectBottomRow ); // near - var objectNearRow = new UI.Row(); - var objectNear = new UI.Number().onChange( update ); + var objectNearRow = new UIRow(); + var objectNear = new UINumber().onChange( update ); - objectNearRow.add( new UI.Text( strings.getKey( 'sidebar/object/near' ) ).setWidth( '90px' ) ); + objectNearRow.add( new UIText( strings.getKey( 'sidebar/object/near' ) ).setWidth( '90px' ) ); objectNearRow.add( objectNear ); container.add( objectNearRow ); // far - var objectFarRow = new UI.Row(); - var objectFar = new UI.Number().onChange( update ); + var objectFarRow = new UIRow(); + var objectFar = new UINumber().onChange( update ); - objectFarRow.add( new UI.Text( strings.getKey( 'sidebar/object/far' ) ).setWidth( '90px' ) ); + objectFarRow.add( new UIText( strings.getKey( 'sidebar/object/far' ) ).setWidth( '90px' ) ); objectFarRow.add( objectFar ); container.add( objectFarRow ); // intensity - var objectIntensityRow = new UI.Row(); - var objectIntensity = new UI.Number().setRange( 0, Infinity ).onChange( update ); + var objectIntensityRow = new UIRow(); + var objectIntensity = new UINumber().setRange( 0, Infinity ).onChange( update ); - objectIntensityRow.add( new UI.Text( strings.getKey( 'sidebar/object/intensity' ) ).setWidth( '90px' ) ); + objectIntensityRow.add( new UIText( strings.getKey( 'sidebar/object/intensity' ) ).setWidth( '90px' ) ); objectIntensityRow.add( objectIntensity ); container.add( objectIntensityRow ); // color - var objectColorRow = new UI.Row(); - var objectColor = new UI.Color().onChange( update ); + var objectColorRow = new UIRow(); + var objectColor = new UIColor().onChange( update ); - objectColorRow.add( new UI.Text( strings.getKey( 'sidebar/object/color' ) ).setWidth( '90px' ) ); + objectColorRow.add( new UIText( strings.getKey( 'sidebar/object/color' ) ).setWidth( '90px' ) ); objectColorRow.add( objectColor ); container.add( objectColorRow ); // ground color - var objectGroundColorRow = new UI.Row(); - var objectGroundColor = new UI.Color().onChange( update ); + var objectGroundColorRow = new UIRow(); + var objectGroundColor = new UIColor().onChange( update ); - objectGroundColorRow.add( new UI.Text( strings.getKey( 'sidebar/object/groundcolor' ) ).setWidth( '90px' ) ); + objectGroundColorRow.add( new UIText( strings.getKey( 'sidebar/object/groundcolor' ) ).setWidth( '90px' ) ); objectGroundColorRow.add( objectGroundColor ); container.add( objectGroundColorRow ); // distance - var objectDistanceRow = new UI.Row(); - var objectDistance = new UI.Number().setRange( 0, Infinity ).onChange( update ); + var objectDistanceRow = new UIRow(); + var objectDistance = new UINumber().setRange( 0, Infinity ).onChange( update ); - objectDistanceRow.add( new UI.Text( strings.getKey( 'sidebar/object/distance' ) ).setWidth( '90px' ) ); + objectDistanceRow.add( new UIText( strings.getKey( 'sidebar/object/distance' ) ).setWidth( '90px' ) ); objectDistanceRow.add( objectDistance ); container.add( objectDistanceRow ); // angle - var objectAngleRow = new UI.Row(); - var objectAngle = new UI.Number().setPrecision( 3 ).setRange( 0, Math.PI / 2 ).onChange( update ); + var objectAngleRow = new UIRow(); + var objectAngle = new UINumber().setPrecision( 3 ).setRange( 0, Math.PI / 2 ).onChange( update ); - objectAngleRow.add( new UI.Text( strings.getKey( 'sidebar/object/angle' ) ).setWidth( '90px' ) ); + objectAngleRow.add( new UIText( strings.getKey( 'sidebar/object/angle' ) ).setWidth( '90px' ) ); objectAngleRow.add( objectAngle ); container.add( objectAngleRow ); // penumbra - var objectPenumbraRow = new UI.Row(); - var objectPenumbra = new UI.Number().setRange( 0, 1 ).onChange( update ); + var objectPenumbraRow = new UIRow(); + var objectPenumbra = new UINumber().setRange( 0, 1 ).onChange( update ); - objectPenumbraRow.add( new UI.Text( strings.getKey( 'sidebar/object/penumbra' ) ).setWidth( '90px' ) ); + objectPenumbraRow.add( new UIText( strings.getKey( 'sidebar/object/penumbra' ) ).setWidth( '90px' ) ); objectPenumbraRow.add( objectPenumbra ); container.add( objectPenumbraRow ); // decay - var objectDecayRow = new UI.Row(); - var objectDecay = new UI.Number().setRange( 0, Infinity ).onChange( update ); + var objectDecayRow = new UIRow(); + var objectDecay = new UINumber().setRange( 0, Infinity ).onChange( update ); - objectDecayRow.add( new UI.Text( strings.getKey( 'sidebar/object/decay' ) ).setWidth( '90px' ) ); + objectDecayRow.add( new UIText( strings.getKey( 'sidebar/object/decay' ) ).setWidth( '90px' ) ); objectDecayRow.add( objectDecay ); container.add( objectDecayRow ); // shadow - var objectShadowRow = new UI.Row(); + var objectShadowRow = new UIRow(); - objectShadowRow.add( new UI.Text( strings.getKey( 'sidebar/object/shadow' ) ).setWidth( '90px' ) ); + objectShadowRow.add( new UIText( strings.getKey( 'sidebar/object/shadow' ) ).setWidth( '90px' ) ); - var objectCastShadow = new UI.THREE.Boolean( false, strings.getKey( 'sidebar/object/cast' ) ).onChange( update ); + var objectCastShadow = new UIBoolean( false, strings.getKey( 'sidebar/object/cast' ) ).onChange( update ); objectShadowRow.add( objectCastShadow ); - var objectReceiveShadow = new UI.THREE.Boolean( false, strings.getKey( 'sidebar/object/receive' ) ).onChange( update ); + var objectReceiveShadow = new UIBoolean( false, strings.getKey( 'sidebar/object/receive' ) ).onChange( update ); objectShadowRow.add( objectReceiveShadow ); - var objectShadowRadius = new UI.Number( 1 ).onChange( update ); + var objectShadowRadius = new UINumber( 1 ).onChange( update ); objectShadowRow.add( objectShadowRadius ); container.add( objectShadowRow ); // visible - var objectVisibleRow = new UI.Row(); - var objectVisible = new UI.Checkbox().onChange( update ); + var objectVisibleRow = new UIRow(); + var objectVisible = new UICheckbox().onChange( update ); - objectVisibleRow.add( new UI.Text( strings.getKey( 'sidebar/object/visible' ) ).setWidth( '90px' ) ); + objectVisibleRow.add( new UIText( strings.getKey( 'sidebar/object/visible' ) ).setWidth( '90px' ) ); objectVisibleRow.add( objectVisible ); container.add( objectVisibleRow ); // frustumCulled - var objectFrustumCulledRow = new UI.Row(); - var objectFrustumCulled = new UI.Checkbox().onChange( update ); + var objectFrustumCulledRow = new UIRow(); + var objectFrustumCulled = new UICheckbox().onChange( update ); - objectFrustumCulledRow.add( new UI.Text( strings.getKey( 'sidebar/object/frustumcull' ) ).setWidth( '90px' ) ); + objectFrustumCulledRow.add( new UIText( strings.getKey( 'sidebar/object/frustumcull' ) ).setWidth( '90px' ) ); objectFrustumCulledRow.add( objectFrustumCulled ); container.add( objectFrustumCulledRow ); // renderOrder - var objectRenderOrderRow = new UI.Row(); - var objectRenderOrder = new UI.Integer().setWidth( '50px' ).onChange( update ); + var objectRenderOrderRow = new UIRow(); + var objectRenderOrder = new UIInteger().setWidth( '50px' ).onChange( update ); - objectRenderOrderRow.add( new UI.Text( strings.getKey( 'sidebar/object/renderorder' ) ).setWidth( '90px' ) ); + objectRenderOrderRow.add( new UIText( strings.getKey( 'sidebar/object/renderorder' ) ).setWidth( '90px' ) ); objectRenderOrderRow.add( objectRenderOrder ); container.add( objectRenderOrderRow ); // user data - var timeout; - - var objectUserDataRow = new UI.Row(); - var objectUserData = new UI.TextArea().setWidth( '150px' ).setHeight( '40px' ).setFontSize( '12px' ).onChange( update ); + var objectUserDataRow = new UIRow(); + var objectUserData = new UITextArea().setWidth( '150px' ).setHeight( '40px' ).setFontSize( '12px' ).onChange( update ); objectUserData.onKeyUp( function () { try { @@ -347,7 +357,7 @@ Sidebar.Object = function ( editor ) { } ); - objectUserDataRow.add( new UI.Text( strings.getKey( 'sidebar/object/userdata' ) ).setWidth( '90px' ) ); + objectUserDataRow.add( new UIText( strings.getKey( 'sidebar/object/userdata' ) ).setWidth( '90px' ) ); objectUserDataRow.add( objectUserData ); container.add( objectUserDataRow ); @@ -419,7 +429,7 @@ Sidebar.Object = function ( editor ) { } - var newRotation = new THREE.Euler( objectRotationX.getValue() * THREE.Math.DEG2RAD, objectRotationY.getValue() * THREE.Math.DEG2RAD, objectRotationZ.getValue() * THREE.Math.DEG2RAD ); + var newRotation = new THREE.Euler( objectRotationX.getValue() * THREE.MathUtils.DEG2RAD, objectRotationY.getValue() * THREE.MathUtils.DEG2RAD, objectRotationZ.getValue() * THREE.MathUtils.DEG2RAD ); if ( object.rotation.toVector3().distanceTo( newRotation.toVector3() ) >= 0.01 ) { editor.execute( new SetRotationCommand( editor, object, newRotation ) ); @@ -558,7 +568,7 @@ Sidebar.Object = function ( editor ) { if ( object.receiveShadow !== undefined && object.receiveShadow !== objectReceiveShadow.getValue() ) { - object.material.needsUpdate = true; + if ( object.material !== undefined ) object.material.needsUpdate = true; editor.execute( new SetValueCommand( editor, object, 'receiveShadow', objectReceiveShadow.getValue() ) ); } @@ -685,9 +695,9 @@ Sidebar.Object = function ( editor ) { objectPositionY.setValue( object.position.y ); objectPositionZ.setValue( object.position.z ); - objectRotationX.setValue( object.rotation.x * THREE.Math.RAD2DEG ); - objectRotationY.setValue( object.rotation.y * THREE.Math.RAD2DEG ); - objectRotationZ.setValue( object.rotation.z * THREE.Math.RAD2DEG ); + objectRotationX.setValue( object.rotation.x * THREE.MathUtils.RAD2DEG ); + objectRotationY.setValue( object.rotation.y * THREE.MathUtils.RAD2DEG ); + objectRotationZ.setValue( object.rotation.z * THREE.MathUtils.RAD2DEG ); objectScaleX.setValue( object.scale.x ); objectScaleY.setValue( object.scale.y ); @@ -819,3 +829,5 @@ Sidebar.Object = function ( editor ) { return container; }; + +export { SidebarObject }; diff --git a/editor/js/Sidebar.Project.js b/editor/js/Sidebar.Project.js index 9e7c82bdacf6ec..9f17aeeb1ed691 100644 --- a/editor/js/Sidebar.Project.js +++ b/editor/js/Sidebar.Project.js @@ -2,169 +2,348 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Project = function ( editor ) { +import * as THREE from '../../build/three.module.js'; + +import { UIPanel, UIRow, UIInput, UICheckbox, UIText, UIListbox, UISpan, UIButton, UISelect, UINumber } from './libs/ui.js'; +import { UIBoolean } from './libs/ui.three.js'; + +import { SetMaterialCommand } from './commands/SetMaterialCommand.js'; + +var SidebarProject = function ( editor ) { var config = editor.config; var signals = editor.signals; var strings = editor.strings; - var rendererTypes = { + var currentRenderer = null; + var currentPmremGenerator = null; - 'WebGLRenderer': THREE.WebGLRenderer, - 'SVGRenderer': THREE.SVGRenderer, - 'SoftwareRenderer': THREE.SoftwareRenderer, - 'RaytracingRenderer': THREE.RaytracingRenderer + var container = new UISpan(); - }; + var projectsettings = new UIPanel(); + projectsettings.setBorderTop( '0' ); + projectsettings.setPaddingTop( '20px' ); - var container = new UI.Panel(); - container.setBorderTop( '0' ); - container.setPaddingTop( '20px' ); + container.add( projectsettings ); // Title - var titleRow = new UI.Row(); - var title = new UI.Input( config.getKey( 'project/title' ) ).setLeft( '100px' ).onChange( function () { + var titleRow = new UIRow(); + var title = new UIInput( config.getKey( 'project/title' ) ).setLeft( '100px' ).onChange( function () { config.setKey( 'project/title', this.getValue() ); } ); - titleRow.add( new UI.Text( strings.getKey( 'sidebar/project/title' ) ).setWidth( '90px' ) ); + titleRow.add( new UIText( strings.getKey( 'sidebar/project/title' ) ).setWidth( '90px' ) ); titleRow.add( title ); - container.add( titleRow ); + projectsettings.add( titleRow ); // Editable - var editableRow = new UI.Row(); - var editable = new UI.Checkbox( config.getKey( 'project/editable' ) ).setLeft( '100px' ).onChange( function () { + var editableRow = new UIRow(); + var editable = new UICheckbox( config.getKey( 'project/editable' ) ).setLeft( '100px' ).onChange( function () { config.setKey( 'project/editable', this.getValue() ); } ); - editableRow.add( new UI.Text( strings.getKey( 'sidebar/project/editable' ) ).setWidth( '90px' ) ); + editableRow.add( new UIText( strings.getKey( 'sidebar/project/editable' ) ).setWidth( '90px' ) ); editableRow.add( editable ); - container.add( editableRow ); + projectsettings.add( editableRow ); - // VR + // WebVR - var vrRow = new UI.Row(); - var vr = new UI.Checkbox( config.getKey( 'project/vr' ) ).setLeft( '100px' ).onChange( function () { + var vrRow = new UIRow(); + var vr = new UICheckbox( config.getKey( 'project/vr' ) ).setLeft( '100px' ).onChange( function () { config.setKey( 'project/vr', this.getValue() ); } ); - vrRow.add( new UI.Text( strings.getKey( 'sidebar/project/vr' ) ).setWidth( '90px' ) ); + vrRow.add( new UIText( strings.getKey( 'sidebar/project/vr' ) ).setWidth( '90px' ) ); vrRow.add( vr ); - container.add( vrRow ); + projectsettings.add( vrRow ); // Renderer - var options = {}; + var rendererPanel = new UIPanel(); + container.add( rendererPanel ); - for ( var key in rendererTypes ) { + var headerRow = new UIRow(); + headerRow.add( new UIText( strings.getKey( 'sidebar/project/renderer' ).toUpperCase() ) ); + rendererPanel.add( headerRow ); - if ( key.indexOf( 'WebGL' ) >= 0 && System.support.webgl === false ) continue; + // Renderer / Antialias - options[ key ] = key; + var antialiasRow = new UIRow(); + var antialiasBoolean = new UIBoolean( config.getKey( 'project/renderer/antialias' ) ).onChange( function () { - } + config.setKey( 'project/renderer/antialias', this.getValue() ); + updateRenderer(); + + } ); - var rendererTypeRow = new UI.Row(); - var rendererType = new UI.Select().setOptions( options ).setWidth( '150px' ).onChange( function () { + antialiasRow.add( new UIText( strings.getKey( 'sidebar/project/antialias' ) ).setWidth( '90px' ) ); + antialiasRow.add( antialiasBoolean ); - var value = this.getValue(); + rendererPanel.add( antialiasRow ); + + // Renderer / Shadows - config.setKey( 'project/renderer', value ); + var shadowsRow = new UIRow(); + var shadowsBoolean = new UIBoolean( config.getKey( 'project/renderer/shadows' ) ).onChange( function () { + config.setKey( 'project/renderer/shadows', this.getValue() ); updateRenderer(); } ); - rendererTypeRow.add( new UI.Text( strings.getKey( 'sidebar/project/renderer' ) ).setWidth( '90px' ) ); - rendererTypeRow.add( rendererType ); + shadowsRow.add( new UIText( strings.getKey( 'sidebar/project/shadows' ) ).setWidth( '90px' ) ); + shadowsRow.add( shadowsBoolean ); - container.add( rendererTypeRow ); + rendererPanel.add( shadowsRow ); - if ( config.getKey( 'project/renderer' ) !== undefined ) { + // Renderer / Shadow Type - rendererType.setValue( config.getKey( 'project/renderer' ) ); + var shadowTypeRow = new UIRow(); + var shadowTypeSelect = new UISelect().setOptions( { + 0: 'Basic', + 1: 'PCF', + 2: 'PCF (Soft)', + // 3: 'VSM' + } ).setWidth( '150px' ).onChange( function () { - } + config.setKey( 'project/renderer/shadowType', parseFloat( this.getValue() ) ); + updateRenderer(); - // Renderer / Antialias + } ); + shadowTypeSelect.setValue( config.getKey( 'project/renderer/shadowType' ) ); - var rendererPropertiesRow = new UI.Row().setMarginLeft( '90px' ); + shadowTypeRow.add( new UIText( strings.getKey( 'sidebar/project/shadowType' ) ).setWidth( '90px' ) ); + shadowTypeRow.add( shadowTypeSelect ); - var rendererAntialias = new UI.THREE.Boolean( config.getKey( 'project/renderer/antialias' ), strings.getKey( 'sidebar/project/antialias' ) ).onChange( function () { + rendererPanel.add( shadowTypeRow ); - config.setKey( 'project/renderer/antialias', this.getValue() ); + // Renderer / Physically Correct lights + + var physicallyCorrectLightsRow = new UIRow(); + var physicallyCorrectLightsBoolean = new UIBoolean( config.getKey( 'project/renderer/physicallyCorrectLights' ) ).onChange( function () { + + config.setKey( 'project/renderer/physicallyCorrectLights', this.getValue() ); updateRenderer(); } ); - rendererPropertiesRow.add( rendererAntialias ); - // Renderer / Shadows + physicallyCorrectLightsRow.add( new UIText( strings.getKey( 'sidebar/project/physicallyCorrectLights' ) ).setWidth( '90px' ) ); + physicallyCorrectLightsRow.add( physicallyCorrectLightsBoolean ); - var rendererShadows = new UI.THREE.Boolean( config.getKey( 'project/renderer/shadows' ), strings.getKey( 'sidebar/project/shadows' ) ).onChange( function () { + rendererPanel.add( physicallyCorrectLightsRow ); - config.setKey( 'project/renderer/shadows', this.getValue() ); + // Renderer / Tonemapping + + var toneMappingRow = new UIRow(); + var toneMappingSelect = new UISelect().setOptions( { + 0: 'None', + 1: 'Linear', + 2: 'Reinhard', + 3: 'Uncharted2', + 4: 'Cineon', + 5: 'ACESFilmic', + } ).setWidth( '150px' ).onChange( function () { + + var toneMapping = parseFloat( this.getValue() ); + config.setKey( 'project/renderer/toneMapping', toneMapping ); updateRenderer(); + // WebGLRenderer.whitePoint is only relevant for Uncharted2 tonemapping + + toneMappingWhitePointRow.setDisplay( ( toneMapping === 3 ) ? 'block' : 'none' ); + + } ); + toneMappingSelect.setValue( config.getKey( 'project/renderer/toneMapping' ) ); + + toneMappingRow.add( new UIText( strings.getKey( 'sidebar/project/toneMapping' ) ).setWidth( '90px' ) ); + toneMappingRow.add( toneMappingSelect ); + + rendererPanel.add( toneMappingRow ); + + // Tonemapping / Exposure + + var toneMappingExposureRow = new UIRow(); + var toneMappingExposure = new UINumber( config.getKey( 'project/renderer/toneMappingExposure' ) ).setRange( 0, 10 ).onChange( function () { + + config.setKey( 'project/renderer/toneMappingExposure', this.getValue() ); + updateTonemapping(); + } ); - rendererPropertiesRow.add( rendererShadows ); - container.add( rendererPropertiesRow ); + toneMappingExposureRow.add( new UIText( strings.getKey( 'sidebar/project/toneMappingExposure' ) ).setWidth( '90px' ) ); + toneMappingExposureRow.add( toneMappingExposure ); + rendererPanel.add( toneMappingExposureRow ); + + // Tonemapping / White Point + + var toneMappingWhitePointRow = new UIRow(); + var toneMappingWhitePoint = new UINumber( config.getKey( 'project/renderer/toneMappingWhitePoint' ) ).setRange( 0, 10 ).onChange( function () { + + config.setKey( 'project/renderer/toneMappingWhitePoint', this.getValue() ); + updateTonemapping(); + + } ); + + toneMappingWhitePointRow.add( new UIText( strings.getKey( 'sidebar/project/toneMappingWhitePoint' ) ).setWidth( '90px' ) ); + toneMappingWhitePointRow.add( toneMappingWhitePoint ); + rendererPanel.add( toneMappingWhitePointRow ); + toneMappingWhitePointRow.setDisplay( ( config.getKey( 'project/renderer/toneMapping' ) === 3 ? 'block' : 'none' ) ); // function updateRenderer() { - createRenderer( rendererType.getValue(), rendererAntialias.getValue() ); + createRenderer( + antialiasBoolean.getValue(), + shadowsBoolean.getValue(), + shadowTypeSelect.getValue(), + toneMappingSelect.getValue(), + physicallyCorrectLightsBoolean.getValue() + ); + + } + + function createRenderer( antialias, shadows, shadowType, toneMapping, physicallyCorrectLights ) { + + var parameters = { antialias: antialias }; + + if ( currentRenderer !== null ) { + + currentRenderer.dispose(); + currentPmremGenerator.dispose(); + + } + + currentRenderer = new THREE.WebGLRenderer( parameters ); + currentPmremGenerator = new THREE.PMREMGenerator( currentRenderer ); + currentPmremGenerator.compileCubemapShader(); + currentPmremGenerator.compileEquirectangularShader(); + + if ( shadows ) { + + currentRenderer.shadowMap.enabled = true; + currentRenderer.shadowMap.type = parseFloat( shadowType ); + + } + + currentRenderer.toneMapping = parseFloat( toneMapping ); + currentRenderer.physicallyCorrectLights = physicallyCorrectLights; + + signals.rendererChanged.dispatch( currentRenderer, currentPmremGenerator ); } - function createRenderer( type, antialias, shadows ) { + function updateTonemapping() { + + currentRenderer.toneMappingExposure = toneMappingExposure.getValue(); + currentRenderer.toneMappingWhitePoint = toneMappingWhitePoint.getValue(); + + signals.rendererUpdated.dispatch(); + + } + + createRenderer( + config.getKey( 'project/renderer/antialias' ), + config.getKey( 'project/renderer/shadows' ), + config.getKey( 'project/renderer/shadowType' ), + config.getKey( 'project/renderer/toneMapping' ), + config.getKey( 'project/renderer/physicallyCorrectLights' ) + ); + + // Materials + + var materials = new UIPanel(); + + var headerRow = new UIRow(); + headerRow.add( new UIText( strings.getKey( 'sidebar/project/materials' ).toUpperCase() ) ); + + materials.add( headerRow ); + + var listbox = new UIListbox(); + materials.add( listbox ); - rendererPropertiesRow.setDisplay( type === 'WebGLRenderer' ? '' : 'none' ); + var buttonsRow = new UIRow(); + buttonsRow.setPadding( '10px 0px' ); + materials.add( buttonsRow ); - var parameters = {}; + /* + var addButton = new UI.Button().setLabel( 'Add' ).setMarginRight( '5px' ); + addButton.onClick( function () { - switch ( type ) { + editor.addMaterial( new THREE.MeshStandardMaterial() ); - case 'WebGLRenderer': - parameters.antialias = antialias; - break; + } ); + buttonsRow.add( addButton ); + */ + + var assignMaterial = new UIButton().setLabel( strings.getKey( 'sidebar/project/Assign' ) ).setMargin( '0px 5px' ); + assignMaterial.onClick( function () { + + var selectedObject = editor.selected; + + if ( selectedObject !== null ) { + + var oldMaterial = selectedObject.material; + + // only assing materials to objects with a material property (e.g. avoid assigning material to THREE.Group) + + if ( oldMaterial !== undefined ) { + + var material = editor.getMaterialById( parseInt( listbox.getValue() ) ); + + if ( material !== undefined ) { + + editor.removeMaterial( oldMaterial ); + editor.execute( new SetMaterialCommand( editor, selectedObject, material ) ); + editor.addMaterial( material ); + + } - case 'RaytracingRenderer': - parameters.workers = navigator.hardwareConcurrency || 4; - parameters.workerPath = '../examples/js/renderers/RaytracingWorker.js'; - parameters.randomize = true; - parameters.blockSize = 64; - break; + } } - var renderer = new rendererTypes[ type ]( parameters ); + } ); + buttonsRow.add( assignMaterial ); + + container.add( materials ); + + // events - if ( shadows && renderer.shadowMap ) { + signals.objectSelected.add( function ( object ) { - renderer.shadowMap.enabled = true; - // renderer.shadowMap.type = THREE.PCFSoftShadowMap; + if ( object !== null ) { + + var index = Object.values( editor.materials ).indexOf( object.material ); + listbox.selectIndex( index ); } - signals.rendererChanged.dispatch( renderer ); + } ); + + signals.materialAdded.add( refreshMaterialBrowserUI ); + signals.materialChanged.add( refreshMaterialBrowserUI ); + signals.materialRemoved.add( refreshMaterialBrowserUI ); - } + function refreshMaterialBrowserUI() { - createRenderer( config.getKey( 'project/renderer' ), config.getKey( 'project/renderer/antialias' ), config.getKey( 'project/renderer/shadows' ) ); + listbox.setItems( Object.values( editor.materials ) ); + + } return container; }; + +export { SidebarProject }; diff --git a/editor/js/Sidebar.Properties.js b/editor/js/Sidebar.Properties.js index 12fbda912cb0ef..df1d568115ae71 100644 --- a/editor/js/Sidebar.Properties.js +++ b/editor/js/Sidebar.Properties.js @@ -2,75 +2,26 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Properties = function ( editor ) { +import { UITabbedPanel } from './libs/ui.js'; - var signals = editor.signals; - var strings = editor.strings; - - var container = new UI.Span(); - - var objectTab = new UI.Text( strings.getKey( 'sidebar/properties/object' ) ).setTextTransform( 'uppercase' ); - objectTab.onClick( function () { select( 'OBJECT' ) } ); - - var geometryTab = new UI.Text( strings.getKey( 'sidebar/properties/geometry' ) ).setTextTransform( 'uppercase' ); - geometryTab.onClick( function () { select( 'GEOMETRY' ) } ); - - var materialTab = new UI.Text( strings.getKey( 'sidebar/properties/material' ) ).setTextTransform( 'uppercase' ); - materialTab.onClick( function () { select( 'MATERIAL' ) } ); - - var tabs = new UI.Div(); - tabs.setId( 'tabs' ); - tabs.add( objectTab, geometryTab, materialTab ); - container.add( tabs ); - - // - - var object = new UI.Span().add( - new Sidebar.Object( editor ) - ); - container.add( object ); +import { SidebarObject } from './Sidebar.Object.js'; +import { SidebarGeometry } from './Sidebar.Geometry.js'; +import { SidebarMaterial } from './Sidebar.Material.js'; - var geometry = new UI.Span().add( - new Sidebar.Geometry( editor ) - ); - container.add( geometry ); +var SidebarProperties = function ( editor ) { - var material = new UI.Span().add( - new Sidebar.Material( editor ) - ); - container.add( material ); - - // - - function select( section ) { - - objectTab.setClass( '' ); - geometryTab.setClass( '' ); - materialTab.setClass( '' ); - - object.setDisplay( 'none' ); - geometry.setDisplay( 'none' ); - material.setDisplay( 'none' ); - - switch ( section ) { - case 'OBJECT': - objectTab.setClass( 'selected' ); - object.setDisplay( '' ); - break; - case 'GEOMETRY': - geometryTab.setClass( 'selected' ); - geometry.setDisplay( '' ); - break; - case 'MATERIAL': - materialTab.setClass( 'selected' ); - material.setDisplay( '' ); - break; - } + var strings = editor.strings; - } + var container = new UITabbedPanel(); + container.setId( 'properties' ); - select( 'OBJECT' ); + container.addTab( 'object', strings.getKey( 'sidebar/properties/object' ), new SidebarObject( editor ) ); + container.addTab( 'geometry', strings.getKey( 'sidebar/properties/geometry' ), new SidebarGeometry( editor ) ); + container.addTab( 'material', strings.getKey( 'sidebar/properties/material' ), new SidebarMaterial( editor ) ); + container.select( 'object' ); return container; }; + +export { SidebarProperties }; diff --git a/editor/js/Sidebar.Scene.js b/editor/js/Sidebar.Scene.js index 17dcee66e3df85..ae87fe5e6a191e 100644 --- a/editor/js/Sidebar.Scene.js +++ b/editor/js/Sidebar.Scene.js @@ -2,12 +2,15 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Scene = function ( editor ) { +import { UIPanel, UIBreak, UIRow, UIColor, UISelect, UIText, UINumber } from './libs/ui.js'; +import { UIOutliner, UITexture, UICubeTexture } from './libs/ui.three.js'; + +var SidebarScene = function ( editor ) { var signals = editor.signals; var strings = editor.strings; - var container = new UI.Panel(); + var container = new UIPanel(); container.setBorderTop( '0' ); container.setPaddingTop( '20px' ); @@ -89,7 +92,7 @@ Sidebar.Scene = function ( editor ) { var ignoreObjectSelectedSignal = false; - var outliner = new UI.Outliner( editor ); + var outliner = new UIOutliner( editor ); outliner.setId( 'outliner' ); outliner.onChange( function () { @@ -106,25 +109,119 @@ Sidebar.Scene = function ( editor ) { } ); container.add( outliner ); - container.add( new UI.Break() ); + container.add( new UIBreak() ); // background function onBackgroundChanged() { - signals.sceneBackgroundChanged.dispatch( backgroundColor.getHexValue() ); + signals.sceneBackgroundChanged.dispatch( + backgroundType.getValue(), + backgroundColor.getHexValue(), + backgroundTexture.getValue(), + backgroundCubeTexture.getValue(), + backgroundEquirectTexture.getValue() + ); + + } + + function onTextureChanged( texture ) { + + texture.encoding = texture.isHDRTexture ? THREE.RGBEEncoding : THREE.sRGBEncoding; + + if ( texture.isCubeTexture && texture.isHDRTexture ) { + + texture.format = THREE.RGBAFormat; + texture.minFilter = THREE.NearestFilter; + texture.magFilter = THREE.NearestFilter; + texture.generateMipmaps = false; + + } + + onBackgroundChanged(); } - var backgroundRow = new UI.Row(); + var backgroundRow = new UIRow(); + + var backgroundType = new UISelect().setOptions( { + + 'None': 'None', + 'Color': 'Color', + 'Texture': 'Texture', + 'CubeTexture': 'CubeTexture', + 'Equirect': 'Equirect (HDR)' + + } ).setWidth( '150px' ); + backgroundType.onChange( function () { + + onBackgroundChanged(); + refreshBackgroundUI(); - var backgroundColor = new UI.Color().setValue( '#aaaaaa' ).onChange( onBackgroundChanged ); + } ); + backgroundType.setValue( 'Color' ); - backgroundRow.add( new UI.Text( strings.getKey( 'sidebar/scene/background' ) ).setWidth( '90px' ) ); - backgroundRow.add( backgroundColor ); + backgroundRow.add( new UIText( strings.getKey( 'sidebar/scene/background' ) ).setWidth( '90px' ) ); + backgroundRow.add( backgroundType ); container.add( backgroundRow ); + // + + var colorRow = new UIRow(); + colorRow.setMarginLeft( '90px' ); + + var backgroundColor = new UIColor().setValue( '#aaaaaa' ).onChange( onBackgroundChanged ); + colorRow.add( backgroundColor ); + + container.add( colorRow ); + + // + + var textureRow = new UIRow(); + textureRow.setDisplay( 'none' ); + textureRow.setMarginLeft( '90px' ); + + var backgroundTexture = new UITexture().onChange( onTextureChanged ); + textureRow.add( backgroundTexture ); + + container.add( textureRow ); + + // + + var cubeTextureRow = new UIRow(); + cubeTextureRow.setDisplay( 'none' ); + cubeTextureRow.setMarginLeft( '90px' ); + + var backgroundCubeTexture = new UICubeTexture().onChange( onTextureChanged ); + cubeTextureRow.add( backgroundCubeTexture ); + + container.add( cubeTextureRow ); + + // + + var equirectRow = new UIRow(); + equirectRow.setDisplay( 'none' ); + equirectRow.setMarginLeft( '90px' ); + + var backgroundEquirectTexture = new UITexture().onChange( onTextureChanged ); + equirectRow.add( backgroundEquirectTexture ); + + container.add( equirectRow ); + + // + + function refreshBackgroundUI() { + + var type = backgroundType.getValue(); + + colorRow.setDisplay( type === 'Color' ? '' : 'none' ); + textureRow.setDisplay( type === 'Texture' ? '' : 'none' ); + cubeTextureRow.setDisplay( type === 'CubeTexture' ? '' : 'none' ); + equirectRow.setDisplay( type === 'Equirect' ? '' : 'none' ); + + } + // fog function onFogChanged() { @@ -139,8 +236,8 @@ Sidebar.Scene = function ( editor ) { } - var fogTypeRow = new UI.Row(); - var fogType = new UI.Select().setOptions( { + var fogTypeRow = new UIRow(); + var fogType = new UISelect().setOptions( { 'None': 'None', 'Fog': 'Linear', @@ -154,35 +251,35 @@ Sidebar.Scene = function ( editor ) { } ); - fogTypeRow.add( new UI.Text( strings.getKey( 'sidebar/scene/fog' ) ).setWidth( '90px' ) ); + fogTypeRow.add( new UIText( strings.getKey( 'sidebar/scene/fog' ) ).setWidth( '90px' ) ); fogTypeRow.add( fogType ); container.add( fogTypeRow ); // fog color - var fogPropertiesRow = new UI.Row(); + var fogPropertiesRow = new UIRow(); fogPropertiesRow.setDisplay( 'none' ); fogPropertiesRow.setMarginLeft( '90px' ); container.add( fogPropertiesRow ); - var fogColor = new UI.Color().setValue( '#aaaaaa' ); + var fogColor = new UIColor().setValue( '#aaaaaa' ); fogColor.onChange( onFogChanged ); fogPropertiesRow.add( fogColor ); // fog near - var fogNear = new UI.Number( 0.1 ).setWidth( '40px' ).setRange( 0, Infinity ).onChange( onFogChanged ); + var fogNear = new UINumber( 0.1 ).setWidth( '40px' ).setRange( 0, Infinity ).onChange( onFogChanged ); fogPropertiesRow.add( fogNear ); // fog far - var fogFar = new UI.Number( 50 ).setWidth( '40px' ).setRange( 0, Infinity ).onChange( onFogChanged ); + var fogFar = new UINumber( 50 ).setWidth( '40px' ).setRange( 0, Infinity ).onChange( onFogChanged ); fogPropertiesRow.add( fogFar ); // fog density - var fogDensity = new UI.Number( 0.05 ).setWidth( '40px' ).setRange( 0, 0.1 ).setStep( 0.001 ).setPrecision( 3 ).onChange( onFogChanged ); + var fogDensity = new UINumber( 0.05 ).setWidth( '40px' ).setRange( 0, 0.1 ).setStep( 0.001 ).setPrecision( 3 ).onChange( onFogChanged ); fogPropertiesRow.add( fogDensity ); // @@ -223,7 +320,34 @@ Sidebar.Scene = function ( editor ) { if ( scene.background ) { - backgroundColor.setHexValue( scene.background.getHex() ); + if ( scene.background.isColor ) { + + backgroundType.setValue( "Color" ); + backgroundColor.setHexValue( scene.background.getHex() ); + backgroundTexture.setValue( null ); + backgroundCubeTexture.setValue( null ); + backgroundEquirectTexture.setValue( null ); + + } else if ( scene.background.isTexture && ! scene.background.isPmremTexture ) { + + backgroundType.setValue( "Texture" ); + backgroundTexture.setValue( scene.background ); + backgroundCubeTexture.setValue( null ); + backgroundEquirectTexture.setValue( null ); + + } else if ( scene.background.isCubeTexture ) { + + backgroundType.setValue( "CubeTexture" ); + backgroundCubeTexture.setValue( scene.background ); + backgroundTexture.setValue( null ); + backgroundEquirectTexture.setValue( null ); + + } + + } else { + + backgroundType.setValue( "None" ); + backgroundTexture.setValue( null ); } @@ -250,6 +374,7 @@ Sidebar.Scene = function ( editor ) { } + refreshBackgroundUI(); refreshFogUI(); } @@ -303,3 +428,5 @@ Sidebar.Scene = function ( editor ) { return container; }; + +export { SidebarScene }; diff --git a/editor/js/Sidebar.Script.js b/editor/js/Sidebar.Script.js index f6948eacd719e4..922d45110ff594 100644 --- a/editor/js/Sidebar.Script.js +++ b/editor/js/Sidebar.Script.js @@ -2,25 +2,31 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Script = function ( editor ) { +import { UIPanel, UIBreak, UIText, UIButton, UIRow, UIInput } from './libs/ui.js'; + +import { AddScriptCommand } from './commands/AddScriptCommand.js'; +import { SetScriptValueCommand } from './commands/SetScriptValueCommand.js'; +import { RemoveScriptCommand } from './commands/RemoveScriptCommand.js'; + +var SidebarScript = function ( editor ) { var strings = editor.strings; var signals = editor.signals; - var container = new UI.Panel(); + var container = new UIPanel(); container.setDisplay( 'none' ); - container.add( new UI.Text( strings.getKey( 'sidebar/script' ) ).setTextTransform( 'uppercase' ) ); - container.add( new UI.Break() ); - container.add( new UI.Break() ); + container.add( new UIText( strings.getKey( 'sidebar/script' ) ).setTextTransform( 'uppercase' ) ); + container.add( new UIBreak() ); + container.add( new UIBreak() ); // - var scriptsContainer = new UI.Row(); + var scriptsContainer = new UIRow(); container.add( scriptsContainer ); - var newScript = new UI.Button( strings.getKey( 'sidebar/script/new' ) ); + var newScript = new UIButton( strings.getKey( 'sidebar/script/new' ) ); newScript.onClick( function () { var script = { name: '', source: 'function update( event ) {}' }; @@ -60,7 +66,7 @@ Sidebar.Script = function ( editor ) { ( function ( object, script ) { - var name = new UI.Input( script.name ).setWidth( '130px' ).setFontSize( '12px' ); + var name = new UIInput( script.name ).setWidth( '130px' ).setFontSize( '12px' ); name.onChange( function () { editor.execute( new SetScriptValueCommand( editor, editor.selected, script, 'name', this.getValue() ) ); @@ -68,7 +74,7 @@ Sidebar.Script = function ( editor ) { } ); scriptsContainer.add( name ); - var edit = new UI.Button( strings.getKey( 'sidebar/script/edit' ) ); + var edit = new UIButton( strings.getKey( 'sidebar/script/edit' ) ); edit.setMarginLeft( '4px' ); edit.onClick( function () { @@ -77,7 +83,7 @@ Sidebar.Script = function ( editor ) { } ); scriptsContainer.add( edit ); - var remove = new UI.Button( strings.getKey( 'sidebar/script/remove' ) ); + var remove = new UIButton( strings.getKey( 'sidebar/script/remove' ) ); remove.setMarginLeft( '4px' ); remove.onClick( function () { @@ -90,9 +96,9 @@ Sidebar.Script = function ( editor ) { } ); scriptsContainer.add( remove ); - scriptsContainer.add( new UI.Break() ); + scriptsContainer.add( new UIBreak() ); - } )( object, scripts[ i ] ) + } )( object, scripts[ i ] ); } @@ -125,3 +131,5 @@ Sidebar.Script = function ( editor ) { return container; }; + +export { SidebarScript }; diff --git a/editor/js/Sidebar.Settings.Shortcuts.js b/editor/js/Sidebar.Settings.Shortcuts.js index bf77239ab9efa6..da916a5d4ed244 100644 --- a/editor/js/Sidebar.Settings.Shortcuts.js +++ b/editor/js/Sidebar.Settings.Shortcuts.js @@ -2,7 +2,11 @@ * @author TyLindberg / https://github.com/TyLindberg */ -Sidebar.Settings.Shortcuts = function ( editor ) { +import { UIDiv, UIBreak, UIText, UIRow, UIInput } from './libs/ui.js'; + +import { RemoveObjectCommand } from './commands/RemoveObjectCommand.js'; + +var SidebarSettingsShortcuts = function ( editor ) { var strings = editor.strings; @@ -17,17 +21,17 @@ Sidebar.Settings.Shortcuts = function ( editor ) { var config = editor.config; var signals = editor.signals; - var container = new UI.Div(); - container.add( new UI.Break() ); + var container = new UIDiv(); + container.add( new UIBreak() ); var shortcuts = [ 'translate', 'rotate', 'scale', 'undo', 'focus' ]; function createShortcutInput( name ) { var configName = 'settings/shortcuts/' + name; - var shortcutRow = new UI.Row(); + var shortcutRow = new UIRow(); - var shortcutInput = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ); + var shortcutInput = new UIInput().setWidth( '150px' ).setFontSize( '12px' ); shortcutInput.setTextTransform( 'lowercase' ); shortcutInput.onChange( function () { @@ -78,7 +82,7 @@ Sidebar.Settings.Shortcuts = function ( editor ) { } shortcutInput.dom.maxLength = 1; - shortcutRow.add( new UI.Text( strings.getKey( 'sidebar/settings/shortcuts/' + name ) ).setTextTransform( 'capitalize' ).setWidth( '90px' ) ); + shortcutRow.add( new UIText( strings.getKey( 'sidebar/settings/shortcuts/' + name ) ).setTextTransform( 'capitalize' ).setWidth( '90px' ) ); shortcutRow.add( shortcutInput ); container.add( shortcutRow ); @@ -167,3 +171,5 @@ Sidebar.Settings.Shortcuts = function ( editor ) { return container; }; + +export { SidebarSettingsShortcuts }; diff --git a/editor/js/Sidebar.Settings.Viewport.js b/editor/js/Sidebar.Settings.Viewport.js index 2cfbecd27eb995..38f35a1382dde0 100644 --- a/editor/js/Sidebar.Settings.Viewport.js +++ b/editor/js/Sidebar.Settings.Viewport.js @@ -2,17 +2,21 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Settings.Viewport = function ( editor ) { +import { UIDiv, UIBreak, UIText } from './libs/ui.js'; +import { UIBoolean } from './libs/ui.three.js'; + + +var SidebarSettingsViewport = function ( editor ) { var signals = editor.signals; var strings = editor.strings; - var container = new UI.Div(); - container.add( new UI.Break() ); + var container = new UIDiv(); + container.add( new UIBreak() ); - container.add( new UI.Text( strings.getKey( 'sidebar/settings/viewport/grid' ) ).setWidth( '90px' ) ); + container.add( new UIText( strings.getKey( 'sidebar/settings/viewport/grid' ) ).setWidth( '90px' ) ); - var show = new UI.THREE.Boolean( true ).onChange( update ); + var show = new UIBoolean( true ).onChange( update ); container.add( show ); /* @@ -34,3 +38,5 @@ Sidebar.Settings.Viewport = function ( editor ) { return container; }; + +export { SidebarSettingsViewport }; diff --git a/editor/js/Sidebar.Settings.js b/editor/js/Sidebar.Settings.js index 1b4fe1ce17a800..4d15aea1c5ba43 100644 --- a/editor/js/Sidebar.Settings.js +++ b/editor/js/Sidebar.Settings.js @@ -2,13 +2,17 @@ * @author mrdoob / http://mrdoob.com/ */ -Sidebar.Settings = function ( editor ) { +import { UIPanel, UIRow, UISelect, UIText, UIInteger } from './libs/ui.js'; + +import { SidebarSettingsViewport } from './Sidebar.Settings.Viewport.js'; +import { SidebarSettingsShortcuts } from './Sidebar.Settings.Shortcuts.js'; + +var SidebarSettings = function ( editor ) { var config = editor.config; - var signals = editor.signals; var strings = editor.strings; - var container = new UI.Panel(); + var container = new UIPanel(); container.setBorderTop( '0' ); container.setPaddingTop( '20px' ); container.setPaddingBottom( '20px' ); @@ -20,8 +24,8 @@ Sidebar.Settings = function ( editor ) { zh: '中文' }; - var languageRow = new UI.Row(); - var language = new UI.Select().setWidth( '150px' ); + var languageRow = new UIRow(); + var language = new UISelect().setWidth( '150px' ); language.setOptions( options ); if ( config.getKey( 'language' ) !== undefined ) { @@ -38,45 +42,36 @@ Sidebar.Settings = function ( editor ) { } ); - languageRow.add( new UI.Text( strings.getKey( 'sidebar/settings/language' ) ).setWidth( '90px' ) ); + languageRow.add( new UIText( strings.getKey( 'sidebar/settings/language' ) ).setWidth( '90px' ) ); languageRow.add( language ); container.add( languageRow ); - // theme - - var options = { - 'css/light.css': strings.getKey( 'sidebar/settings/theme/light' ), - 'css/dark.css': strings.getKey( 'sidebar/settings/theme/dark' ) - }; - - var themeRow = new UI.Row(); - var theme = new UI.Select().setWidth( '150px' ); - theme.setOptions( options ); + // export precision - if ( config.getKey( 'theme' ) !== undefined ) { + var exportPrecisionRow = new UIRow(); + var exportPrecision = new UIInteger( config.getKey( 'exportPrecision' ) ).setRange( 2, Infinity ); - theme.setValue( config.getKey( 'theme' ) ); - - } - - theme.onChange( function () { + exportPrecision.onChange( function () { var value = this.getValue(); - editor.setTheme( value ); - editor.config.setKey( 'theme', value ); + editor.config.setKey( 'exportPrecision', value ); } ); - themeRow.add( new UI.Text( strings.getKey( 'sidebar/settings/theme' ) ).setWidth( '90px' ) ); - themeRow.add( theme ); + exportPrecisionRow.add( new UIText( strings.getKey( 'sidebar/settings/exportPrecision' ) ).setWidth( '90px' ) ); + exportPrecisionRow.add( exportPrecision ); - container.add( themeRow ); + container.add( exportPrecisionRow ); - container.add( new Sidebar.Settings.Shortcuts( editor ) ); - container.add( new Sidebar.Settings.Viewport( editor ) ); + // + + container.add( new SidebarSettingsShortcuts( editor ) ); + container.add( new SidebarSettingsViewport( editor ) ); return container; }; + +export { SidebarSettings }; diff --git a/editor/js/Sidebar.js b/editor/js/Sidebar.js index 82fa2550854b2a..8170c688b00022 100644 --- a/editor/js/Sidebar.js +++ b/editor/js/Sidebar.js @@ -2,81 +2,44 @@ * @author mrdoob / http://mrdoob.com/ */ +import { UITabbedPanel, UISpan } from './libs/ui.js'; + +import { SidebarScene } from './Sidebar.Scene.js'; +import { SidebarProperties } from './Sidebar.Properties.js'; +import { SidebarScript } from './Sidebar.Script.js'; +import { SidebarAnimation } from './Sidebar.Animation.js'; +import { SidebarProject } from './Sidebar.Project.js'; +import { SidebarHistory } from './Sidebar.History.js'; +import { SidebarSettings } from './Sidebar.Settings.js'; + var Sidebar = function ( editor ) { var strings = editor.strings; - var container = new UI.Panel(); + var container = new UITabbedPanel(); container.setId( 'sidebar' ); - // - - var sceneTab = new UI.Text( strings.getKey( 'sidebar/scene' ) ).setTextTransform( 'uppercase' ); - sceneTab.onClick( function () { select( 'SCENE' ) } ); - - var projectTab = new UI.Text( strings.getKey( 'sidebar/project' ) ).setTextTransform( 'uppercase' ); - projectTab.onClick( function () { select( 'PROJECT' ) } ); - - var settingsTab = new UI.Text( strings.getKey( 'sidebar/settings' ) ).setTextTransform( 'uppercase' ); - settingsTab.onClick( function () { select( 'SETTINGS' ) } ); - - var tabs = new UI.Div(); - tabs.setId( 'tabs' ); - tabs.add( sceneTab, projectTab, settingsTab ); - container.add( tabs ); - - // - - var scene = new UI.Span().add( - new Sidebar.Scene( editor ), - new Sidebar.Properties( editor ), - new Sidebar.Animation( editor ), - new Sidebar.Script( editor ) + var scene = new UISpan().add( + new SidebarScene( editor ), + new SidebarProperties( editor ), + new SidebarAnimation( editor ), + new SidebarScript( editor ) ); - container.add( scene ); - var project = new UI.Span().add( - new Sidebar.Project( editor ) - ); - container.add( project ); + var project = new SidebarProject( editor ); - var settings = new UI.Span().add( - new Sidebar.Settings( editor ), - new Sidebar.History( editor ) + var settings = new UISpan().add( + new SidebarSettings( editor ), + new SidebarHistory( editor ) ); - container.add( settings ); - - // - - function select( section ) { - - sceneTab.setClass( '' ); - projectTab.setClass( '' ); - settingsTab.setClass( '' ); - scene.setDisplay( 'none' ); - project.setDisplay( 'none' ); - settings.setDisplay( 'none' ); - - switch ( section ) { - case 'SCENE': - sceneTab.setClass( 'selected' ); - scene.setDisplay( '' ); - break; - case 'PROJECT': - projectTab.setClass( 'selected' ); - project.setDisplay( '' ); - break; - case 'SETTINGS': - settingsTab.setClass( 'selected' ); - settings.setDisplay( '' ); - break; - } - - } - - select( 'SCENE' ); + container.addTab( 'scene', strings.getKey( 'sidebar/scene' ), scene ); + container.addTab( 'project', strings.getKey( 'sidebar/project' ), project ); + container.addTab( 'settings', strings.getKey( 'sidebar/settings' ), settings ); + container.select( 'scene' ); return container; }; + +export { Sidebar }; diff --git a/editor/js/Storage.js b/editor/js/Storage.js index 42a9cee983177c..9b7f52c2e7df48 100644 --- a/editor/js/Storage.js +++ b/editor/js/Storage.js @@ -6,7 +6,7 @@ var Storage = function () { var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; - if ( indexedDB === undefined ) { + if ( indexedDB === undefined ) { console.warn( 'Storage: IndexedDB not available.' ); return { init: function () {}, get: function () {}, set: function () {}, clear: function () {} }; @@ -63,14 +63,14 @@ var Storage = function () { }, - set: function ( data, callback ) { + set: function ( data ) { var start = performance.now(); var transaction = database.transaction( [ 'states' ], 'readwrite' ); var objectStore = transaction.objectStore( 'states' ); var request = objectStore.put( data, 0 ); - request.onsuccess = function ( event ) { + request.onsuccess = function () { console.log( '[' + /\d\d\:\d\d\:\d\d/.exec( new Date() )[ 0 ] + ']', 'Saved state to IndexedDB. ' + ( performance.now() - start ).toFixed( 2 ) + 'ms' ); @@ -85,7 +85,7 @@ var Storage = function () { var transaction = database.transaction( [ 'states' ], 'readwrite' ); var objectStore = transaction.objectStore( 'states' ); var request = objectStore.clear(); - request.onsuccess = function ( event ) { + request.onsuccess = function () { console.log( '[' + /\d\d\:\d\d\:\d\d/.exec( new Date() )[ 0 ] + ']', 'Cleared IndexedDB.' ); @@ -96,3 +96,5 @@ var Storage = function () { }; }; + +export { Storage }; diff --git a/editor/js/Strings.js b/editor/js/Strings.js index 5d2f44f10caa76..ca80fc8572f6ae 100644 --- a/editor/js/Strings.js +++ b/editor/js/Strings.js @@ -20,6 +20,8 @@ var Strings = function ( config ) { 'menubar/file/export/glb': 'Export GLB', 'menubar/file/export/gltf': 'Export GLTF', 'menubar/file/export/obj': 'Export OBJ', + 'menubar/file/export/ply': 'Export PLY', + 'menubar/file/export/ply_binary': 'Export PLY (Binary)', 'menubar/file/export/stl': 'Export STL', 'menubar/file/export/stl_binary': 'Export STL (Binary)', 'menubar/file/publish': 'Publish', @@ -41,6 +43,7 @@ var Strings = function ( config ) { 'menubar/add/cylinder': 'Cylinder', 'menubar/add/ring': 'Ring', 'menubar/add/sphere': 'Sphere', + 'menubar/add/dodecahedron': 'Dodecahedron', 'menubar/add/icosahedron': 'Icosahedron', 'menubar/add/octahedron': 'Octahedron', 'menubar/add/tetrahedron': 'Tetrahedron', @@ -64,6 +67,11 @@ var Strings = function ( config ) { 'menubar/play/play': 'Play', 'menubar/examples': 'Examples', + 'menubar/examples/Arkanoid': 'Arkanoid', + 'menubar/examples/Camera': 'Camera', + 'menubar/examples/Particles': 'Particles', + 'menubar/examples/Pong': 'Pong', + 'menubar/examples/Shaders': 'Shaders', 'menubar/help': 'Help', 'menubar/help/source_code': 'Source Code', @@ -148,6 +156,9 @@ var Strings = function ( config ) { 'sidebar/geometry/geometry/vertices': 'Vertices', 'sidebar/geometry/geometry/faces': 'Faces', + 'sidebar/geometry/dodecahedron_geometry/radius': 'Radius', + 'sidebar/geometry/dodecahedron_geometry/detail': 'Detail', + 'sidebar/geometry/icosahedron_geometry/radius': 'Radius', 'sidebar/geometry/icosahedron_geometry/detail': 'Detail', @@ -221,22 +232,21 @@ var Strings = function ( config ) { 'sidebar/material/depthPacking': 'Depth Packing', 'sidebar/material/roughness': 'Roughness', 'sidebar/material/metalness': 'Metalness', + 'sidebar/material/sheen': 'Sheen', 'sidebar/material/emissive': 'Emissive', 'sidebar/material/specular': 'Specular', 'sidebar/material/shininess': 'Shininess', - 'sidebar/material/clearcoat': 'ClearCoat', - 'sidebar/material/clearcoatroughness': 'ClearCoat Roughness', + 'sidebar/material/clearcoat': 'Clearcoat', + 'sidebar/material/clearcoatroughness': 'Clearcoat Roughness', 'sidebar/material/vertexcolors': 'Vertex Colors', - 'sidebar/material/vertexcolors/no': 'No', - 'sidebar/material/vertexcolors/face': 'Face', - 'sidebar/material/vertexcolors/vertex': 'Vertex', + 'sidebar/material/vertextangents': 'Vertex Tangents', 'sidebar/material/skinning': 'Skinning', 'sidebar/material/matcap': 'Matcap', 'sidebar/material/map': 'Map', 'sidebar/material/alphamap': 'Alpha Map', 'sidebar/material/bumpmap': 'Bump Map', 'sidebar/material/normalmap': 'Normal Map', - 'sidebar/material/clearcoatnormalmap': 'ClearCoat Normal Map', + 'sidebar/material/clearcoatnormalmap': 'Clearcoat Normal Map', 'sidebar/material/displacemap': 'Displace Map', 'sidebar/material/roughmap': 'Rough. Map', 'sidebar/material/metalmap': 'Metal. Map', @@ -273,14 +283,19 @@ var Strings = function ( config ) { 'sidebar/project/editable': 'Editable', 'sidebar/project/vr': 'VR', 'sidebar/project/renderer': 'Renderer', - 'sidebar/project/antialias': 'antialias', - 'sidebar/project/shadows': 'shadows', + 'sidebar/project/antialias': 'Antialias', + 'sidebar/project/shadows': 'Shadows', + 'sidebar/project/shadowType': 'Shadow Type', + 'sidebar/project/physicallyCorrectLights': 'Physically correct lights', + 'sidebar/project/toneMapping': 'Tone mapping', + 'sidebar/project/toneMappingExposure': 'Exposure', + 'sidebar/project/toneMappingWhitePoint': 'White Point', + 'sidebar/project/materials': 'Materials', + 'sidebar/project/Assign': 'Assign', 'sidebar/settings': 'Settings', 'sidebar/settings/language': 'Language', - 'sidebar/settings/theme': 'Theme', - 'sidebar/settings/theme/light': 'light', - 'sidebar/settings/theme/dark': 'dark', + 'sidebar/settings/exportPrecision': 'Export Precision', 'sidebar/settings/shortcuts/translate': 'Translate', 'sidebar/settings/shortcuts/rotate': 'Rotate', @@ -290,7 +305,7 @@ var Strings = function ( config ) { 'sidebar/settings/viewport/grid': 'Grid', - 'sidebar/history/history': 'HISTORY', + 'sidebar/history': 'History', 'sidebar/history/persistent': 'persistent', 'toolbar/translate': 'Translate', @@ -300,7 +315,8 @@ var Strings = function ( config ) { 'viewport/info/objects': 'Objects', 'viewport/info/vertices': 'Vertices', - 'viewport/info/triangles': 'Triangles' + 'viewport/info/triangles': 'Triangles', + 'viewport/info/frametime': 'Frametime' }, @@ -316,6 +332,8 @@ var Strings = function ( config ) { 'menubar/file/export/glb': '导出GLB', 'menubar/file/export/gltf': '导出GLTF', 'menubar/file/export/obj': '导出OBJ', + 'menubar/file/export/ply': '导出PLY', + 'menubar/file/export/ply_binary': '导出PLY(二进制)', 'menubar/file/export/stl': '导出STL', 'menubar/file/export/stl_binary': '导出STL(二进制)', 'menubar/file/publish': '发布', @@ -337,6 +355,7 @@ var Strings = function ( config ) { 'menubar/add/cylinder': '圆柱体', 'menubar/add/ring': '环', 'menubar/add/sphere': '球体', + 'menubar/add/dodecahedron': '十二面体', 'menubar/add/icosahedron': '二十面体', 'menubar/add/octahedron': '八面体', 'menubar/add/tetrahedron': '四面体', @@ -360,6 +379,11 @@ var Strings = function ( config ) { 'menubar/play/play': '启动', 'menubar/examples': '示例', + 'menubar/examples/Arkanoid': '打砖块', + 'menubar/examples/Camera': ' 摄像机', + 'menubar/examples/Particles': '粒子', + 'menubar/examples/Pong': '乒乓球', + 'menubar/examples/Shaders': '着色器', 'menubar/help': '帮助', 'menubar/help/source_code': '源码', @@ -434,6 +458,9 @@ var Strings = function ( config ) { 'sidebar/geometry/geometry/vertices': '顶点', 'sidebar/geometry/geometry/faces': '面', + 'sidebar/geometry/dodecahedron_geometry/radius': '半径', + 'sidebar/geometry/dodecahedron_geometry/detail': '面片分段', + 'sidebar/geometry/icosahedron_geometry/radius': '半径', 'sidebar/geometry/icosahedron_geometry/detail': '面片分段', @@ -497,18 +524,16 @@ var Strings = function ( config ) { 'sidebar/material/emissive': '自发光', 'sidebar/material/specular': '高光', 'sidebar/material/shininess': '高光大小', - 'sidebar/material/clearcoat': '透明贴图', - 'sidebar/material/clearcoatroughness': '透明贴图粗糙度', + 'sidebar/material/clearcoat': '透明图层', + 'sidebar/material/clearcoatroughness': '透明图层粗糙度', 'sidebar/material/vertexcolors': '顶点颜色', - 'sidebar/material/vertexcolors/no': '无', - 'sidebar/material/vertexcolors/face': '面', - 'sidebar/material/vertexcolors/vertex': '顶点', + 'sidebar/material/vertextangents': 'Vertex Tangents', 'sidebar/material/skinning': '皮肤', 'sidebar/material/map': '贴图', 'sidebar/material/alphamap': '透明贴图', 'sidebar/material/bumpmap': '凹凸贴图', 'sidebar/material/normalmap': '法线贴图', - 'sidebar/material/clearcoatnormalmap': 'ClearCoat Normal Map', + 'sidebar/material/clearcoatnormalmap': '透明图层法线贴图', 'sidebar/material/displacemap': '置换贴图', 'sidebar/material/roughmap': '粗糙贴图', 'sidebar/material/metalmap': '金属贴图', @@ -546,12 +571,17 @@ var Strings = function ( config ) { 'sidebar/project/renderer': '渲染器', 'sidebar/project/antialias': '抗锯齿', 'sidebar/project/shadows': '阴影', + 'sidebar/project/shadowType': '阴影类型', + 'sidebar/project/physicallyCorrectLights': '物理光照', + 'sidebar/project/toneMapping': '色调映射', + 'sidebar/project/toneMappingExposure': '曝光', + 'sidebar/project/toneMappingWhitePoint': '白点', + 'sidebar/project/materials': '材质', + 'sidebar/project/Assign': '应用', 'sidebar/settings': '设置', 'sidebar/settings/language': '语言', - 'sidebar/settings/theme': '主题', - 'sidebar/settings/theme/light': '浅色', - 'sidebar/settings/theme/dark': '深色', + 'sidebar/settings/exportPrecision': 'Export Precision', 'sidebar/settings/shortcuts/translate': '移动', 'sidebar/settings/shortcuts/rotate': '旋转', @@ -561,7 +591,7 @@ var Strings = function ( config ) { 'sidebar/settings/viewport/grid': '网格', - 'sidebar/history/history': '历史记录', + 'sidebar/history': '历史记录', 'sidebar/history/persistent': '本地存储', 'toolbar/translate': '移动', @@ -571,7 +601,8 @@ var Strings = function ( config ) { 'viewport/info/objects': '物体', 'viewport/info/vertices': '顶点', - 'viewport/info/triangles': '三角形' + 'viewport/info/triangles': '三角形', + 'viewport/info/frametime': '帧时' } @@ -588,3 +619,5 @@ var Strings = function ( config ) { }; }; + +export { Strings }; diff --git a/editor/js/Toolbar.js b/editor/js/Toolbar.js index 0c31a45b8154ee..303c8f9b852bd8 100644 --- a/editor/js/Toolbar.js +++ b/editor/js/Toolbar.js @@ -2,21 +2,24 @@ * @author mrdoob / http://mrdoob.com/ */ +import { UIPanel, UIButton } from './libs/ui.js'; +import { UIBoolean } from './libs/ui.three.js'; + var Toolbar = function ( editor ) { var signals = editor.signals; var strings = editor.strings; - var container = new UI.Panel(); + var container = new UIPanel(); container.setId( 'toolbar' ); container.setDisplay( 'none' ); - var buttons = new UI.Panel(); + var buttons = new UIPanel(); container.add( buttons ); // translate / rotate / scale - var translate = new UI.Button( strings.getKey( 'toolbar/translate' ) ); + var translate = new UIButton( strings.getKey( 'toolbar/translate' ) ); translate.dom.className = 'Button selected'; translate.onClick( function () { @@ -25,7 +28,7 @@ var Toolbar = function ( editor ) { } ); buttons.add( translate ); - var rotate = new UI.Button( strings.getKey( 'toolbar/rotate' ) ); + var rotate = new UIButton( strings.getKey( 'toolbar/rotate' ) ); rotate.onClick( function () { signals.transformModeChanged.dispatch( 'rotate' ); @@ -33,7 +36,7 @@ var Toolbar = function ( editor ) { } ); buttons.add( rotate ); - var scale = new UI.Button( strings.getKey( 'toolbar/scale' ) ); + var scale = new UIButton( strings.getKey( 'toolbar/scale' ) ); scale.onClick( function () { signals.transformModeChanged.dispatch( 'scale' ); @@ -41,7 +44,7 @@ var Toolbar = function ( editor ) { } ); buttons.add( scale ); - var local = new UI.THREE.Boolean( false, strings.getKey( 'toolbar/local' ) ); + var local = new UIBoolean( false, strings.getKey( 'toolbar/local' ) ); local.onChange( function () { signals.spaceChanged.dispatch( this.getValue() === true ? 'local' : 'world' ); @@ -76,3 +79,5 @@ var Toolbar = function ( editor ) { return container; }; + +export { Toolbar }; diff --git a/editor/js/Viewport.Camera.js b/editor/js/Viewport.Camera.js index c8f0f5c521688e..f7b77663d4c0b6 100644 --- a/editor/js/Viewport.Camera.js +++ b/editor/js/Viewport.Camera.js @@ -2,13 +2,15 @@ * @author mrdoob / http://mrdoob.com/ */ -Viewport.Camera = function ( editor ) { +import { UISelect } from './libs/ui.js'; + +var ViewportCamera = function ( editor ) { var signals = editor.signals; // - var cameraSelect = new UI.Select(); + var cameraSelect = new UISelect(); cameraSelect.setPosition( 'absolute' ); cameraSelect.setRight( '10px' ); cameraSelect.setTop( '10px' ); @@ -46,3 +48,5 @@ Viewport.Camera = function ( editor ) { return cameraSelect; }; + +export { ViewportCamera }; diff --git a/editor/js/Viewport.Info.js b/editor/js/Viewport.Info.js index dc5fe7b2984749..210ab5465a8073 100644 --- a/editor/js/Viewport.Info.js +++ b/editor/js/Viewport.Info.js @@ -2,12 +2,14 @@ * @author mrdoob / http://mrdoob.com/ */ -Viewport.Info = function ( editor ) { +import { UIPanel, UIBreak, UIText } from './libs/ui.js'; + +var ViewportInfo = function ( editor ) { var signals = editor.signals; var strings = editor.strings; - var container = new UI.Panel(); + var container = new UIPanel(); container.setId( 'info' ); container.setPosition( 'absolute' ); container.setLeft( '10px' ); @@ -15,16 +17,19 @@ Viewport.Info = function ( editor ) { container.setFontSize( '12px' ); container.setColor( '#fff' ); - var objectsText = new UI.Text( '0' ).setMarginLeft( '6px' ); - var verticesText = new UI.Text( '0' ).setMarginLeft( '6px' ); - var trianglesText = new UI.Text( '0' ).setMarginLeft( '6px' ); + var objectsText = new UIText( '0' ).setMarginLeft( '6px' ); + var verticesText = new UIText( '0' ).setMarginLeft( '6px' ); + var trianglesText = new UIText( '0' ).setMarginLeft( '6px' ); + var frametimeText = new UIText( '0' ).setMarginLeft( '6px' ); - container.add( new UI.Text( strings.getKey( 'viewport/info/objects' ) ).setTextTransform( 'lowercase' ) ); - container.add( objectsText, new UI.Break() ); - container.add( new UI.Text( strings.getKey( 'viewport/info/vertices' ) ).setTextTransform( 'lowercase' ) ); - container.add( verticesText, new UI.Break() ); - container.add( new UI.Text( strings.getKey( 'viewport/info/triangles' ) ).setTextTransform( 'lowercase' ) ); - container.add( trianglesText, new UI.Break() ); + container.add( new UIText( strings.getKey( 'viewport/info/objects' ) ).setTextTransform( 'lowercase' ) ); + container.add( objectsText, new UIBreak() ); + container.add( new UIText( strings.getKey( 'viewport/info/vertices' ) ).setTextTransform( 'lowercase' ) ); + container.add( verticesText, new UIBreak() ); + container.add( new UIText( strings.getKey( 'viewport/info/triangles' ) ).setTextTransform( 'lowercase' ) ); + container.add( trianglesText, new UIBreak() ); + container.add( new UIText( strings.getKey( 'viewport/info/frametime' ) ).setTextTransform( 'lowercase' ) ); + container.add( frametimeText, new UIBreak() ); signals.objectAdded.add( update ); signals.objectRemoved.add( update ); @@ -83,6 +88,16 @@ Viewport.Info = function ( editor ) { } + signals.sceneRendered.add( updateFrametime ); + + function updateFrametime( frametime ) { + + frametimeText.setValue( Number( frametime ).toFixed( 2 ) + " ms" ); + + } + return container; }; + +export { ViewportInfo }; diff --git a/editor/js/Viewport.js b/editor/js/Viewport.js index 085f384042d32e..82f07fea19b4a3 100644 --- a/editor/js/Viewport.js +++ b/editor/js/Viewport.js @@ -2,20 +2,36 @@ * @author mrdoob / http://mrdoob.com/ */ +import * as THREE from '../../build/three.module.js'; + +import { TransformControls } from '../../examples/jsm/controls/TransformControls.js'; + +import { UIPanel } from './libs/ui.js'; + +import { EditorControls } from './EditorControls.js'; + +import { ViewportCamera } from './Viewport.Camera.js'; +import { ViewportInfo } from './Viewport.Info.js'; + +import { SetPositionCommand } from './commands/SetPositionCommand.js'; +import { SetRotationCommand } from './commands/SetRotationCommand.js'; +import { SetScaleCommand } from './commands/SetScaleCommand.js'; + var Viewport = function ( editor ) { var signals = editor.signals; - var container = new UI.Panel(); + var container = new UIPanel(); container.setId( 'viewport' ); container.setPosition( 'absolute' ); - container.add( new Viewport.Camera( editor ) ); - container.add( new Viewport.Info( editor ) ); + container.add( new ViewportCamera( editor ) ); + container.add( new ViewportInfo( editor ) ); // var renderer = null; + var pmremGenerator = null; var camera = editor.camera; var scene = editor.scene; @@ -54,7 +70,7 @@ var Viewport = function ( editor ) { var objectRotationOnDown = null; var objectScaleOnDown = null; - var transformControls = new THREE.TransformControls( camera, container.dom ); + var transformControls = new TransformControls( camera, container.dom ); transformControls.addEventListener( 'change', function () { var object = transformControls.object; @@ -63,9 +79,11 @@ var Viewport = function ( editor ) { selectionBox.setFromObject( object ); - if ( editor.helpers[ object.id ] !== undefined ) { + var helper = editor.helpers[ object.id ]; - editor.helpers[ object.id ].update(); + if ( helper !== undefined && helper.isSkeletonHelper !== true ) { + + helper.update(); } @@ -267,7 +285,7 @@ var Viewport = function ( editor ) { // controls need to be added *after* main logic, // otherwise controls.enabled doesn't work. - var controls = new THREE.EditorControls( camera, container.dom ); + var controls = new EditorControls( camera, container.dom ); controls.addEventListener( 'change', function () { signals.cameraChanged.dispatch( camera ); @@ -279,6 +297,8 @@ var Viewport = function ( editor ) { signals.editorCleared.add( function () { controls.center.set( 0, 0, 0 ); + currentBackgroundType = null; + currentFogType = null; render(); } ); @@ -301,7 +321,13 @@ var Viewport = function ( editor ) { } ); - signals.rendererChanged.add( function ( newRenderer ) { + signals.rendererUpdated.add( function () { + + render(); + + } ); + + signals.rendererChanged.add( function ( newRenderer, newPmremGenerator ) { if ( renderer !== null ) { @@ -310,10 +336,11 @@ var Viewport = function ( editor ) { } renderer = newRenderer; + pmremGenerator = newPmremGenerator; renderer.autoClear = false; renderer.autoUpdateScene = false; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight ); @@ -440,22 +467,85 @@ var Viewport = function ( editor ) { } ); - signals.materialChanged.add( function ( material ) { + signals.materialChanged.add( function () { render(); } ); - // fog + // background + + var currentBackgroundType = null; + + signals.sceneBackgroundChanged.add( function ( backgroundType, backgroundColor, backgroundTexture, backgroundCubeTexture, backgroundEquirectTexture ) { + + if ( currentBackgroundType !== backgroundType ) { + + switch ( backgroundType ) { + + case 'None': + scene.background = null; + break; + case 'Color': + scene.background = new THREE.Color(); + break; + + } + + } + + if ( backgroundType === 'Color' ) { + + scene.background.set( backgroundColor ); + scene.environment = null; + + } else if ( backgroundType === 'Texture' ) { + + scene.background = backgroundTexture; + scene.environment = null; - signals.sceneBackgroundChanged.add( function ( backgroundColor ) { + } else if ( backgroundType === 'CubeTexture' ) { - scene.background.setHex( backgroundColor ); + if ( backgroundCubeTexture && backgroundCubeTexture.isHDRTexture ) { + + var texture = pmremGenerator.fromCubemap( backgroundCubeTexture ).texture; + texture.isPmremTexture = true; + + scene.background = texture; + scene.environment = texture; + + } else { + + scene.background = backgroundCubeTexture; + scene.environment = null; + + } + + } else if ( backgroundType === 'Equirect' ) { + + if ( backgroundEquirectTexture && backgroundEquirectTexture.isHDRTexture ) { + + var texture = pmremGenerator.fromEquirectangular( backgroundEquirectTexture ).texture; + texture.isPmremTexture = true; + + scene.background = texture; + scene.environment = texture; + + } else { + + scene.background = null; + scene.environment = null; + + } + + } render(); } ); + // fog + var currentFogType = null; signals.sceneFogChanged.add( function ( fogType, fogColor, fogNear, fogFar, fogDensity ) { @@ -547,9 +637,9 @@ var Viewport = function ( editor ) { // animations - var prevTime = performance.now(); + var clock = new THREE.Clock(); // only used for animations - function animate( time ) { + function animate() { requestAnimationFrame( animate ); @@ -557,37 +647,42 @@ var Viewport = function ( editor ) { if ( mixer.stats.actions.inUse > 0 ) { - mixer.update( ( time - prevTime ) / 1000 ); + mixer.update( clock.getDelta() ); render(); } - prevTime = time; - } requestAnimationFrame( animate ); // + var startTime = 0; + var endTime = 0; + function render() { + startTime = performance.now(); + scene.updateMatrixWorld(); renderer.render( scene, camera ); - if ( renderer instanceof THREE.RaytracingRenderer === false ) { + if ( camera === editor.camera ) { - if ( camera === editor.camera ) { - - sceneHelpers.updateMatrixWorld(); - renderer.render( sceneHelpers, camera ); - - } + sceneHelpers.updateMatrixWorld(); + renderer.render( sceneHelpers, camera ); } + endTime = performance.now(); + var frametime = endTime - startTime; + editor.signals.sceneRendered.dispatch( frametime ); + } return container; }; + +export { Viewport }; diff --git a/editor/js/commands/AddObjectCommand.js b/editor/js/commands/AddObjectCommand.js index 35191474833674..f6b5851834213f 100644 --- a/editor/js/commands/AddObjectCommand.js +++ b/editor/js/commands/AddObjectCommand.js @@ -3,12 +3,14 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D * @constructor */ - var AddObjectCommand = function ( editor, object ) { Command.call( this, editor ); @@ -65,3 +67,5 @@ AddObjectCommand.prototype = { } }; + +export { AddObjectCommand }; diff --git a/editor/js/commands/AddScriptCommand.js b/editor/js/commands/AddScriptCommand.js index f45735348fd047..8a24e11ba6c3e8 100644 --- a/editor/js/commands/AddScriptCommand.js +++ b/editor/js/commands/AddScriptCommand.js @@ -3,13 +3,14 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D * @param script javascript object * @constructor */ - var AddScriptCommand = function ( editor, object, script ) { Command.call( this, editor ); @@ -75,3 +76,5 @@ AddScriptCommand.prototype = { } }; + +export { AddScriptCommand }; diff --git a/editor/js/commands/Commands.js b/editor/js/commands/Commands.js new file mode 100644 index 00000000000000..40dd6ec045f27b --- /dev/null +++ b/editor/js/commands/Commands.js @@ -0,0 +1,21 @@ +export { AddObjectCommand } from './AddObjectCommand.js'; +export { AddScriptCommand } from './AddScriptCommand.js'; +export { MoveObjectCommand } from './MoveObjectCommand.js'; +export { MultiCmdsCommand } from './MultiCmdsCommand.js'; +export { RemoveObjectCommand } from './RemoveObjectCommand.js'; +export { RemoveScriptCommand } from './RemoveScriptCommand.js'; +export { SetColorCommand } from './SetColorCommand.js'; +export { SetGeometryCommand } from './SetGeometryCommand.js'; +export { SetGeometryValueCommand } from './SetGeometryValueCommand.js'; +export { SetMaterialColorCommand } from './SetMaterialColorCommand.js'; +export { SetMaterialCommand } from './SetMaterialCommand.js'; +export { SetMaterialMapCommand } from './SetMaterialMapCommand.js'; +export { SetMaterialValueCommand } from './SetMaterialValueCommand.js'; +export { SetMaterialVectorCommand } from './SetMaterialVectorCommand.js'; +export { SetPositionCommand } from './SetPositionCommand.js'; +export { SetRotationCommand } from './SetRotationCommand.js'; +export { SetScaleCommand } from './SetScaleCommand.js'; +export { SetSceneCommand } from './SetSceneCommand.js'; +export { SetScriptValueCommand } from './SetScriptValueCommand.js'; +export { SetUuidCommand } from './SetUuidCommand.js'; +export { SetValueCommand } from './SetValueCommand.js'; diff --git a/editor/js/commands/MoveObjectCommand.js b/editor/js/commands/MoveObjectCommand.js index f52fc7947db2b8..ba1cd334e7a830 100644 --- a/editor/js/commands/MoveObjectCommand.js +++ b/editor/js/commands/MoveObjectCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +12,6 @@ * @param newBefore THREE.Object3D * @constructor */ - var MoveObjectCommand = function ( editor, object, newParent, newBefore ) { Command.call( this, editor ); @@ -106,3 +107,5 @@ MoveObjectCommand.prototype = { } }; + +export { MoveObjectCommand }; diff --git a/editor/js/commands/MultiCmdsCommand.js b/editor/js/commands/MultiCmdsCommand.js index 358e8ea54453ab..7ba692cd47545c 100644 --- a/editor/js/commands/MultiCmdsCommand.js +++ b/editor/js/commands/MultiCmdsCommand.js @@ -3,12 +3,13 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param cmdArray array containing command objects * @constructor */ - var MultiCmdsCommand = function ( editor, cmdArray ) { Command.call( this, editor ); @@ -84,3 +85,5 @@ MultiCmdsCommand.prototype = { } }; + +export { MultiCmdsCommand }; diff --git a/editor/js/commands/RemoveObjectCommand.js b/editor/js/commands/RemoveObjectCommand.js index ba8d2d73ab76dd..6ec2131d79be07 100644 --- a/editor/js/commands/RemoveObjectCommand.js +++ b/editor/js/commands/RemoveObjectCommand.js @@ -3,12 +3,15 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D * @constructor */ - var RemoveObjectCommand = function ( editor, object ) { Command.call( this, editor ); @@ -30,41 +33,16 @@ RemoveObjectCommand.prototype = { execute: function () { - var scope = this.editor; - this.object.traverse( function ( child ) { - - scope.removeHelper( child ); - - } ); - - this.parent.remove( this.object ); - this.editor.select( this.parent ); - - this.editor.signals.objectRemoved.dispatch( this.object ); - this.editor.signals.sceneGraphChanged.dispatch(); + this.editor.removeObject( this.object ); + this.editor.deselect(); }, undo: function () { - var scope = this.editor; - - this.object.traverse( function ( child ) { - - if ( child.geometry !== undefined ) scope.addGeometry( child.geometry ); - if ( child.material !== undefined ) scope.addMaterial( child.material ); - - scope.addHelper( child ); - - } ); - - this.parent.children.splice( this.index, 0, this.object ); - this.object.parent = this.parent; + this.editor.addObject( this.object, this.parent, this.index ); this.editor.select( this.object ); - this.editor.signals.objectAdded.dispatch( this.object ); - this.editor.signals.sceneGraphChanged.dispatch(); - }, toJSON: function () { @@ -102,3 +80,5 @@ RemoveObjectCommand.prototype = { } }; + +export { RemoveObjectCommand }; diff --git a/editor/js/commands/RemoveScriptCommand.js b/editor/js/commands/RemoveScriptCommand.js index 1a771223842f7e..adba012ddd36b1 100644 --- a/editor/js/commands/RemoveScriptCommand.js +++ b/editor/js/commands/RemoveScriptCommand.js @@ -3,13 +3,14 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D * @param script javascript object * @constructor */ - var RemoveScriptCommand = function ( editor, object, script ) { Command.call( this, editor ); @@ -80,3 +81,5 @@ RemoveScriptCommand.prototype = { } }; + +export { RemoveScriptCommand }; diff --git a/editor/js/commands/SetColorCommand.js b/editor/js/commands/SetColorCommand.js index c4e154c7adf9f6..fcf645cf3597d7 100644 --- a/editor/js/commands/SetColorCommand.js +++ b/editor/js/commands/SetColorCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +12,6 @@ * @param newValue integer representing a hex color value * @constructor */ - var SetColorCommand = function ( editor, object, attributeName, newValue ) { Command.call( this, editor ); @@ -73,3 +74,5 @@ SetColorCommand.prototype = { } }; + +export { SetColorCommand }; diff --git a/editor/js/commands/SetGeometryCommand.js b/editor/js/commands/SetGeometryCommand.js index 9ecde6248bf7e0..243b76a53e57ca 100644 --- a/editor/js/commands/SetGeometryCommand.js +++ b/editor/js/commands/SetGeometryCommand.js @@ -3,6 +3,10 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -75,7 +79,7 @@ SetGeometryCommand.prototype = { this.oldGeometry = parseGeometry( json.oldGeometry ); this.newGeometry = parseGeometry( json.newGeometry ); - function parseGeometry ( data ) { + function parseGeometry( data ) { var loader = new THREE.ObjectLoader(); return loader.parseGeometries( [ data ] )[ data.uuid ]; @@ -85,3 +89,5 @@ SetGeometryCommand.prototype = { } }; + +export { SetGeometryCommand }; diff --git a/editor/js/commands/SetGeometryValueCommand.js b/editor/js/commands/SetGeometryValueCommand.js index b019914be4d9f6..840420663c88d4 100644 --- a/editor/js/commands/SetGeometryValueCommand.js +++ b/editor/js/commands/SetGeometryValueCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +12,6 @@ * @param newValue number, string, boolean or object * @constructor */ - var SetGeometryValueCommand = function ( editor, object, attributeName, newValue ) { Command.call( this, editor ); @@ -70,3 +71,5 @@ SetGeometryValueCommand.prototype = { } }; + +export { SetGeometryValueCommand }; diff --git a/editor/js/commands/SetMaterialColorCommand.js b/editor/js/commands/SetMaterialColorCommand.js index c4d97ad6453504..abd59cadb55f08 100644 --- a/editor/js/commands/SetMaterialColorCommand.js +++ b/editor/js/commands/SetMaterialColorCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +12,6 @@ * @param newValue integer representing a hex color value * @constructor */ - var SetMaterialColorCommand = function ( editor, object, attributeName, newValue, materialSlot ) { Command.call( this, editor ); @@ -78,3 +79,5 @@ SetMaterialColorCommand.prototype = { } }; + +export { SetMaterialColorCommand }; diff --git a/editor/js/commands/SetMaterialCommand.js b/editor/js/commands/SetMaterialCommand.js index 7852ae3d7972d9..fd7795200381ea 100644 --- a/editor/js/commands/SetMaterialCommand.js +++ b/editor/js/commands/SetMaterialCommand.js @@ -3,13 +3,16 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D * @param newMaterial THREE.Material * @constructor */ - var SetMaterialCommand = function ( editor, object, newMaterial, materialSlot ) { Command.call( this, editor ); @@ -61,11 +64,11 @@ SetMaterialCommand.prototype = { this.oldMaterial = parseMaterial( json.oldMaterial ); this.newMaterial = parseMaterial( json.newMaterial ); - function parseMaterial ( json ) { + function parseMaterial( json ) { var loader = new THREE.ObjectLoader(); var images = loader.parseImages( json.images ); - var textures = loader.parseTextures( json.textures, images ); + var textures = loader.parseTextures( json.textures, images ); var materials = loader.parseMaterials( [ json ], textures ); return materials[ json.uuid ]; @@ -74,3 +77,5 @@ SetMaterialCommand.prototype = { } }; + +export { SetMaterialCommand }; diff --git a/editor/js/commands/SetMaterialMapCommand.js b/editor/js/commands/SetMaterialMapCommand.js index 5793c675c253a2..3a2bc4302bf814 100644 --- a/editor/js/commands/SetMaterialMapCommand.js +++ b/editor/js/commands/SetMaterialMapCommand.js @@ -3,6 +3,10 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +14,6 @@ * @param newMap THREE.Texture * @constructor */ - var SetMaterialMapCommand = function ( editor, object, mapName, newMap, materialSlot ) { Command.call( this, editor ); @@ -61,7 +64,7 @@ SetMaterialMapCommand.prototype = { // serializes a map (THREE.Texture) - function serializeMap ( map ) { + function serializeMap( map ) { if ( map === null || map === undefined ) return null; @@ -86,7 +89,7 @@ SetMaterialMapCommand.prototype = { // extract data from the cache hash // remove metadata on each item // and return as array - function extractFromCache ( cache ) { + function extractFromCache( cache ) { var values = []; for ( var key in cache ) { @@ -111,14 +114,14 @@ SetMaterialMapCommand.prototype = { this.oldMap = parseTexture( json.oldMap ); this.newMap = parseTexture( json.newMap ); - function parseTexture ( json ) { + function parseTexture( json ) { var map = null; if ( json !== null ) { var loader = new THREE.ObjectLoader(); var images = loader.parseImages( json.images ); - var textures = loader.parseTextures( [ json ], images ); + var textures = loader.parseTextures( [ json ], images ); map = textures[ json.uuid ]; map.sourceFile = json.sourceFile; @@ -130,3 +133,5 @@ SetMaterialMapCommand.prototype = { } }; + +export { SetMaterialMapCommand }; diff --git a/editor/js/commands/SetMaterialValueCommand.js b/editor/js/commands/SetMaterialValueCommand.js index 6db8962bb61b1f..4597d74b7dae63 100644 --- a/editor/js/commands/SetMaterialValueCommand.js +++ b/editor/js/commands/SetMaterialValueCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +12,6 @@ * @param newValue number, string, boolean or object * @constructor */ - var SetMaterialValueCommand = function ( editor, object, attributeName, newValue, materialSlot ) { Command.call( this, editor ); @@ -82,3 +83,5 @@ SetMaterialValueCommand.prototype = { } }; + +export { SetMaterialValueCommand }; diff --git a/editor/js/commands/SetMaterialVectorCommand.js b/editor/js/commands/SetMaterialVectorCommand.js index 93185fb73496a8..e73f639443afb3 100644 --- a/editor/js/commands/SetMaterialVectorCommand.js +++ b/editor/js/commands/SetMaterialVectorCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + var SetMaterialVectorCommand = function ( editor, object, attributeName, newValue, materialSlot ) { Command.call( this, editor ); @@ -70,3 +72,5 @@ SetMaterialVectorCommand.prototype = { } }; + +export { SetMaterialVectorCommand }; diff --git a/editor/js/commands/SetPositionCommand.js b/editor/js/commands/SetPositionCommand.js index 13d1c138cf342f..96744df72f3b01 100644 --- a/editor/js/commands/SetPositionCommand.js +++ b/editor/js/commands/SetPositionCommand.js @@ -3,6 +3,10 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +14,6 @@ * @param optionalOldPosition THREE.Vector3 * @constructor */ - var SetPositionCommand = function ( editor, object, newPosition, optionalOldPosition ) { Command.call( this, editor ); @@ -82,3 +85,5 @@ SetPositionCommand.prototype = { } }; + +export { SetPositionCommand }; diff --git a/editor/js/commands/SetRotationCommand.js b/editor/js/commands/SetRotationCommand.js index 1539b08625a9d2..98ae6df74341f7 100644 --- a/editor/js/commands/SetRotationCommand.js +++ b/editor/js/commands/SetRotationCommand.js @@ -3,6 +3,10 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +14,6 @@ * @param optionalOldRotation THREE.Euler * @constructor */ - var SetRotationCommand = function ( editor, object, newRotation, optionalOldRotation ) { Command.call( this, editor ); @@ -83,3 +86,5 @@ SetRotationCommand.prototype = { } }; + +export { SetRotationCommand }; diff --git a/editor/js/commands/SetScaleCommand.js b/editor/js/commands/SetScaleCommand.js index f833ca26970119..18ede0eabb4e35 100644 --- a/editor/js/commands/SetScaleCommand.js +++ b/editor/js/commands/SetScaleCommand.js @@ -3,6 +3,10 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + +import * as THREE from '../../../build/three.module.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +14,6 @@ * @param optionalOldScale THREE.Vector3 * @constructor */ - var SetScaleCommand = function ( editor, object, newScale, optionalOldScale ) { Command.call( this, editor ); @@ -83,3 +86,5 @@ SetScaleCommand.prototype = { } }; + +export { SetScaleCommand }; diff --git a/editor/js/commands/SetSceneCommand.js b/editor/js/commands/SetSceneCommand.js index 7b5d6d3a90e870..19950fac8b139d 100644 --- a/editor/js/commands/SetSceneCommand.js +++ b/editor/js/commands/SetSceneCommand.js @@ -3,12 +3,16 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; +import { SetUuidCommand } from './SetUuidCommand.js'; +import { SetValueCommand } from './SetValueCommand.js'; +import { AddObjectCommand } from './AddObjectCommand.js'; + /** * @param editor Editor * @param scene containing children to import * @constructor */ - var SetSceneCommand = function ( editor, scene ) { Command.call( this, editor ); @@ -99,3 +103,5 @@ SetSceneCommand.prototype = { } }; + +export { SetSceneCommand }; diff --git a/editor/js/commands/SetScriptValueCommand.js b/editor/js/commands/SetScriptValueCommand.js index db79c57f2363a9..bafd06b4331c4b 100644 --- a/editor/js/commands/SetScriptValueCommand.js +++ b/editor/js/commands/SetScriptValueCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -11,7 +13,6 @@ * @param newValue string, object * @constructor */ - var SetScriptValueCommand = function ( editor, object, script, attributeName, newValue ) { Command.call( this, editor ); @@ -80,3 +81,5 @@ SetScriptValueCommand.prototype = { } }; + +export { SetScriptValueCommand }; diff --git a/editor/js/commands/SetUuidCommand.js b/editor/js/commands/SetUuidCommand.js index 6563ab412df158..18f6c6a28d349c 100644 --- a/editor/js/commands/SetUuidCommand.js +++ b/editor/js/commands/SetUuidCommand.js @@ -3,13 +3,14 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D * @param newUuid string * @constructor */ - var SetUuidCommand = function ( editor, object, newUuid ) { Command.call( this, editor ); @@ -70,3 +71,5 @@ SetUuidCommand.prototype = { } }; + +export { SetUuidCommand }; diff --git a/editor/js/commands/SetValueCommand.js b/editor/js/commands/SetValueCommand.js index 1fa2e64e98d779..cee1b76563a4e3 100644 --- a/editor/js/commands/SetValueCommand.js +++ b/editor/js/commands/SetValueCommand.js @@ -3,6 +3,8 @@ * Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch) */ +import { Command } from '../Command.js'; + /** * @param editor Editor * @param object THREE.Object3D @@ -10,7 +12,6 @@ * @param newValue number, string, boolean or object * @constructor */ - var SetValueCommand = function ( editor, object, attributeName, newValue ) { Command.call( this, editor ); @@ -75,3 +76,5 @@ SetValueCommand.prototype = { } }; + +export { SetValueCommand }; diff --git a/editor/js/libs/app.js b/editor/js/libs/app.js index 1e379cf986eaf8..f6810943d91806 100644 --- a/editor/js/libs/app.js +++ b/editor/js/libs/app.js @@ -1,3 +1,4 @@ + /** * @author mrdoob / http://mrdoob.com/ */ @@ -6,12 +7,19 @@ var APP = { Player: function () { + var renderer = new THREE.WebGLRenderer( { antialias: true } ); + renderer.setPixelRatio( window.devicePixelRatio ); + renderer.outputEncoding = THREE.sRGBEncoding; + var loader = new THREE.ObjectLoader(); - var camera, scene, renderer; + var camera, scene; + + var vrButton = VRButton.createButton( renderer ); var events = {}; var dom = document.createElement( 'div' ); + dom.appendChild( renderer.domElement ); this.dom = dom; @@ -20,17 +28,10 @@ var APP = { this.load = function ( json ) { - renderer = new THREE.WebGLRenderer( { antialias: true } ); - renderer.gammaOutput = true; - renderer.setClearColor( 0x000000 ); - renderer.setPixelRatio( window.devicePixelRatio ); - var project = json.project; - if ( project.shadows ) renderer.shadowMap.enabled = true; - if ( project.vr ) renderer.vr.enabled = true; - - dom.appendChild( renderer.domElement ); + renderer.shadowMap.enabled = project.shadows === true; + renderer.xr.enabled = project.vr === true; this.setScene( loader.parse( json.scene ) ); this.setCamera( loader.parse( json.camera ) ); @@ -110,12 +111,6 @@ var APP = { camera.aspect = this.width / this.height; camera.updateProjectionMatrix(); - if ( renderer.vr.enabled ) { - - dom.appendChild( THREE.WEBVR.createButton( renderer ) ); - - } - }; this.setScene = function ( value ) { @@ -178,6 +173,8 @@ var APP = { this.play = function () { + if ( renderer.xr.enabled ) dom.append( vrButton ); + prevTime = performance.now(); document.addEventListener( 'keydown', onDocumentKeyDown ); @@ -197,6 +194,8 @@ var APP = { this.stop = function () { + if ( renderer.xr.enabled ) vrButton.remove(); + document.removeEventListener( 'keydown', onDocumentKeyDown ); document.removeEventListener( 'keyup', onDocumentKeyUp ); document.removeEventListener( 'mousedown', onDocumentMouseDown ); @@ -214,17 +213,10 @@ var APP = { this.dispose = function () { - while ( dom.children.length ) { - - dom.removeChild( dom.firstChild ); - - } - renderer.dispose(); camera = undefined; scene = undefined; - renderer = undefined; }; @@ -281,3 +273,5 @@ var APP = { } }; + +export { APP }; diff --git a/editor/js/libs/app/index.html b/editor/js/libs/app/index.html index 025a9f301ca13e..6ce1c92e2b02a7 100644 --- a/editor/js/libs/app/index.html +++ b/editor/js/libs/app/index.html @@ -8,7 +8,7 @@ - - - - + + diff --git a/examples/js/WebGL.js b/examples/js/WebGL.js index 046fcfbcf3c150..41fd599bcebf00 100644 --- a/examples/js/WebGL.js +++ b/examples/js/WebGL.js @@ -1,6 +1,6 @@ /** * @author alteredq / http://alteredqualia.com/ - * @author mr.doob / http://mrdoob.com/ + * @author mrdoob / http://mrdoob.com/ */ THREE.WEBGL = { diff --git a/examples/js/animation/CCDIKSolver.js b/examples/js/animation/CCDIKSolver.js index c7db2cb20aa1cb..2d5853aac3a743 100644 --- a/examples/js/animation/CCDIKSolver.js +++ b/examples/js/animation/CCDIKSolver.js @@ -399,7 +399,7 @@ THREE.CCDIKSolver = ( function () { var geometry = new THREE.BufferGeometry(); var vertices = new Float32Array( ( 2 + ik.links.length ) * 3 ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); return geometry; diff --git a/examples/js/controls/DeviceOrientationControls.js b/examples/js/controls/DeviceOrientationControls.js index cb1e8b750ce2d9..b3fd5fb069c589 100644 --- a/examples/js/controls/DeviceOrientationControls.js +++ b/examples/js/controls/DeviceOrientationControls.js @@ -61,8 +61,31 @@ THREE.DeviceOrientationControls = function ( object ) { onScreenOrientationChangeEvent(); // run once on load - window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent, false ); - window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false ); + // iOS 13+ + + if ( window.DeviceOrientationEvent !== undefined && typeof window.DeviceOrientationEvent.requestPermission === 'function' ) { + + window.DeviceOrientationEvent.requestPermission().then( function ( response ) { + + if ( response == 'granted' ) { + + window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent, false ); + window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false ); + + } + + } ).catch( function ( error ) { + + console.error( 'THREE.DeviceOrientationControls: Unable to use DeviceOrientation API:', error ); + + } ); + + } else { + + window.addEventListener( 'orientationchange', onScreenOrientationChangeEvent, false ); + window.addEventListener( 'deviceorientation', onDeviceOrientationChangeEvent, false ); + + } scope.enabled = true; @@ -85,13 +108,13 @@ THREE.DeviceOrientationControls = function ( object ) { if ( device ) { - var alpha = device.alpha ? THREE.Math.degToRad( device.alpha ) + scope.alphaOffset : 0; // Z + var alpha = device.alpha ? THREE.MathUtils.degToRad( device.alpha ) + scope.alphaOffset : 0; // Z - var beta = device.beta ? THREE.Math.degToRad( device.beta ) : 0; // X' + var beta = device.beta ? THREE.MathUtils.degToRad( device.beta ) : 0; // X' - var gamma = device.gamma ? THREE.Math.degToRad( device.gamma ) : 0; // Y'' + var gamma = device.gamma ? THREE.MathUtils.degToRad( device.gamma ) : 0; // Y'' - var orient = scope.screenOrientation ? THREE.Math.degToRad( scope.screenOrientation ) : 0; // O + var orient = scope.screenOrientation ? THREE.MathUtils.degToRad( scope.screenOrientation ) : 0; // O setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient ); diff --git a/examples/js/controls/DragControls.js b/examples/js/controls/DragControls.js index 6ea844aa8d5c5b..14853002507e1d 100644 --- a/examples/js/controls/DragControls.js +++ b/examples/js/controls/DragControls.js @@ -6,13 +6,6 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) { - if ( _objects instanceof THREE.Camera ) { - - console.warn( 'THREE.DragControls: Constructor now expects ( objects, camera, domElement )' ); - var temp = _objects; _objects = _camera; _camera = temp; - - } - var _plane = new THREE.Plane(); var _raycaster = new THREE.Raycaster(); @@ -21,6 +14,7 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) { var _intersection = new THREE.Vector3(); var _worldPosition = new THREE.Vector3(); var _inverseMatrix = new THREE.Matrix4(); + var _intersections = []; var _selected = null, _hovered = null; @@ -58,6 +52,12 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) { } + function getObjects() { + + return _objects; + + } + function onDocumentMouseMove( event ) { event.preventDefault(); @@ -83,13 +83,14 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) { } - _raycaster.setFromCamera( _mouse, _camera ); + _intersections.length = 0; - var intersects = _raycaster.intersectObjects( _objects, true ); + _raycaster.setFromCamera( _mouse, _camera ); + _raycaster.intersectObjects( _objects, true, _intersections ); - if ( intersects.length > 0 ) { + if ( _intersections.length > 0 ) { - var object = intersects[ 0 ].object; + var object = _intersections[ 0 ].object; _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) ); @@ -121,13 +122,14 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) { event.preventDefault(); - _raycaster.setFromCamera( _mouse, _camera ); + _intersections.length = 0; - var intersects = _raycaster.intersectObjects( _objects, true ); + _raycaster.setFromCamera( _mouse, _camera ); + _raycaster.intersectObjects( _objects, true, _intersections ); - if ( intersects.length > 0 ) { + if ( _intersections.length > 0 ) { - _selected = intersects[ 0 ].object; + _selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object; if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { @@ -199,13 +201,14 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) { _mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1; _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; - _raycaster.setFromCamera( _mouse, _camera ); + _intersections.length = 0; - var intersects = _raycaster.intersectObjects( _objects, true ); + _raycaster.setFromCamera( _mouse, _camera ); + _raycaster.intersectObjects( _objects, true, _intersections ); - if ( intersects.length > 0 ) { + if ( _intersections.length > 0 ) { - _selected = intersects[ 0 ].object; + _selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object; _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); @@ -246,39 +249,12 @@ THREE.DragControls = function ( _objects, _camera, _domElement ) { // API this.enabled = true; + this.transformGroup = false; this.activate = activate; this.deactivate = deactivate; this.dispose = dispose; - - // Backward compatibility - - this.setObjects = function () { - - console.error( 'THREE.DragControls: setObjects() has been removed.' ); - - }; - - this.on = function ( type, listener ) { - - console.warn( 'THREE.DragControls: on() has been deprecated. Use addEventListener() instead.' ); - scope.addEventListener( type, listener ); - - }; - - this.off = function ( type, listener ) { - - console.warn( 'THREE.DragControls: off() has been deprecated. Use removeEventListener() instead.' ); - scope.removeEventListener( type, listener ); - - }; - - this.notify = function ( type ) { - - console.error( 'THREE.DragControls: notify() has been deprecated. Use dispatchEvent() instead.' ); - scope.dispatchEvent( { type: type } ); - - }; + this.getObjects = getObjects; }; diff --git a/examples/js/controls/FirstPersonControls.js b/examples/js/controls/FirstPersonControls.js index 34c25510989134..add3b027658310 100644 --- a/examples/js/controls/FirstPersonControls.js +++ b/examples/js/controls/FirstPersonControls.js @@ -6,9 +6,17 @@ THREE.FirstPersonControls = function ( object, domElement ) { + if ( domElement === undefined ) { + + console.warn( 'THREE.FirstPersonControls: The second parameter "domElement" is now mandatory.' ); + domElement = document; + + } + this.object = object; + this.domElement = domElement; - this.domElement = ( domElement !== undefined ) ? domElement : document; + // API this.enabled = true; @@ -29,6 +37,10 @@ THREE.FirstPersonControls = function ( object, domElement ) { this.verticalMin = 0; this.verticalMax = Math.PI; + this.mouseDragOn = false; + + // internals + this.autoSpeedFactor = 0.0; this.mouseX = 0; @@ -39,8 +51,6 @@ THREE.FirstPersonControls = function ( object, domElement ) { this.moveLeft = false; this.moveRight = false; - this.mouseDragOn = false; - this.viewHalfX = 0; this.viewHalfY = 0; @@ -219,7 +229,7 @@ THREE.FirstPersonControls = function ( object, domElement ) { if ( this.heightSpeed ) { - var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax ); + var y = THREE.MathUtils.clamp( this.object.position.y, this.heightMin, this.heightMax ); var heightDelta = y - this.heightMin; this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef ); @@ -262,12 +272,12 @@ THREE.FirstPersonControls = function ( object, domElement ) { lat = Math.max( - 85, Math.min( 85, lat ) ); - var phi = THREE.Math.degToRad( 90 - lat ); - var theta = THREE.Math.degToRad( lon ); + var phi = THREE.MathUtils.degToRad( 90 - lat ); + var theta = THREE.MathUtils.degToRad( lon ); if ( this.constrainVertical ) { - phi = THREE.Math.mapLinear( phi, 0, Math.PI, this.verticalMin, this.verticalMax ); + phi = THREE.MathUtils.mapLinear( phi, 0, Math.PI, this.verticalMin, this.verticalMax ); } @@ -330,8 +340,8 @@ THREE.FirstPersonControls = function ( object, domElement ) { lookDirection.set( 0, 0, - 1 ).applyQuaternion( quaternion ); spherical.setFromVector3( lookDirection ); - lat = 90 - THREE.Math.radToDeg( spherical.phi ); - lon = THREE.Math.radToDeg( spherical.theta ); + lat = 90 - THREE.MathUtils.radToDeg( spherical.phi ); + lon = THREE.MathUtils.radToDeg( spherical.theta ); } diff --git a/examples/js/controls/FlyControls.js b/examples/js/controls/FlyControls.js index 1cc6c60ebace7a..435418bb11cca4 100644 --- a/examples/js/controls/FlyControls.js +++ b/examples/js/controls/FlyControls.js @@ -4,9 +4,16 @@ THREE.FlyControls = function ( object, domElement ) { + if ( domElement === undefined ) { + + console.warn( 'THREE.FlyControls: The second parameter "domElement" is now mandatory.' ); + domElement = document; + + } + this.object = object; + this.domElement = domElement; - this.domElement = ( domElement !== undefined ) ? domElement : document; if ( domElement ) this.domElement.setAttribute( 'tabindex', - 1 ); // API diff --git a/examples/js/controls/OrbitControls.js b/examples/js/controls/OrbitControls.js index 82792fb7f78fbb..02093f4d0a8a73 100644 --- a/examples/js/controls/OrbitControls.js +++ b/examples/js/controls/OrbitControls.js @@ -16,9 +16,11 @@ THREE.OrbitControls = function ( object, domElement ) { - this.object = object; + if ( domElement === undefined ) console.warn( 'THREE.OrbitControls: The second parameter "domElement" is now mandatory.' ); + if ( domElement === document ) console.error( 'THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); - this.domElement = ( domElement !== undefined ) ? domElement : document; + this.object = object; + this.domElement = domElement; // Set to false to disable this control this.enabled = true; @@ -256,7 +258,7 @@ THREE.OrbitControls = function ( object, domElement ) { document.removeEventListener( 'mousemove', onMouseMove, false ); document.removeEventListener( 'mouseup', onMouseUp, false ); - window.removeEventListener( 'keydown', onKeyDown, false ); + scope.domElement.removeEventListener( 'keydown', onKeyDown, false ); //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? @@ -378,7 +380,7 @@ THREE.OrbitControls = function ( object, domElement ) { return function pan( deltaX, deltaY ) { - var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + var element = scope.domElement; if ( scope.object.isPerspectiveCamera ) { @@ -482,7 +484,7 @@ THREE.OrbitControls = function ( object, domElement ) { rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); - var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + var element = scope.domElement; rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height @@ -670,7 +672,7 @@ THREE.OrbitControls = function ( object, domElement ) { rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); - var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + var element = scope.domElement; rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height @@ -751,7 +753,6 @@ THREE.OrbitControls = function ( object, domElement ) { if ( scope.enabled === false ) return; // Prevent the browser from scrolling. - event.preventDefault(); // Manually set the focus since calling preventDefault above @@ -759,119 +760,90 @@ THREE.OrbitControls = function ( object, domElement ) { scope.domElement.focus ? scope.domElement.focus() : window.focus(); + var mouseAction; + switch ( event.button ) { case 0: - switch ( scope.mouseButtons.LEFT ) { - - case THREE.MOUSE.ROTATE: - - if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + mouseAction = scope.mouseButtons.LEFT; + break; - if ( scope.enablePan === false ) return; + case 1: - handleMouseDownPan( event ); + mouseAction = scope.mouseButtons.MIDDLE; + break; - state = STATE.PAN; + case 2: - } else { + mouseAction = scope.mouseButtons.RIGHT; + break; - if ( scope.enableRotate === false ) return; + default: - handleMouseDownRotate( event ); + mouseAction = - 1; - state = STATE.ROTATE; + } - } + switch ( mouseAction ) { - break; + case THREE.MOUSE.DOLLY: - case THREE.MOUSE.PAN: + if ( scope.enableZoom === false ) return; - if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + handleMouseDownDolly( event ); - if ( scope.enableRotate === false ) return; + state = STATE.DOLLY; - handleMouseDownRotate( event ); + break; - state = STATE.ROTATE; + case THREE.MOUSE.ROTATE: - } else { + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { - if ( scope.enablePan === false ) return; + if ( scope.enablePan === false ) return; - handleMouseDownPan( event ); + handleMouseDownPan( event ); - state = STATE.PAN; + state = STATE.PAN; - } + } else { - break; + if ( scope.enableRotate === false ) return; - default: + handleMouseDownRotate( event ); - state = STATE.NONE; + state = STATE.ROTATE; } break; + case THREE.MOUSE.PAN: - case 1: - - switch ( scope.mouseButtons.MIDDLE ) { - - case THREE.MOUSE.DOLLY: + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { - if ( scope.enableZoom === false ) return; + if ( scope.enableRotate === false ) return; - handleMouseDownDolly( event ); + handleMouseDownRotate( event ); - state = STATE.DOLLY; + state = STATE.ROTATE; - break; + } else { + if ( scope.enablePan === false ) return; - default: + handleMouseDownPan( event ); - state = STATE.NONE; + state = STATE.PAN; } break; - case 2: - - switch ( scope.mouseButtons.RIGHT ) { - - case THREE.MOUSE.ROTATE: - - if ( scope.enableRotate === false ) return; - - handleMouseDownRotate( event ); - - state = STATE.ROTATE; - - break; - - case THREE.MOUSE.PAN: - - if ( scope.enablePan === false ) return; - - handleMouseDownPan( event ); - - state = STATE.PAN; - - break; - - default: - - state = STATE.NONE; - - } + default: - break; + state = STATE.NONE; } @@ -964,7 +936,7 @@ THREE.OrbitControls = function ( object, domElement ) { if ( scope.enabled === false ) return; - event.preventDefault(); + event.preventDefault(); // prevent scrolling switch ( event.touches.length ) { @@ -1050,7 +1022,7 @@ THREE.OrbitControls = function ( object, domElement ) { if ( scope.enabled === false ) return; - event.preventDefault(); + event.preventDefault(); // prevent scrolling event.stopPropagation(); switch ( state ) { @@ -1134,7 +1106,15 @@ THREE.OrbitControls = function ( object, domElement ) { scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); - window.addEventListener( 'keydown', onKeyDown, false ); + scope.domElement.addEventListener( 'keydown', onKeyDown, false ); + + // make sure element can receive keys. + + if ( scope.domElement.tabIndex === - 1 ) { + + scope.domElement.tabIndex = 0; + + } // force an update at start diff --git a/examples/js/controls/OrthographicTrackballControls.js b/examples/js/controls/OrthographicTrackballControls.js deleted file mode 100644 index e4fd51720a26da..00000000000000 --- a/examples/js/controls/OrthographicTrackballControls.js +++ /dev/null @@ -1,644 +0,0 @@ -/** - * @author Eberhard Graether / http://egraether.com/ - * @author Mark Lundin / http://mark-lundin.com - * @author Patrick Fuller / http://patrick-fuller.com - * @author Max Smolens / https://github.com/msmolens - */ - -THREE.OrthographicTrackballControls = function ( object, domElement ) { - - var _this = this; - var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 }; - - this.object = object; - this.domElement = ( domElement !== undefined ) ? domElement : document; - - // API - - this.enabled = true; - - this.screen = { left: 0, top: 0, width: 0, height: 0 }; - - this.radius = 0; - - this.rotateSpeed = 1.0; - this.zoomSpeed = 1.2; - - this.noRotate = false; - this.noZoom = false; - this.noPan = false; - this.noRoll = false; - - this.staticMoving = false; - this.dynamicDampingFactor = 0.2; - - this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ]; - - // internals - - this.target = new THREE.Vector3(); - - var EPS = 0.000001; - - var _changed = true; - - var _state = STATE.NONE, - _prevState = STATE.NONE, - - _eye = new THREE.Vector3(), - - _rotateStart = new THREE.Vector3(), - _rotateEnd = new THREE.Vector3(), - - _zoomStart = new THREE.Vector2(), - _zoomEnd = new THREE.Vector2(), - - _touchZoomDistanceStart = 0, - _touchZoomDistanceEnd = 0, - - _panStart = new THREE.Vector2(), - _panEnd = new THREE.Vector2(); - - // for reset - - this.target0 = this.target.clone(); - this.position0 = this.object.position.clone(); - this.up0 = this.object.up.clone(); - - this.left0 = this.object.left; - this.right0 = this.object.right; - this.top0 = this.object.top; - this.bottom0 = this.object.bottom; - - // events - - var changeEvent = { type: 'change' }; - var startEvent = { type: 'start' }; - var endEvent = { type: 'end' }; - - - // methods - - this.handleResize = function () { - - if ( this.domElement === document ) { - - this.screen.left = 0; - this.screen.top = 0; - this.screen.width = window.innerWidth; - this.screen.height = window.innerHeight; - - } else { - - var box = this.domElement.getBoundingClientRect(); - // adjustments come from similar code in the jquery offset() function - var d = this.domElement.ownerDocument.documentElement; - this.screen.left = box.left + window.pageXOffset - d.clientLeft; - this.screen.top = box.top + window.pageYOffset - d.clientTop; - this.screen.width = box.width; - this.screen.height = box.height; - - } - - this.radius = 0.5 * Math.min( this.screen.width, this.screen.height ); - - this.left0 = this.object.left; - this.right0 = this.object.right; - this.top0 = this.object.top; - this.bottom0 = this.object.bottom; - - }; - - var getMouseOnScreen = ( function () { - - var vector = new THREE.Vector2(); - - return function getMouseOnScreen( pageX, pageY ) { - - vector.set( - ( pageX - _this.screen.left ) / _this.screen.width, - ( pageY - _this.screen.top ) / _this.screen.height - ); - - return vector; - - }; - - }() ); - - var getMouseProjectionOnBall = ( function () { - - var vector = new THREE.Vector3(); - var objectUp = new THREE.Vector3(); - var mouseOnBall = new THREE.Vector3(); - - return function getMouseProjectionOnBall( pageX, pageY ) { - - mouseOnBall.set( - ( pageX - _this.screen.width * 0.5 - _this.screen.left ) / _this.radius, - ( _this.screen.height * 0.5 + _this.screen.top - pageY ) / _this.radius, - 0.0 - ); - - var length = mouseOnBall.length(); - - if ( _this.noRoll ) { - - if ( length < Math.SQRT1_2 ) { - - mouseOnBall.z = Math.sqrt( 1.0 - length * length ); - - } else { - - mouseOnBall.z = .5 / length; - - } - - } else if ( length > 1.0 ) { - - mouseOnBall.normalize(); - - } else { - - mouseOnBall.z = Math.sqrt( 1.0 - length * length ); - - } - - _eye.copy( _this.object.position ).sub( _this.target ); - - vector.copy( _this.object.up ).setLength( mouseOnBall.y ); - vector.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) ); - vector.add( _eye.setLength( mouseOnBall.z ) ); - - return vector; - - }; - - }() ); - - this.rotateCamera = ( function () { - - var axis = new THREE.Vector3(), - quaternion = new THREE.Quaternion(); - - - return function rotateCamera() { - - var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() ); - - if ( angle ) { - - axis.crossVectors( _rotateStart, _rotateEnd ).normalize(); - - angle *= _this.rotateSpeed; - - quaternion.setFromAxisAngle( axis, - angle ); - - _eye.applyQuaternion( quaternion ); - _this.object.up.applyQuaternion( quaternion ); - - _rotateEnd.applyQuaternion( quaternion ); - - if ( _this.staticMoving ) { - - _rotateStart.copy( _rotateEnd ); - - } else { - - quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) ); - _rotateStart.applyQuaternion( quaternion ); - - } - - _changed = true; - - } - - }; - - }() ); - - this.zoomCamera = function () { - - if ( _state === STATE.TOUCH_ZOOM_PAN ) { - - var factor = _touchZoomDistanceEnd / _touchZoomDistanceStart; - _touchZoomDistanceStart = _touchZoomDistanceEnd; - - _this.object.zoom *= factor; - - _changed = true; - - } else { - - var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed; - - if ( Math.abs( factor - 1.0 ) > EPS && factor > 0.0 ) { - - _this.object.zoom /= factor; - - if ( _this.staticMoving ) { - - _zoomStart.copy( _zoomEnd ); - - } else { - - _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor; - - } - - _changed = true; - - } - - } - - }; - - this.panCamera = ( function () { - - var mouseChange = new THREE.Vector2(), - objectUp = new THREE.Vector3(), - pan = new THREE.Vector3(); - - return function panCamera() { - - mouseChange.copy( _panEnd ).sub( _panStart ); - - if ( mouseChange.lengthSq() ) { - - // Scale movement to keep clicked/dragged position under cursor - var scale_x = ( _this.object.right - _this.object.left ) / _this.object.zoom; - var scale_y = ( _this.object.top - _this.object.bottom ) / _this.object.zoom; - mouseChange.x *= scale_x; - mouseChange.y *= scale_y; - - pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x ); - pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) ); - - _this.object.position.add( pan ); - _this.target.add( pan ); - - if ( _this.staticMoving ) { - - _panStart.copy( _panEnd ); - - } else { - - _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) ); - - } - - _changed = true; - - } - - }; - - }() ); - - this.update = function () { - - _eye.subVectors( _this.object.position, _this.target ); - - if ( ! _this.noRotate ) { - - _this.rotateCamera(); - - } - - if ( ! _this.noZoom ) { - - _this.zoomCamera(); - - if ( _changed ) { - - _this.object.updateProjectionMatrix(); - - } - - } - - if ( ! _this.noPan ) { - - _this.panCamera(); - - } - - _this.object.position.addVectors( _this.target, _eye ); - - _this.object.lookAt( _this.target ); - - if ( _changed ) { - - _this.dispatchEvent( changeEvent ); - - _changed = false; - - } - - }; - - this.reset = function () { - - _state = STATE.NONE; - _prevState = STATE.NONE; - - _this.target.copy( _this.target0 ); - _this.object.position.copy( _this.position0 ); - _this.object.up.copy( _this.up0 ); - - _eye.subVectors( _this.object.position, _this.target ); - - _this.object.left = _this.left0; - _this.object.right = _this.right0; - _this.object.top = _this.top0; - _this.object.bottom = _this.bottom0; - - _this.object.lookAt( _this.target ); - - _this.dispatchEvent( changeEvent ); - - _changed = false; - - }; - - // listeners - - function keydown( event ) { - - if ( _this.enabled === false ) return; - - window.removeEventListener( 'keydown', keydown ); - - _prevState = _state; - - if ( _state !== STATE.NONE ) { - - return; - - } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && ! _this.noRotate ) { - - _state = STATE.ROTATE; - - } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && ! _this.noZoom ) { - - _state = STATE.ZOOM; - - } else if ( event.keyCode === _this.keys[ STATE.PAN ] && ! _this.noPan ) { - - _state = STATE.PAN; - - } - - } - - function keyup() { - - if ( _this.enabled === false ) return; - - _state = _prevState; - - window.addEventListener( 'keydown', keydown, false ); - - } - - function mousedown( event ) { - - if ( _this.enabled === false ) return; - - event.preventDefault(); - event.stopPropagation(); - - if ( _state === STATE.NONE ) { - - _state = event.button; - - } - - if ( _state === STATE.ROTATE && ! _this.noRotate ) { - - _rotateStart.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); - _rotateEnd.copy( _rotateStart ); - - } else if ( _state === STATE.ZOOM && ! _this.noZoom ) { - - _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - _zoomEnd.copy( _zoomStart ); - - } else if ( _state === STATE.PAN && ! _this.noPan ) { - - _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - _panEnd.copy( _panStart ); - - } - - document.addEventListener( 'mousemove', mousemove, false ); - document.addEventListener( 'mouseup', mouseup, false ); - - _this.dispatchEvent( startEvent ); - - } - - function mousemove( event ) { - - if ( _this.enabled === false ) return; - - event.preventDefault(); - event.stopPropagation(); - - if ( _state === STATE.ROTATE && ! _this.noRotate ) { - - _rotateEnd.copy( getMouseProjectionOnBall( event.pageX, event.pageY ) ); - - } else if ( _state === STATE.ZOOM && ! _this.noZoom ) { - - _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - - } else if ( _state === STATE.PAN && ! _this.noPan ) { - - _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) ); - - } - - } - - function mouseup( event ) { - - if ( _this.enabled === false ) return; - - event.preventDefault(); - event.stopPropagation(); - - _state = STATE.NONE; - - document.removeEventListener( 'mousemove', mousemove ); - document.removeEventListener( 'mouseup', mouseup ); - _this.dispatchEvent( endEvent ); - - } - - function mousewheel( event ) { - - if ( _this.enabled === false ) return; - - event.preventDefault(); - event.stopPropagation(); - - switch ( event.deltaMode ) { - - case 2: - // Zoom in pages - _zoomStart.y -= event.deltaY * 0.025; - break; - - case 1: - // Zoom in lines - _zoomStart.y -= event.deltaY * 0.01; - break; - - default: - // undefined, 0, assume pixels - _zoomStart.y -= event.deltaY * 0.00025; - break; - - } - - _this.dispatchEvent( startEvent ); - _this.dispatchEvent( endEvent ); - - } - - function touchstart( event ) { - - if ( _this.enabled === false ) return; - - switch ( event.touches.length ) { - - case 1: - _state = STATE.TOUCH_ROTATE; - _rotateStart.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - _rotateEnd.copy( _rotateStart ); - break; - - case 2: - _state = STATE.TOUCH_ZOOM_PAN; - var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; - var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; - _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy ); - - var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2; - var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2; - _panStart.copy( getMouseOnScreen( x, y ) ); - _panEnd.copy( _panStart ); - break; - - default: - _state = STATE.NONE; - - } - _this.dispatchEvent( startEvent ); - - } - - function touchmove( event ) { - - if ( _this.enabled === false ) return; - - event.preventDefault(); - event.stopPropagation(); - - switch ( event.touches.length ) { - - case 1: - _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - break; - - case 2: - var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; - var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; - _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy ); - - var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2; - var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2; - _panEnd.copy( getMouseOnScreen( x, y ) ); - break; - - default: - _state = STATE.NONE; - - } - - } - - function touchend( event ) { - - if ( _this.enabled === false ) return; - - switch ( event.touches.length ) { - - case 1: - _rotateEnd.copy( getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); - _rotateStart.copy( _rotateEnd ); - break; - - case 2: - _touchZoomDistanceStart = _touchZoomDistanceEnd = 0; - - var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2; - var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2; - _panEnd.copy( getMouseOnScreen( x, y ) ); - _panStart.copy( _panEnd ); - break; - - } - - _state = STATE.NONE; - _this.dispatchEvent( endEvent ); - - } - - function contextmenu( event ) { - - event.preventDefault(); - - } - - this.dispose = function () { - - this.domElement.removeEventListener( 'contextmenu', contextmenu, false ); - this.domElement.removeEventListener( 'mousedown', mousedown, false ); - this.domElement.removeEventListener( 'wheel', mousewheel, false ); - - this.domElement.removeEventListener( 'touchstart', touchstart, false ); - this.domElement.removeEventListener( 'touchend', touchend, false ); - this.domElement.removeEventListener( 'touchmove', touchmove, false ); - - document.removeEventListener( 'mousemove', mousemove, false ); - document.removeEventListener( 'mouseup', mouseup, false ); - - window.removeEventListener( 'keydown', keydown, false ); - window.removeEventListener( 'keyup', keyup, false ); - - }; - - this.domElement.addEventListener( 'contextmenu', contextmenu, false ); - this.domElement.addEventListener( 'mousedown', mousedown, false ); - this.domElement.addEventListener( 'wheel', mousewheel, false ); - - this.domElement.addEventListener( 'touchstart', touchstart, false ); - this.domElement.addEventListener( 'touchend', touchend, false ); - this.domElement.addEventListener( 'touchmove', touchmove, false ); - - window.addEventListener( 'keydown', keydown, false ); - window.addEventListener( 'keyup', keyup, false ); - - this.handleResize(); - - // force an update at start - this.update(); - -}; - -THREE.OrthographicTrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype ); -THREE.OrthographicTrackballControls.prototype.constructor = THREE.OrthographicTrackballControls; diff --git a/examples/js/controls/PointerLockControls.js b/examples/js/controls/PointerLockControls.js index b048e29123f424..67edc8456dbff7 100644 --- a/examples/js/controls/PointerLockControls.js +++ b/examples/js/controls/PointerLockControls.js @@ -5,7 +5,14 @@ THREE.PointerLockControls = function ( camera, domElement ) { - this.domElement = domElement || document.body; + if ( domElement === undefined ) { + + console.warn( 'THREE.PointerLockControls: The second parameter "domElement" is now mandatory.' ); + domElement = document.body; + + } + + this.domElement = domElement; this.isLocked = false; // @@ -22,6 +29,8 @@ THREE.PointerLockControls = function ( camera, domElement ) { var PI_2 = Math.PI / 2; + var vec = new THREE.Vector3(); + function onMouseMove( event ) { if ( scope.isLocked === false ) return; @@ -106,6 +115,27 @@ THREE.PointerLockControls = function ( camera, domElement ) { }(); + this.moveForward = function ( distance ) { + + // move forward parallel to the xz-plane + // assumes camera.up is y-up + + vec.setFromMatrixColumn( camera.matrix, 0 ); + + vec.crossVectors( camera.up, vec ); + + camera.position.addScaledVector( vec, distance ); + + }; + + this.moveRight = function ( distance ) { + + vec.setFromMatrixColumn( camera.matrix, 0 ); + + camera.position.addScaledVector( vec, distance ); + + }; + this.lock = function () { this.domElement.requestPointerLock(); diff --git a/examples/js/controls/TrackballControls.js b/examples/js/controls/TrackballControls.js index 3cfbb72cded55a..ff89280e1db1af 100644 --- a/examples/js/controls/TrackballControls.js +++ b/examples/js/controls/TrackballControls.js @@ -7,11 +7,14 @@ THREE.TrackballControls = function ( object, domElement ) { + if ( domElement === undefined ) console.warn( 'THREE.TrackballControls: The second parameter "domElement" is now mandatory.' ); + if ( domElement === document ) console.error( 'THREE.TrackballControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' ); + var _this = this; var STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 }; this.object = object; - this.domElement = ( domElement !== undefined ) ? domElement : document; + this.domElement = domElement; // API @@ -44,6 +47,7 @@ THREE.TrackballControls = function ( object, domElement ) { var EPS = 0.000001; var lastPosition = new THREE.Vector3(); + var lastZoom = 1; var _state = STATE.NONE, _keyState = STATE.NONE, @@ -70,6 +74,7 @@ THREE.TrackballControls = function ( object, domElement ) { this.target0 = this.target.clone(); this.position0 = this.object.position.clone(); this.up0 = this.object.up.clone(); + this.zoom0 = this.object.zoom; // events @@ -82,24 +87,13 @@ THREE.TrackballControls = function ( object, domElement ) { this.handleResize = function () { - if ( this.domElement === document ) { - - this.screen.left = 0; - this.screen.top = 0; - this.screen.width = window.innerWidth; - this.screen.height = window.innerHeight; - - } else { - - var box = this.domElement.getBoundingClientRect(); - // adjustments come from similar code in the jquery offset() function - var d = this.domElement.ownerDocument.documentElement; - this.screen.left = box.left + window.pageXOffset - d.clientLeft; - this.screen.top = box.top + window.pageYOffset - d.clientTop; - this.screen.width = box.width; - this.screen.height = box.height; - - } + var box = this.domElement.getBoundingClientRect(); + // adjustments come from similar code in the jquery offset() function + var d = this.domElement.ownerDocument.documentElement; + this.screen.left = box.left + window.pageXOffset - d.clientLeft; + this.screen.top = box.top + window.pageYOffset - d.clientTop; + this.screen.width = box.width; + this.screen.height = box.height; }; @@ -201,7 +195,21 @@ THREE.TrackballControls = function ( object, domElement ) { factor = _touchZoomDistanceStart / _touchZoomDistanceEnd; _touchZoomDistanceStart = _touchZoomDistanceEnd; - _eye.multiplyScalar( factor ); + + if ( _this.object.isPerspectiveCamera ) { + + _eye.multiplyScalar( factor ); + + } else if ( _this.object.isOrthographicCamera ) { + + _this.object.zoom *= factor; + _this.object.updateProjectionMatrix(); + + } else { + + console.warn( 'THREE.TrackballControls: Unsupported camera type' ); + + } } else { @@ -209,7 +217,20 @@ THREE.TrackballControls = function ( object, domElement ) { if ( factor !== 1.0 && factor > 0.0 ) { - _eye.multiplyScalar( factor ); + if ( _this.object.isPerspectiveCamera ) { + + _eye.multiplyScalar( factor ); + + } else if ( _this.object.isOrthographicCamera ) { + + _this.object.zoom /= factor; + _this.object.updateProjectionMatrix(); + + } else { + + console.warn( 'THREE.TrackballControls: Unsupported camera type' ); + + } } @@ -239,6 +260,16 @@ THREE.TrackballControls = function ( object, domElement ) { if ( mouseChange.lengthSq() ) { + if ( _this.object.isOrthographicCamera ) { + + var scale_x = ( _this.object.right - _this.object.left ) / _this.object.zoom / _this.domElement.clientWidth; + var scale_y = ( _this.object.top - _this.object.bottom ) / _this.object.zoom / _this.domElement.clientWidth; + + mouseChange.x *= scale_x; + mouseChange.y *= scale_y; + + } + mouseChange.multiplyScalar( _eye.length() * _this.panSpeed ); pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x ); @@ -309,15 +340,36 @@ THREE.TrackballControls = function ( object, domElement ) { _this.object.position.addVectors( _this.target, _eye ); - _this.checkDistances(); + if ( _this.object.isPerspectiveCamera ) { - _this.object.lookAt( _this.target ); + _this.checkDistances(); - if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) { + _this.object.lookAt( _this.target ); - _this.dispatchEvent( changeEvent ); + if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) { - lastPosition.copy( _this.object.position ); + _this.dispatchEvent( changeEvent ); + + lastPosition.copy( _this.object.position ); + + } + + } else if ( _this.object.isOrthographicCamera ) { + + _this.object.lookAt( _this.target ); + + if ( lastPosition.distanceToSquared( _this.object.position ) > EPS || lastZoom !== _this.object.zoom ) { + + _this.dispatchEvent( changeEvent ); + + lastPosition.copy( _this.object.position ); + lastZoom = _this.object.zoom; + + } + + } else { + + console.warn( 'THREE.TrackballControls: Unsupported camera type' ); } @@ -331,6 +383,9 @@ THREE.TrackballControls = function ( object, domElement ) { _this.target.copy( _this.target0 ); _this.object.position.copy( _this.position0 ); _this.object.up.copy( _this.up0 ); + _this.object.zoom = _this.zoom0; + + _this.object.updateProjectionMatrix(); _eye.subVectors( _this.object.position, _this.target ); @@ -339,6 +394,7 @@ THREE.TrackballControls = function ( object, domElement ) { _this.dispatchEvent( changeEvent ); lastPosition.copy( _this.object.position ); + lastZoom = _this.object.zoom; }; diff --git a/examples/js/controls/TransformControls.js b/examples/js/controls/TransformControls.js index e89930dd7fe3f0..4da137bdd6ce5a 100644 --- a/examples/js/controls/TransformControls.js +++ b/examples/js/controls/TransformControls.js @@ -4,11 +4,17 @@ THREE.TransformControls = function ( camera, domElement ) { - THREE.Object3D.call( this ); + if ( domElement === undefined ) { + + console.warn( 'THREE.TransformControls: The second parameter "domElement" is now mandatory.' ); + domElement = document; + + } - domElement = ( domElement !== undefined ) ? domElement : document; + THREE.Object3D.call( this ); this.visible = false; + this.domElement = domElement; var _gizmo = new THREE.TransformControlsGizmo(); this.add( _gizmo ); @@ -29,6 +35,7 @@ THREE.TransformControls = function ( camera, domElement ) { defineProperty( "mode", "translate" ); defineProperty( "translationSnap", null ); defineProperty( "rotationSnap", null ); + defineProperty( "scaleSnap", null ); defineProperty( "space", "world" ); defineProperty( "size", 1 ); defineProperty( "dragging", false ); @@ -199,7 +206,17 @@ THREE.TransformControls = function ( camera, domElement ) { if ( this.object !== undefined ) { this.object.updateMatrixWorld(); - this.object.parent.matrixWorld.decompose( parentPosition, parentQuaternion, parentScale ); + + if ( this.object.parent === null ) { + + console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' ); + + } else { + + this.object.parent.matrixWorld.decompose( parentPosition, parentQuaternion, parentScale ); + + } + this.object.matrixWorld.decompose( worldPosition, worldQuaternion, worldScale ); parentQuaternionInv.copy( parentQuaternion ).inverse(); @@ -210,15 +227,7 @@ THREE.TransformControls = function ( camera, domElement ) { this.camera.updateMatrixWorld(); this.camera.matrixWorld.decompose( cameraPosition, cameraQuaternion, cameraScale ); - if ( this.camera instanceof THREE.PerspectiveCamera ) { - - eye.copy( cameraPosition ).sub( worldPosition ).normalize(); - - } else if ( this.camera instanceof THREE.OrthographicCamera ) { - - eye.copy( cameraPosition ).normalize(); - - } + eye.copy( cameraPosition ).sub( worldPosition ).normalize(); THREE.Object3D.prototype.updateMatrixWorld.call( this ); @@ -462,6 +471,28 @@ THREE.TransformControls = function ( camera, domElement ) { object.scale.copy( scaleStart ).multiply( _tempVector2 ); + if ( this.scaleSnap ) { + + if ( axis.search( 'X' ) !== - 1 ) { + + object.scale.x = Math.round( object.scale.x / this.scaleSnap ) * this.scaleSnap || this.scaleSnap; + + } + + if ( axis.search( 'Y' ) !== - 1 ) { + + object.scale.y = Math.round( object.scale.y / this.scaleSnap ) * this.scaleSnap || this.scaleSnap; + + } + + if ( axis.search( 'Z' ) !== - 1 ) { + + object.scale.z = Math.round( object.scale.z / this.scaleSnap ) * this.scaleSnap || this.scaleSnap; + + } + + } + } else if ( mode === 'rotate' ) { offset.copy( pointEnd ).sub( pointStart ); @@ -547,15 +578,27 @@ THREE.TransformControls = function ( camera, domElement ) { function getPointer( event ) { - var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event; + if ( document.pointerLockElement ) { - var rect = domElement.getBoundingClientRect(); + return { + x: 0, + y: 0, + button: event.button + }; - return { - x: ( pointer.clientX - rect.left ) / rect.width * 2 - 1, - y: - ( pointer.clientY - rect.top ) / rect.height * 2 + 1, - button: event.button - }; + } else { + + var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event; + + var rect = domElement.getBoundingClientRect(); + + return { + x: ( pointer.clientX - rect.left ) / rect.width * 2 - 1, + y: - ( pointer.clientY - rect.top ) / rect.height * 2 + 1, + button: event.button + }; + + } } @@ -624,6 +667,12 @@ THREE.TransformControls = function ( camera, domElement ) { }; + this.setScaleSnap = function ( scaleSnap ) { + + scope.scaleSnap = scaleSnap; + + }; + this.setSize = function ( size ) { scope.size = size; @@ -696,16 +745,16 @@ THREE.TransformControlsGizmo = function () { var matBlue = gizmoMaterial.clone(); matBlue.color.set( 0x0000ff ); - var matWhiteTransperent = gizmoMaterial.clone(); - matWhiteTransperent.opacity = 0.25; + var matWhiteTransparent = gizmoMaterial.clone(); + matWhiteTransparent.opacity = 0.25; - var matYellowTransparent = matWhiteTransperent.clone(); + var matYellowTransparent = matWhiteTransparent.clone(); matYellowTransparent.color.set( 0xffff00 ); - var matCyanTransparent = matWhiteTransperent.clone(); + var matCyanTransparent = matWhiteTransparent.clone(); matCyanTransparent.color.set( 0x00ffff ); - var matMagentaTransparent = matWhiteTransperent.clone(); + var matMagentaTransparent = matWhiteTransparent.clone(); matMagentaTransparent.color.set( 0xff00ff ); var matYellow = gizmoMaterial.clone(); @@ -742,7 +791,7 @@ THREE.TransformControlsGizmo = function () { var scaleHandleGeometry = new THREE.BoxBufferGeometry( 0.125, 0.125, 0.125 ); var lineGeometry = new THREE.BufferGeometry( ); - lineGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 0, 0 ], 3 ) ); + lineGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 0, 0 ], 3 ) ); var CircleGeometry = function ( radius, arc ) { @@ -755,7 +804,7 @@ THREE.TransformControlsGizmo = function () { } - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); return geometry; @@ -767,7 +816,7 @@ THREE.TransformControlsGizmo = function () { var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) ); return geometry; @@ -792,20 +841,20 @@ THREE.TransformControlsGizmo = function () { [ new THREE.Line( lineGeometry, matLineBlue ), null, [ 0, - Math.PI / 2, 0 ]] ], XYZ: [ - [ new THREE.Mesh( new THREE.OctahedronBufferGeometry( 0.1, 0 ), matWhiteTransperent ), [ 0, 0, 0 ], [ 0, 0, 0 ]] + [ new THREE.Mesh( new THREE.OctahedronBufferGeometry( 0.1, 0 ), matWhiteTransparent.clone() ), [ 0, 0, 0 ], [ 0, 0, 0 ]] ], XY: [ - [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.295, 0.295 ), matYellowTransparent ), [ 0.15, 0.15, 0 ]], + [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.295, 0.295 ), matYellowTransparent.clone() ), [ 0.15, 0.15, 0 ]], [ new THREE.Line( lineGeometry, matLineYellow ), [ 0.18, 0.3, 0 ], null, [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineYellow ), [ 0.3, 0.18, 0 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]] ], YZ: [ - [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.295, 0.295 ), matCyanTransparent ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]], + [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.295, 0.295 ), matCyanTransparent.clone() ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]], [ new THREE.Line( lineGeometry, matLineCyan ), [ 0, 0.18, 0.3 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineCyan ), [ 0, 0.3, 0.18 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]] ], XZ: [ - [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.295, 0.295 ), matMagentaTransparent ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]], + [ new THREE.Mesh( new THREE.PlaneBufferGeometry( 0.295, 0.295 ), matMagentaTransparent.clone() ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]], [ new THREE.Line( lineGeometry, matLineMagenta ), [ 0.18, 0, 0.3 ], null, [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineMagenta ), [ 0.3, 0, 0.18 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]] ] @@ -934,13 +983,13 @@ THREE.TransformControlsGizmo = function () { [ new THREE.Line( lineGeometry, matLineMagenta ), [ 0.98, 0, 0.855 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]] ], XYZX: [ - [ new THREE.Mesh( new THREE.BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransperent ), [ 1.1, 0, 0 ]], + [ new THREE.Mesh( new THREE.BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 1.1, 0, 0 ]], ], XYZY: [ - [ new THREE.Mesh( new THREE.BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransperent ), [ 0, 1.1, 0 ]], + [ new THREE.Mesh( new THREE.BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 0, 1.1, 0 ]], ], XYZZ: [ - [ new THREE.Mesh( new THREE.BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransperent ), [ 0, 0, 1.1 ]], + [ new THREE.Mesh( new THREE.BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 0, 0, 1.1 ]], ] }; @@ -1025,7 +1074,7 @@ THREE.TransformControlsGizmo = function () { object.updateMatrix(); var tempGeometry = object.geometry.clone(); - tempGeometry.applyMatrix( object.matrix ); + tempGeometry.applyMatrix4( object.matrix ); object.geometry = tempGeometry; object.renderOrder = Infinity; diff --git a/examples/js/curves/CurveExtras.js b/examples/js/curves/CurveExtras.js index 110eda83a16964..1986bad5c08e19 100644 --- a/examples/js/curves/CurveExtras.js +++ b/examples/js/curves/CurveExtras.js @@ -8,7 +8,7 @@ * http://en.wikipedia.org/wiki/Viviani%27s_curve * http://mathdl.maa.org/images/upload_library/23/stemkoski/knots/page4.html * http://www.mi.sanu.ac.rs/vismath/taylorapril2011/Taylor.pdf - * http://prideout.net/blog/?p=44 + * https://prideout.net/blog/old/blog/index.html@p=44.html */ THREE.Curves = ( function () { diff --git a/examples/js/effects/OutlineEffect.js b/examples/js/effects/OutlineEffect.js index fe06cd9382fdb2..1a4e80b9137056 100644 --- a/examples/js/effects/OutlineEffect.js +++ b/examples/js/effects/OutlineEffect.js @@ -54,9 +54,6 @@ * visible: true, * keepAlive: true * }; - * - * TODO - * - support shader material without objectNormal in its vertexShader */ THREE.OutlineEffect = function ( renderer, parameters ) { @@ -90,58 +87,57 @@ THREE.OutlineEffect = function ( renderer, parameters ) { //this.cache = cache; // for debug - // copied from WebGLPrograms and removed some materials - var shaderIDs = { - MeshBasicMaterial: 'basic', - MeshLambertMaterial: 'lambert', - MeshPhongMaterial: 'phong', - MeshToonMaterial: 'phong', - MeshStandardMaterial: 'physical', - MeshPhysicalMaterial: 'physical' - }; - - var uniformsChunk = { + var uniformsOutline = { outlineThickness: { value: defaultThickness }, outlineColor: { value: defaultColor }, outlineAlpha: { value: defaultAlpha } }; - var vertexShaderChunk = [ + var vertexShader = [ + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", + "#include ", "uniform float outlineThickness;", - "vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {", - + "vec4 calculateOutline( vec4 pos, vec3 normal, vec4 skinned ) {", " float thickness = outlineThickness;", " const float ratio = 1.0;", // TODO: support outline thickness ratio for each vertex - " vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );", + " vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + normal, 1.0 );", // NOTE: subtract pos2 from pos because BackSide objectNormal is negative " vec4 norm = normalize( pos - pos2 );", " return pos + norm * thickness * pos.w * ratio;", + "}", - "}" + "void main() {", - ].join( "\n" ); + " #include ", - var vertexShaderChunk2 = [ + " #include ", + " #include ", + " #include ", + " #include ", - "#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )", - " #ifndef USE_ENVMAP", - " vec3 objectNormal = normalize( normal );", - " #endif", - "#endif", + " #include ", + " #include ", + " #include ", + " #include ", + " #include ", - "#ifdef FLIP_SIDED", - " objectNormal = -objectNormal;", - "#endif", + " vec3 outlineNormal = - objectNormal;", // the outline material is always rendered with THREE.BackSide - "#ifdef DECLARE_TRANSFORMED", - " vec3 transformed = vec3( position );", - "#endif", + " gl_Position = calculateOutline( gl_Position, outlineNormal, vec4( transformed, 1.0 ) );", - "gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );", + " #include ", + " #include ", + " #include ", - "#include " + "}", ].join( "\n" ); @@ -149,92 +145,40 @@ THREE.OutlineEffect = function ( renderer, parameters ) { "#include ", "#include ", + "#include ", + "#include ", "uniform vec3 outlineColor;", "uniform float outlineAlpha;", "void main() {", + " #include ", + " #include ", + " gl_FragColor = vec4( outlineColor, outlineAlpha );", + " #include ", + " #include ", " #include ", + " #include ", "}" ].join( "\n" ); - function createInvisibleMaterial() { - - return new THREE.ShaderMaterial( { name: 'invisible', visible: false } ); - - } - - function createMaterial( originalMaterial ) { - - var shaderID = shaderIDs[ originalMaterial.type ]; - var originalUniforms, originalVertexShader; - - if ( shaderID !== undefined ) { - - var shader = THREE.ShaderLib[ shaderID ]; - originalUniforms = shader.uniforms; - originalVertexShader = shader.vertexShader; - - } else if ( originalMaterial.isRawShaderMaterial === true ) { - - originalUniforms = originalMaterial.uniforms; - originalVertexShader = originalMaterial.vertexShader; - - if ( ! /attribute\s+vec3\s+position\s*;/.test( originalVertexShader ) || - ! /attribute\s+vec3\s+normal\s*;/.test( originalVertexShader ) ) { - - console.warn( 'THREE.OutlineEffect requires both vec3 position and normal attributes in vertex shader, ' + - 'does not draw outline for ' + originalMaterial.name + '(uuid:' + originalMaterial.uuid + ') material.' ); - - return createInvisibleMaterial(); - - } - - } else if ( originalMaterial.isShaderMaterial === true ) { - - originalUniforms = originalMaterial.uniforms; - originalVertexShader = originalMaterial.vertexShader; - - } else { - - return createInvisibleMaterial(); - - } - - var uniforms = Object.assign( {}, originalUniforms, uniformsChunk ); - - var vertexShader = originalVertexShader - // put vertexShaderChunk right before "void main() {...}" - .replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' ) - // put vertexShaderChunk2 the end of "void main() {...}" - // Note: here assums originalVertexShader ends with "}" of "void main() {...}" - .replace( /\}\s*$/, vertexShaderChunk2 + '\n}' ) - // remove any light related lines - // Note: here is very sensitive to originalVertexShader - // TODO: consider safer way - .replace( /#include\s+<[\w_]*light[\w_]*>/g, '' ); - - var defines = {}; - - if ( ! /vec3\s+transformed\s*=/.test( originalVertexShader ) && - ! /#include\s+/.test( originalVertexShader ) ) defines.DECLARE_TRANSFORMED = true; + function createMaterial() { return new THREE.ShaderMaterial( { - defines: defines, - uniforms: uniforms, + type: 'OutlineEffect', + uniforms: THREE.UniformsUtils.merge( [ + THREE.UniformsLib[ 'fog' ], + THREE.UniformsLib[ 'displacementmap' ], + uniformsOutline + ] ), vertexShader: vertexShader, fragmentShader: fragmentShader, - side: THREE.BackSide, - //wireframe: true, - skinning: false, - morphTargets: false, - morphNormals: false, - fog: false + side: THREE.BackSide } ); } @@ -246,7 +190,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { if ( data === undefined ) { data = { - material: createMaterial( originalMaterial ), + material: createMaterial(), used: true, keepAlive: defaultKeepAlive, count: 0 @@ -274,9 +218,32 @@ THREE.OutlineEffect = function ( renderer, parameters ) { } + function isCompatible( object ) { + + var geometry = object.geometry; + var hasNormals = false; + + if ( object.geometry !== undefined ) { + + if ( geometry.isBufferGeometry ) { + + hasNormals = geometry.attributes.normal !== undefined; + + } else { + + hasNormals = true; // the renderer always produces a normal attribute for Geometry + + } + + } + + return ( object.isMesh === true && object.material !== undefined && hasNormals === true ); + + } + function setOutlineMaterial( object ) { - if ( object.material === undefined ) return; + if ( isCompatible( object ) === false ) return; if ( Array.isArray( object.material ) ) { @@ -299,7 +266,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { function restoreOriginalMaterial( object ) { - if ( object.material === undefined ) return; + if ( isCompatible( object ) === false ) return; if ( Array.isArray( object.material ) ) { @@ -344,6 +311,14 @@ THREE.OutlineEffect = function ( renderer, parameters ) { } + if ( originalMaterial.displacementMap ) { + + material.uniforms.displacementMap.value = originalMaterial.displacementMap; + material.uniforms.displacementScale.value = originalMaterial.displacementScale; + material.uniforms.displacementBias.value = originalMaterial.displacementBias; + + } + } function updateOutlineMaterial( material, originalMaterial ) { @@ -356,6 +331,9 @@ THREE.OutlineEffect = function ( renderer, parameters ) { material.morphTargets = originalMaterial.morphTargets; material.morphNormals = originalMaterial.morphNormals; material.fog = originalMaterial.fog; + material.toneMapped = originalMaterial.toneMapped; + material.premultipliedAlpha = originalMaterial.premultipliedAlpha; + material.displacementMap = originalMaterial.displacementMap; if ( outlineParameters !== undefined ) { @@ -382,6 +360,18 @@ THREE.OutlineEffect = function ( renderer, parameters ) { if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false; + if ( originalMaterial.clippingPlanes ) { + + material.clipping = true; + + material.clippingPlanes = originalMaterial.clippingPlanes; + material.clipIntersection = originalMaterial.clipIntersection; + material.clipShadows = originalMaterial.clipShadows; + + } + + material.version = originalMaterial.version; // update outline material if necessary + } function cleanupCache() { diff --git a/examples/js/exporters/ColladaExporter.js b/examples/js/exporters/ColladaExporter.js index 85222c80eb3ca8..ec7b610a3d9a1c 100644 --- a/examples/js/exporters/ColladaExporter.js +++ b/examples/js/exporters/ColladaExporter.js @@ -220,7 +220,9 @@ THREE.ColladaExporter.prototype = { bufferGeometry.groups : [ { start: 0, count: indexCount, materialIndex: 0 } ]; - var gnode = ``; + + var gname = g.name ? ` name="${ g.name }"` : ''; + var gnode = ``; // define the geometry node and the vertices for the geometry var posName = `${ meshid }-position`; @@ -485,7 +487,7 @@ THREE.ColladaExporter.prototype = { ( m.side === THREE.DoubleSide ? - `1` : + `1` : '' ) + @@ -493,7 +495,10 @@ THREE.ColladaExporter.prototype = { ''; - libraryMaterials.push( `` ); + var materialName = m.name ? ` name="${ m.name }"` : ''; + var materialNode = ``; + + libraryMaterials.push( materialNode ); libraryEffects.push( effectnode ); materialMap.set( m, matid ); diff --git a/examples/js/exporters/GLTFExporter.js b/examples/js/exporters/GLTFExporter.js index 49af98dcb630fb..3889b093c31c50 100644 --- a/examples/js/exporters/GLTFExporter.js +++ b/examples/js/exporters/GLTFExporter.js @@ -78,6 +78,7 @@ THREE.GLTFExporter.prototype = { onlyVisible: true, truncateDrawRange: true, embedImages: true, + maxTextureSize: Infinity, animations: [], forceIndices: false, forcePowerOfTwoTextures: false, @@ -225,7 +226,7 @@ THREE.GLTFExporter.prototype = { */ function isPowerOfTwo( image ) { - return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ); + return THREE.MathUtils.isPowerOfTwo( image.width ) && THREE.MathUtils.isPowerOfTwo( image.height ); } @@ -751,15 +752,15 @@ THREE.GLTFExporter.prototype = { var canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' ); - canvas.width = image.width; - canvas.height = image.height; + canvas.width = Math.min( image.width, options.maxTextureSize ); + canvas.height = Math.min( image.height, options.maxTextureSize ); - if ( options.forcePowerOfTwoTextures && ! isPowerOfTwo( image ) ) { + if ( options.forcePowerOfTwoTextures && ! isPowerOfTwo( canvas ) ) { console.warn( 'GLTFExporter: Resized non-power-of-two image.', image ); - canvas.width = THREE.Math.floorPowerOfTwo( canvas.width ); - canvas.height = THREE.Math.floorPowerOfTwo( canvas.height ); + canvas.width = THREE.MathUtils.floorPowerOfTwo( canvas.width ); + canvas.height = THREE.MathUtils.floorPowerOfTwo( canvas.height ); } @@ -867,6 +868,12 @@ THREE.GLTFExporter.prototype = { }; + if ( map.name ) { + + gltfTexture.name = map.name; + + } + outputJSON.textures.push( gltfTexture ); var index = outputJSON.textures.length - 1; @@ -895,7 +902,7 @@ THREE.GLTFExporter.prototype = { } - if ( material.isShaderMaterial ) { + if ( material.isShaderMaterial && ! material.isGLTFSpecularGlossinessMaterial ) { console.warn( 'GLTFExporter: THREE.ShaderMaterial not supported.' ); return null; @@ -915,6 +922,12 @@ THREE.GLTFExporter.prototype = { extensionsUsed[ 'KHR_materials_unlit' ] = true; + } else if ( material.isGLTFSpecularGlossinessMaterial ) { + + gltfMaterial.extensions = { KHR_materials_pbrSpecularGlossiness: {} }; + + extensionsUsed[ 'KHR_materials_pbrSpecularGlossiness' ] = true; + } else if ( ! material.isMeshStandardMaterial ) { console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' ); @@ -947,6 +960,23 @@ THREE.GLTFExporter.prototype = { } + // pbrSpecularGlossiness diffuse, specular and glossiness factor + if ( material.isGLTFSpecularGlossinessMaterial ) { + + if ( gltfMaterial.pbrMetallicRoughness.baseColorFactor ) { + + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.diffuseFactor = gltfMaterial.pbrMetallicRoughness.baseColorFactor; + + } + + var specularFactor = [ 1, 1, 1 ]; + material.specular.toArray( specularFactor, 0 ); + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.specularFactor = specularFactor; + + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.glossinessFactor = material.glossiness; + + } + // pbrMetallicRoughness.metallicRoughnessTexture if ( material.metalnessMap || material.roughnessMap ) { @@ -964,20 +994,32 @@ THREE.GLTFExporter.prototype = { } - // pbrMetallicRoughness.baseColorTexture + // pbrMetallicRoughness.baseColorTexture or pbrSpecularGlossiness diffuseTexture if ( material.map ) { var baseColorMapDef = { index: processTexture( material.map ) }; applyTextureTransform( baseColorMapDef, material.map ); + + if ( material.isGLTFSpecularGlossinessMaterial ) { + + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.diffuseTexture = baseColorMapDef; + + } + gltfMaterial.pbrMetallicRoughness.baseColorTexture = baseColorMapDef; } - if ( material.isMeshBasicMaterial || - material.isLineBasicMaterial || - material.isPointsMaterial ) { + // pbrSpecularGlossiness specular map + if ( material.isGLTFSpecularGlossinessMaterial && material.specularMap ) { - } else { + var specularMapDef = { index: processTexture( material.specularMap ) }; + applyTextureTransform( specularMapDef, material.specularMap ); + gltfMaterial.extensions.KHR_materials_pbrSpecularGlossiness.specularGlossinessTexture = specularMapDef; + + } + + if ( material.emissive ) { // emissiveFactor var emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity ).toArray(); @@ -1004,7 +1046,7 @@ THREE.GLTFExporter.prototype = { var normalMapDef = { index: processTexture( material.normalMap ) }; - if ( material.normalScale.x !== - 1 ) { + if ( material.normalScale && material.normalScale.x !== - 1 ) { if ( material.normalScale.x !== material.normalScale.y ) { @@ -1043,13 +1085,15 @@ THREE.GLTFExporter.prototype = { } // alphaMode - if ( material.transparent || material.alphaTest > 0.0 ) { + if ( material.transparent ) { + + gltfMaterial.alphaMode = 'BLEND'; - gltfMaterial.alphaMode = material.opacity < 1.0 ? 'BLEND' : 'MASK'; + } else { - // Write alphaCutoff if it's non-zero and different from the default (0.5). - if ( material.alphaTest > 0.0 && material.alphaTest !== 0.5 ) { + if ( material.alphaTest > 0.0 ) { + gltfMaterial.alphaMode = 'MASK'; gltfMaterial.alphaCutoff = material.alphaTest; } @@ -1087,10 +1131,25 @@ THREE.GLTFExporter.prototype = { */ function processMesh( mesh ) { - var cacheKey = mesh.geometry.uuid + ':' + mesh.material.uuid; - if ( cachedData.meshes.has( cacheKey ) ) { + var meshCacheKeyParts = [ mesh.geometry.uuid ]; + if ( Array.isArray( mesh.material ) ) { - return cachedData.meshes.get( cacheKey ); + for ( var i = 0, l = mesh.material.length; i < l; i ++ ) { + + meshCacheKeyParts.push( mesh.material[ i ].uuid ); + + } + + } else { + + meshCacheKeyParts.push( mesh.material.uuid ); + + } + + var meshCacheKey = meshCacheKeyParts.join( ':' ); + if ( cachedData.meshes.has( meshCacheKey ) ) { + + return cachedData.meshes.get( meshCacheKey ); } @@ -1127,20 +1186,7 @@ THREE.GLTFExporter.prototype = { } - if ( mesh.drawMode === THREE.TriangleFanDrawMode ) { - - console.warn( 'GLTFExporter: TriangleFanDrawMode and wireframe incompatible.' ); - mode = WEBGL_CONSTANTS.TRIANGLE_FAN; - - } else if ( mesh.drawMode === THREE.TriangleStripDrawMode ) { - - mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINE_STRIP : WEBGL_CONSTANTS.TRIANGLE_STRIP; - - } else { - - mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES; - - } + mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES; } @@ -1167,11 +1213,11 @@ THREE.GLTFExporter.prototype = { console.warn( 'THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.' ); - geometry.addAttribute( 'normal', createNormalizedNormalAttribute( originalNormal ) ); + geometry.setAttribute( 'normal', createNormalizedNormalAttribute( originalNormal ) ); } - // @QUESTION Detect if .vertexColors = THREE.VertexColors? + // @QUESTION Detect if .vertexColors = true? // For every attribute create an accessor var modifiedAttribute = null; for ( var attributeName in geometry.attributes ) { @@ -1221,7 +1267,7 @@ THREE.GLTFExporter.prototype = { } - if ( originalNormal !== undefined ) geometry.addAttribute( 'normal', originalNormal ); + if ( originalNormal !== undefined ) geometry.setAttribute( 'normal', originalNormal ); // Skip if no exportable attributes found if ( Object.keys( attributes ).length === 0 ) { @@ -1291,14 +1337,18 @@ THREE.GLTFExporter.prototype = { // Clones attribute not to override var relativeAttribute = attribute.clone(); - for ( var j = 0, jl = attribute.count; j < jl; j ++ ) { + if ( ! geometry.morphTargetsRelative ) { - relativeAttribute.setXYZ( - j, - attribute.getX( j ) - baseAttribute.getX( j ), - attribute.getY( j ) - baseAttribute.getY( j ), - attribute.getZ( j ) - baseAttribute.getZ( j ) - ); + for ( var j = 0, jl = attribute.count; j < jl; j ++ ) { + + relativeAttribute.setXYZ( + j, + attribute.getX( j ) - baseAttribute.getX( j ), + attribute.getY( j ) - baseAttribute.getY( j ), + attribute.getZ( j ) - baseAttribute.getZ( j ) + ); + + } } @@ -1424,7 +1474,7 @@ THREE.GLTFExporter.prototype = { outputJSON.meshes.push( gltfMesh ); var index = outputJSON.meshes.length - 1; - cachedData.meshes.set( cacheKey, index ); + cachedData.meshes.set( meshCacheKey, index ); return index; @@ -1467,7 +1517,7 @@ THREE.GLTFExporter.prototype = { gltfCamera.perspective = { aspectRatio: camera.aspect, - yfov: THREE.Math.degToRad( camera.fov ), + yfov: THREE.MathUtils.degToRad( camera.fov ), zfar: camera.far <= 0 ? 0.001 : camera.far, znear: camera.near < 0 ? 0 : camera.near @@ -1611,6 +1661,9 @@ THREE.GLTFExporter.prototype = { var node = outputJSON.nodes[ nodeMap.get( object ) ]; var skeleton = object.skeleton; + + if ( skeleton === undefined ) return null; + var rootJoint = object.skeleton.bones[ 0 ]; if ( rootJoint === undefined ) return null; @@ -1868,12 +1921,6 @@ THREE.GLTFExporter.prototype = { } - if ( scene.userData && Object.keys( scene.userData ).length > 0 ) { - - gltfScene.extras = serializeUserData( scene ); - - } - outputJSON.scenes.push( gltfScene ); var nodes = []; diff --git a/examples/js/exporters/OBJExporter.js b/examples/js/exporters/OBJExporter.js index 77fc4595d4d91d..28f2dc2ab6694c 100644 --- a/examples/js/exporters/OBJExporter.js +++ b/examples/js/exporters/OBJExporter.js @@ -105,7 +105,7 @@ THREE.OBJExporter.prototype = { normal.z = normals.getZ( i ); // transfrom the normal to world space - normal.applyMatrix3( normalMatrixWorld ); + normal.applyMatrix3( normalMatrixWorld ).normalize(); // transform the normal to export format output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n'; diff --git a/examples/js/exporters/PLYExporter.js b/examples/js/exporters/PLYExporter.js index 45602189ab3ec7..60c44a449cd489 100644 --- a/examples/js/exporters/PLYExporter.js +++ b/examples/js/exporters/PLYExporter.js @@ -144,22 +144,7 @@ THREE.PLYExporter.prototype = { } - // get how many bytes will be needed to save out the faces - // so we can use a minimal amount of memory / data - var indexByteCount = 1; - - if ( vertexCount > 256 ) { // 2^8 bits - - indexByteCount = 2; - - } - - if ( vertexCount > 65536 ) { // 2^16 bits - - indexByteCount = 4; - - } - + var indexByteCount = 4; var header = 'ply\n' + @@ -205,7 +190,7 @@ THREE.PLYExporter.prototype = { // faces header += `element face ${faceCount}\n` + - `property list uchar uint${ indexByteCount * 8 } vertex_index\n`; + `property list uchar int vertex_index\n`; } @@ -276,7 +261,7 @@ THREE.PLYExporter.prototype = { vertex.y = normals.getY( i ); vertex.z = normals.getZ( i ); - vertex.applyMatrix3( normalMatrixWorld ); + vertex.applyMatrix3( normalMatrixWorld ).normalize(); output.setFloat32( vOffset, vertex.x ); vOffset += 4; @@ -359,7 +344,7 @@ THREE.PLYExporter.prototype = { if ( includeIndices === true ) { // Create the face list - var faceIndexFunc = `setUint${indexByteCount * 8}`; + if ( indices !== null ) { for ( var i = 0, l = indices.count; i < l; i += 3 ) { @@ -367,13 +352,13 @@ THREE.PLYExporter.prototype = { output.setUint8( fOffset, 3 ); fOffset += 1; - output[ faceIndexFunc ]( fOffset, indices.getX( i + 0 ) + writtenVertices ); + output.setUint32( fOffset, indices.getX( i + 0 ) + writtenVertices ); fOffset += indexByteCount; - output[ faceIndexFunc ]( fOffset, indices.getX( i + 1 ) + writtenVertices ); + output.setUint32( fOffset, indices.getX( i + 1 ) + writtenVertices ); fOffset += indexByteCount; - output[ faceIndexFunc ]( fOffset, indices.getX( i + 2 ) + writtenVertices ); + output.setUint32( fOffset, indices.getX( i + 2 ) + writtenVertices ); fOffset += indexByteCount; } @@ -385,13 +370,13 @@ THREE.PLYExporter.prototype = { output.setUint8( fOffset, 3 ); fOffset += 1; - output[ faceIndexFunc ]( fOffset, writtenVertices + i ); + output.setUint32( fOffset, writtenVertices + i ); fOffset += indexByteCount; - output[ faceIndexFunc ]( fOffset, writtenVertices + i + 1 ); + output.setUint32( fOffset, writtenVertices + i + 1 ); fOffset += indexByteCount; - output[ faceIndexFunc ]( fOffset, writtenVertices + i + 2 ); + output.setUint32( fOffset, writtenVertices + i + 2 ); fOffset += indexByteCount; } @@ -452,7 +437,7 @@ THREE.PLYExporter.prototype = { vertex.y = normals.getY( i ); vertex.z = normals.getZ( i ); - vertex.applyMatrix3( normalMatrixWorld ); + vertex.applyMatrix3( normalMatrixWorld ).normalize(); line += ' ' + vertex.x + ' ' + @@ -537,7 +522,7 @@ THREE.PLYExporter.prototype = { } ); - result = `${ header }${vertexList}\n${ includeIndices ? `${faceList}\n` : '' }`; + result = `${ header }${vertexList}${ includeIndices ? `${faceList}\n` : '\n' }`; } diff --git a/examples/js/geometries/BoxLineGeometry.js b/examples/js/geometries/BoxLineGeometry.js index dfc9e1478450c5..d08c2430913efb 100644 --- a/examples/js/geometries/BoxLineGeometry.js +++ b/examples/js/geometries/BoxLineGeometry.js @@ -59,7 +59,7 @@ THREE.BoxLineGeometry = function ( width, height, depth, widthSegments, heightSe } - this.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); }; diff --git a/examples/js/geometries/ConvexGeometry.js b/examples/js/geometries/ConvexGeometry.js index 392bcf86582c65..6cbeb60fd2aa00 100644 --- a/examples/js/geometries/ConvexGeometry.js +++ b/examples/js/geometries/ConvexGeometry.js @@ -61,8 +61,8 @@ THREE.ConvexBufferGeometry = function ( points ) { // build geometry - this.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); }; diff --git a/examples/js/geometries/DecalGeometry.js b/examples/js/geometries/DecalGeometry.js index 58e06d272ae86f..8f4ee5d76579fb 100644 --- a/examples/js/geometries/DecalGeometry.js +++ b/examples/js/geometries/DecalGeometry.js @@ -44,9 +44,9 @@ THREE.DecalGeometry = function ( mesh, position, orientation, size ) { // build geometry - this.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); function generate() { diff --git a/examples/js/geometries/LightningStrike.js b/examples/js/geometries/LightningStrike.js index 3a05b34013326e..2d9939e6d27654 100644 --- a/examples/js/geometries/LightningStrike.js +++ b/examples/js/geometries/LightningStrike.js @@ -419,22 +419,22 @@ THREE.LightningStrike.prototype.createMesh = function () { this.setIndex( new THREE.Uint32BufferAttribute( this.indices, 1 ) ); this.positionAttribute = new THREE.Float32BufferAttribute( this.vertices, 3 ); - this.addAttribute( 'position', this.positionAttribute ); + this.setAttribute( 'position', this.positionAttribute ); if ( this.generateUVs ) { this.uvsAttribute = new THREE.Float32BufferAttribute( new Float32Array( this.uvs ), 2 ); - this.addAttribute( 'uv', this.uvsAttribute ); + this.setAttribute( 'uv', this.uvsAttribute ); } if ( ! this.isStatic ) { - this.index.dynamic = true; - this.positionAttribute.dynamic = true; + this.index.usage = THREE.DynamicDrawUsage; + this.positionAttribute.usage = THREE.DynamicDrawUsage; if ( this.generateUVs ) { - this.uvsAttribute.dynamic = true; + this.uvsAttribute.usage = THREE.DynamicDrawUsage; } @@ -577,8 +577,8 @@ THREE.LightningStrike.prototype.fractalRay = function ( time, segmentCallback ) this.randomGenerator.setSeed( subray.seed ); - subray.endPropagationTime = THREE.Math.lerp( subray.birthTime, subray.deathTime, subray.propagationTimeFactor ); - subray.beginVanishingTime = THREE.Math.lerp( subray.deathTime, subray.birthTime, 1 - subray.vanishingTimeFactor ); + subray.endPropagationTime = THREE.MathUtils.lerp( subray.birthTime, subray.deathTime, subray.propagationTimeFactor ); + subray.beginVanishingTime = THREE.MathUtils.lerp( subray.deathTime, subray.birthTime, 1 - subray.vanishingTimeFactor ); var random1 = this.randomGenerator.random; subray.linPos0.set( random1(), random1(), random1() ).multiplyScalar( 1000 ); @@ -823,7 +823,7 @@ THREE.LightningStrike.prototype.createDefaultSubrayCreationCallbacks = function var period = lightningStrike.rayParameters.subrayPeriod; var dutyCycle = lightningStrike.rayParameters.subrayDutyCycle; - var phase0 = ( lightningStrike.rayParameters.isEternal && subray.recursion == 0 ) ? - random1() * period : THREE.Math.lerp( subray.birthTime, subray.endPropagationTime, segment.fraction0 ) - random1() * period; + var phase0 = ( lightningStrike.rayParameters.isEternal && subray.recursion == 0 ) ? - random1() * period : THREE.MathUtils.lerp( subray.birthTime, subray.endPropagationTime, segment.fraction0 ) - random1() * period; var phase = lightningStrike.time - phase0; var currentCycle = Math.floor( phase / period ); diff --git a/examples/js/geometries/TeapotBufferGeometry.js b/examples/js/geometries/TeapotBufferGeometry.js index d29cfb1cd23d6b..7f51f69e4a6986 100644 --- a/examples/js/geometries/TeapotBufferGeometry.js +++ b/examples/js/geometries/TeapotBufferGeometry.js @@ -674,7 +674,7 @@ THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLi v4 = v1 + vertPerRow; // Normals and UVs cannot be shared. Without clone(), you can see the consequences - // of sharing if you call geometry.applyMatrix( matrix ). + // of sharing if you call geometry.applyMatrix4( matrix ). if ( notDegenerate( v1, v2, v3 ) ) { indices[ indexCount ++ ] = v1; @@ -702,9 +702,9 @@ THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLi } this.setIndex( new THREE.BufferAttribute( indices, 1 ) ); - this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); this.computeBoundingSphere(); diff --git a/examples/js/libs/basis/README.md b/examples/js/libs/basis/README.md index 295b7a544418d4..0c9961a3d8a262 100644 --- a/examples/js/libs/basis/README.md +++ b/examples/js/libs/basis/README.md @@ -36,7 +36,7 @@ basisLoader.load( 'diffuse.basis', function ( texture ) { ``` For further documentation about the Basis compressor and transcoder, refer to -the [Basis GitHub repository](https://github.com/BinomialLLC/basis_universal). The JavaScript wrapper requires one modification from the version provided in the Basis repository – the declaration on the first line is changed from `var Module` to `Module`, to accomodate lazy initialization in a Web Worker ([details](https://github.com/mrdoob/three.js/issues/16524)). +the [Basis GitHub repository](https://github.com/BinomialLLC/basis_universal). ## License diff --git a/examples/js/libs/basis/basis_transcoder.js b/examples/js/libs/basis/basis_transcoder.js index a64c35a4c16a7a..8e4ddc40f05b63 100644 --- a/examples/js/libs/basis/basis_transcoder.js +++ b/examples/js/libs/basis/basis_transcoder.js @@ -1 +1,21 @@ -Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=function(status,toThrow){throw toThrow};Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}else{return scriptDirectory+path}}if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/";var nodeFS;var nodePath;Module["read"]=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};Module["readBinary"]=function readBinary(filename){var ret=Module["read"](filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);Module["quit"]=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){Module["read"]=function shell_read(f){return read(f)}}Module["readBinary"]=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof quit==="function"){Module["quit"]=function(status){quit(status)}}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}Module["read"]=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){Module["readBinary"]=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}Module["readAsync"]=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};Module["setWindowTitle"]=function(title){document.title=title}}else{}var out=Module["print"]||(typeof console!=="undefined"?console.log.bind(console):typeof print!=="undefined"?print:null);var err=Module["printErr"]||(typeof printErr!=="undefined"?printErr:typeof console!=="undefined"&&console.warn.bind(console)||out);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=undefined;var asm2wasmImports={"f64-rem":function(x,y){return x%y},"debugger":function(){debugger}};var functionPointers=new Array(0);var tempRet0=0;var setTempRet0=function(value){tempRet0=value};if(typeof WebAssembly!=="object"){err("no native wasm support detected")}var wasmMemory;var wasmTable;var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(u8Array,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(u8Array[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferViews(){Module["HEAP8"]=HEAP8=new Int8Array(buffer);Module["HEAP16"]=HEAP16=new Int16Array(buffer);Module["HEAP32"]=HEAP32=new Int32Array(buffer);Module["HEAPU8"]=HEAPU8=new Uint8Array(buffer);Module["HEAPU16"]=HEAPU16=new Uint16Array(buffer);Module["HEAPU32"]=HEAPU32=new Uint32Array(buffer);Module["HEAPF32"]=HEAPF32=new Float32Array(buffer);Module["HEAPF64"]=HEAPF64=new Float64Array(buffer)}var DYNAMIC_BASE=5401280,DYNAMICTOP_PTR=158368;var TOTAL_STACK=5242880;var INITIAL_TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(INITIAL_TOTAL_MEMORY>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}var wasmBinaryFile="basis_transcoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(Module["wasmBinary"]){return new Uint8Array(Module["wasmBinary"])}if(Module["readBinary"]){return Module["readBinary"](wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!Module["wasmBinary"]&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(env){var info={"env":env,"global":{"NaN":NaN,Infinity:Infinity},"global.Math":Math,"asm2wasm":asm2wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}if(!Module["wasmBinary"]&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch==="function"){WebAssembly.instantiateStreaming(fetch(wasmBinaryFile,{credentials:"same-origin"}),info).then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");instantiateArrayBuffer(receiveInstantiatedSource)})}else{instantiateArrayBuffer(receiveInstantiatedSource)}return{}}Module["asm"]=function(global,env,providedBuffer){env["memory"]=wasmMemory;env["table"]=wasmTable=new WebAssembly.Table({"initial":70,"maximum":70,"element":"anyfunc"});env["__memory_base"]=1024;env["__table_base"]=0;var exports=createWasm(env);return exports};__ATINIT__.push({func:function(){globalCtors()}});function ___cxa_allocate_exception(size){return _malloc(size)}function __ZSt18uncaught_exceptionv(){return!!__ZSt18uncaught_exceptionv.uncaught_exception}function ___cxa_free_exception(ptr){try{return _free(ptr)}catch(e){}}var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:function(adjusted){if(!adjusted||EXCEPTIONS.infos[adjusted])return adjusted;for(var key in EXCEPTIONS.infos){var ptr=+key;var adj=EXCEPTIONS.infos[ptr].adjusted;var len=adj.length;for(var i=0;i0);info.refcount--;if(info.refcount===0&&!info.rethrown){if(info.destructor){Module["dynCall_vi"](info.destructor,ptr)}delete EXCEPTIONS.infos[ptr];___cxa_free_exception(ptr)}},clearRef:function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount=0}};function ___cxa_throw(ptr,type,destructor){EXCEPTIONS.infos[ptr]={ptr:ptr,adjusted:[ptr],type:type,destructor:destructor,refcount:0,caught:false,rethrown:false};EXCEPTIONS.last=ptr;if(!("uncaught_exception"in __ZSt18uncaught_exceptionv)){__ZSt18uncaught_exceptionv.uncaught_exception=1}else{__ZSt18uncaught_exceptionv.uncaught_exception++}throw ptr}var SYSCALLS={buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:0,get:function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(){var ret=UTF8ToString(SYSCALLS.get());return ret},get64:function(){var low=SYSCALLS.get(),high=SYSCALLS.get();return low},getZero:function(){SYSCALLS.get()}};function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall146(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.get(),iov=SYSCALLS.get(),iovcnt=SYSCALLS.get();var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}});clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function runDestructor(handle){var $$=handle.$$;if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}this.$$.count.value-=1;var toDelete=0===this.$$.count.value;if(toDelete){runDestructor(this)}if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return Object.create(prototype,{$$:{value:record}})}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(dynCall){var args=[];for(var i=1;i>2)+i])}return array}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}var destructors=[];var args=new Array(argCount);args[0]=rawConstructor;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap["buffer"],data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var endChar=HEAPU8[value+4+length];var endCharSwap=0;if(endChar!=0){endCharSwap=endChar;HEAPU8[value+4+length]=0}var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(HEAPU8[currentBytePtr]==0){var stringSegment=UTF8ToString(decodeStartPtr);if(str===undefined)str=stringSegment;else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}if(endCharSwap!=0)HEAPU8[value+4+length]=endCharSwap}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var a=new Array(length);var start=value+4>>shift;for(var i=0;i>2]=length;var start=ptr+4>>shift;for(var i=0;i>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_get_global(){return function(){return Function}()("return this")()}function __emval_get_global(name){if(name===0){return __emval_register(emval_get_global())}else{name=getStringOrSymbol(name);return __emval_register(emval_get_global()[name])}}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes,argWireTypes){var a=new Array(argCount);for(var i=0;i>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function craftEmvalAllocator(argCount){var argsList="";for(var i=0;i> 2) + "+i+'], "parameter '+i+'");\n'+"var arg"+i+" = argType"+i+".readValueFromPointer(args);\n"+"args += argType"+i+"['argPackAdvance'];\n"}functionBody+="var obj = new constructor("+argsList+");\n"+"return __emval_register(obj);\n"+"}\n";return new Function("requireRegisteredType","Module","__emval_register",functionBody)(requireRegisteredType,Module,__emval_register)}var emval_newers={};function __emval_new(handle,argCount,argTypes,args){handle=requireHandle(handle);var newer=emval_newers[argCount];if(!newer){newer=craftEmvalAllocator(argCount);emval_newers[argCount]=newer}return newer(handle,argTypes,args)}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function _abort(){Module["abort"]()}function _emscripten_get_heap_size(){return HEAP8.length}function abortOnCannotGrowMemory(requestedSize){abort("OOM")}function emscripten_realloc_buffer(size){var PAGE_MULTIPLE=65536;size=alignUp(size,PAGE_MULTIPLE);var oldSize=buffer.byteLength;try{var result=wasmMemory.grow((size-oldSize)/65536);if(result!==(-1|0)){buffer=wasmMemory.buffer;return true}else{return false}}catch(e){return false}}function _emscripten_resize_heap(requestedSize){var oldSize=_emscripten_get_heap_size();var PAGE_MULTIPLE=65536;var LIMIT=2147483648-PAGE_MULTIPLE;if(requestedSize>LIMIT){return false}var MIN_TOTAL_MEMORY=16777216;var newSize=Math.max(oldSize,MIN_TOTAL_MEMORY);while(newSize>2]=value;return value}embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var asmGlobalArg={};var asmLibraryArg={"d":abort,"B":setTempRet0,"i":___cxa_allocate_exception,"h":___cxa_throw,"n":___setErrNo,"A":___syscall140,"m":___syscall146,"z":___syscall6,"y":__embind_register_bool,"x":__embind_register_class,"w":__embind_register_class_constructor,"g":__embind_register_class_function,"K":__embind_register_emval,"v":__embind_register_float,"J":__embind_register_function,"f":__embind_register_integer,"c":__embind_register_memory_view,"u":__embind_register_std_string,"I":__embind_register_std_wstring,"H":__embind_register_void,"t":__emval_as,"s":__emval_call_void_method,"b":__emval_decref,"G":__emval_get_global,"r":__emval_get_method_caller,"q":__emval_get_module_property,"k":__emval_get_property,"l":__emval_incref,"p":__emval_new,"j":__emval_new_cstring,"o":__emval_run_destructors,"e":_abort,"F":_emscripten_get_heap_size,"E":_emscripten_memcpy_big,"D":_emscripten_resize_heap,"C":abortOnCannotGrowMemory,"a":DYNAMICTOP_PTR};var asm=Module["asm"](asmGlobalArg,asmLibraryArg,buffer);Module["asm"]=asm;var ___errno_location=Module["___errno_location"]=function(){return Module["asm"]["L"].apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return Module["asm"]["M"].apply(null,arguments)};var _free=Module["_free"]=function(){return Module["asm"]["N"].apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return Module["asm"]["O"].apply(null,arguments)};var globalCtors=Module["globalCtors"]=function(){return Module["asm"]["ca"].apply(null,arguments)};var dynCall_ii=Module["dynCall_ii"]=function(){return Module["asm"]["P"].apply(null,arguments)};var dynCall_iidiiii=Module["dynCall_iidiiii"]=function(){return Module["asm"]["Q"].apply(null,arguments)};var dynCall_iii=Module["dynCall_iii"]=function(){return Module["asm"]["R"].apply(null,arguments)};var dynCall_iiii=Module["dynCall_iiii"]=function(){return Module["asm"]["S"].apply(null,arguments)};var dynCall_iiiii=Module["dynCall_iiiii"]=function(){return Module["asm"]["T"].apply(null,arguments)};var dynCall_iiiiii=Module["dynCall_iiiiii"]=function(){return Module["asm"]["U"].apply(null,arguments)};var dynCall_iiiiiiii=Module["dynCall_iiiiiiii"]=function(){return Module["asm"]["V"].apply(null,arguments)};var dynCall_iiiiiiiii=Module["dynCall_iiiiiiiii"]=function(){return Module["asm"]["W"].apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return Module["asm"]["X"].apply(null,arguments)};var dynCall_v=Module["dynCall_v"]=function(){return Module["asm"]["Y"].apply(null,arguments)};var dynCall_vi=Module["dynCall_vi"]=function(){return Module["asm"]["Z"].apply(null,arguments)};var dynCall_vii=Module["dynCall_vii"]=function(){return Module["asm"]["_"].apply(null,arguments)};var dynCall_viiii=Module["dynCall_viiii"]=function(){return Module["asm"]["$"].apply(null,arguments)};var dynCall_viiiii=Module["dynCall_viiiii"]=function(){return Module["asm"]["aa"].apply(null,arguments)};var dynCall_viiiiii=Module["dynCall_viiiiii"]=function(){return Module["asm"]["ba"].apply(null,arguments)};Module["asm"]=asm;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};function run(args){args=args||Module["arguments"];if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(what!==undefined){out(what);err(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;throw"abort("+what+"). Build with -s ASSERTIONS=1 for more info."}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}Module["noExitRuntime"]=true;run(); + +var BASIS = (function() { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + return ( +function(BASIS) { + BASIS = BASIS || {}; + +var Module=typeof BASIS!=="undefined"?BASIS:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_HAS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_HAS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_NODE=ENVIRONMENT_HAS_NODE&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/";var nodeFS;var nodePath;read_=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var asm2wasmImports={"f64-rem":function(x,y){return x%y},"debugger":function(){}};var functionPointers=new Array(0);var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){err("no native wasm support detected")}var wasmMemory;var wasmTable;var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(u8Array,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(u8Array[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var DYNAMIC_BASE=5482368,DYNAMICTOP_PTR=239456;var INITIAL_TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_TOTAL_MEMORY/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_TOTAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}var wasmBinaryFile="basis_transcoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(env){var info={"env":env,"wasi_unstable":env,"global":{"NaN":NaN,Infinity:Infinity},"global.Math":Math,"asm2wasm":asm2wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}Module["asm"]=function(global,env,providedBuffer){env["memory"]=wasmMemory;env["table"]=wasmTable=new WebAssembly.Table({"initial":342,"maximum":342,"element":"anyfunc"});env["__memory_base"]=1024;env["__table_base"]=0;var exports=createWasm(env);return exports};__ATINIT__.push({func:function(){globalCtors()}});function ___cxa_allocate_exception(size){return _malloc(size)}var ___exception_infos={};function ___cxa_pure_virtual(){ABORT=true;throw"Pure virtual function called!"}var ___exception_last=0;function ___cxa_throw(ptr,type,destructor){___exception_infos[ptr]={ptr:ptr,adjusted:[ptr],type:type,destructor:destructor,refcount:0,caught:false,rethrown:false};___exception_last=ptr;if(!("uncaught_exception"in __ZSt18uncaught_exceptionv)){__ZSt18uncaught_exceptionv.uncaught_exceptions=1}else{__ZSt18uncaught_exceptionv.uncaught_exceptions++}throw ptr}function ___cxa_uncaught_exceptions(){return __ZSt18uncaught_exceptionv.uncaught_exceptions}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};var SYSCALLS={buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:0,get:function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(){var ret=UTF8ToString(SYSCALLS.get());return ret},get64:function(){var low=SYSCALLS.get(),high=SYSCALLS.get();return low},getZero:function(){SYSCALLS.get()}};function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall6(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD();return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function _fd_write(stream,iov,iovcnt,pnum){try{var num=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___wasi_fd_write(){return _fd_write.apply(null,arguments)}function getShiftFromSize(size){switch(size){case 1:return 0;case 2:return 1;case 4:return 2;case 8:return 3;default:throw new TypeError("Unknown type size: "+size)}}function embind_init_charCodes(){var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes}var embind_charCodes=undefined;function readLatin1String(ptr){var ret="";var c=ptr;while(HEAPU8[c]){ret+=embind_charCodes[HEAPU8[c++]]}return ret}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var BindingError=undefined;function throwBindingError(message){throw new BindingError(message)}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function embind__requireFunction(signature,rawFunction){signature=readLatin1String(signature);function makeDynCaller(dynCall){var args=[];for(var i=1;i>2)+i])}return array}function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}var destructors=[];var args=new Array(argCount);args[0]=rawConstructor;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(heap["buffer"],data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var endChar=HEAPU8[value+4+length];var endCharSwap=0;if(endChar!=0){endCharSwap=endChar;HEAPU8[value+4+length]=0}var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(HEAPU8[currentBytePtr]==0){var stringSegment=UTF8ToString(decodeStartPtr);if(str===undefined)str=stringSegment;else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}if(endCharSwap!=0)HEAPU8[value+4+length]=endCharSwap}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var a=new Array(length);var start=value+4>>shift;for(var i=0;i>2]=length;var start=ptr+4>>shift;for(var i=0;i>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_get_global(){if(typeof globalThis==="object"){return globalThis}return function(){return Function}()("return this")()}function __emval_get_global(name){if(name===0){return __emval_register(emval_get_global())}else{name=getStringOrSymbol(name);return __emval_register(emval_get_global()[name])}}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes,argWireTypes){var a=new Array(argCount);for(var i=0;i>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function craftEmvalAllocator(argCount){var argsList="";for(var i=0;i> 2) + "+i+'], "parameter '+i+'");\n'+"var arg"+i+" = argType"+i+".readValueFromPointer(args);\n"+"args += argType"+i+"['argPackAdvance'];\n"}functionBody+="var obj = new constructor("+argsList+");\n"+"return __emval_register(obj);\n"+"}\n";return new Function("requireRegisteredType","Module","__emval_register",functionBody)(requireRegisteredType,Module,__emval_register)}var emval_newers={};function __emval_new(handle,argCount,argTypes,args){handle=requireHandle(handle);var newer=emval_newers[argCount];if(!newer){newer=craftEmvalAllocator(argCount);emval_newers[argCount]=newer}return newer(handle,argTypes,args)}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function _abort(){Module["abort"]()}function _emscripten_get_heap_size(){return HEAP8.length}function _llvm_trap(){abort("trap!")}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest)}function ___setErrNo(value){if(Module["___errno_location"])HEAP32[Module["___errno_location"]()>>2]=value;return value}function abortOnCannotGrowMemory(requestedSize){abort("OOM")}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=_emscripten_get_heap_size();var PAGE_MULTIPLE=65536;var LIMIT=2147483648-PAGE_MULTIPLE;if(requestedSize>LIMIT){return false}var MIN_TOTAL_MEMORY=16777216;var newSize=Math.max(oldSize,MIN_TOTAL_MEMORY);while(newSize0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;throw"abort("+what+"). Build with -s ASSERTIONS=1 for more info."}Module["abort"]=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); + + + return BASIS +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = BASIS; + else if (typeof define === 'function' && define['amd']) + define([], function() { return BASIS; }); + else if (typeof exports === 'object') + exports["BASIS"] = BASIS; + \ No newline at end of file diff --git a/examples/js/libs/basis/basis_transcoder.wasm b/examples/js/libs/basis/basis_transcoder.wasm index c5b4d204411003..9298699dae5f4e 100644 Binary files a/examples/js/libs/basis/basis_transcoder.wasm and b/examples/js/libs/basis/basis_transcoder.wasm differ diff --git a/examples/js/libs/cannon.js b/examples/js/libs/cannon.js new file mode 100644 index 00000000000000..331ecc5fec8adc --- /dev/null +++ b/examples/js/libs/cannon.js @@ -0,0 +1,13687 @@ +/* + * Copyright (c) 2015 cannon.js Authors + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&false)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.CANNON=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o (http://steffe.se)", + "keywords": [ + "cannon.js", + "cannon", + "physics", + "engine", + "3d" + ], + "main": "./build/cannon.js", + "engines": { + "node": "*" + }, + "repository": { + "type": "git", + "url": "https://github.com/schteppe/cannon.js.git" + }, + "bugs": { + "url": "https://github.com/schteppe/cannon.js/issues" + }, + "licenses": [ + { + "type": "MIT" + } + ], + "devDependencies": { + "jshint": "latest", + "uglify-js": "latest", + "nodeunit": "^0.9.0", + "grunt": "~0.4.0", + "grunt-contrib-jshint": "~0.1.1", + "grunt-contrib-nodeunit": "^0.4.1", + "grunt-contrib-concat": "~0.1.3", + "grunt-contrib-uglify": "^0.5.1", + "grunt-browserify": "^2.1.4", + "grunt-contrib-yuidoc": "^0.5.2", + "browserify": "*" + }, + "dependencies": {} +} + +},{}],2:[function(_dereq_,module,exports){ +// Export classes +module.exports = { + version : _dereq_('../package.json').version, + + AABB : _dereq_('./collision/AABB'), + ArrayCollisionMatrix : _dereq_('./collision/ArrayCollisionMatrix'), + Body : _dereq_('./objects/Body'), + Box : _dereq_('./shapes/Box'), + Broadphase : _dereq_('./collision/Broadphase'), + Constraint : _dereq_('./constraints/Constraint'), + ContactEquation : _dereq_('./equations/ContactEquation'), + Narrowphase : _dereq_('./world/Narrowphase'), + ConeTwistConstraint : _dereq_('./constraints/ConeTwistConstraint'), + ContactMaterial : _dereq_('./material/ContactMaterial'), + ConvexPolyhedron : _dereq_('./shapes/ConvexPolyhedron'), + Cylinder : _dereq_('./shapes/Cylinder'), + DistanceConstraint : _dereq_('./constraints/DistanceConstraint'), + Equation : _dereq_('./equations/Equation'), + EventTarget : _dereq_('./utils/EventTarget'), + FrictionEquation : _dereq_('./equations/FrictionEquation'), + GSSolver : _dereq_('./solver/GSSolver'), + GridBroadphase : _dereq_('./collision/GridBroadphase'), + Heightfield : _dereq_('./shapes/Heightfield'), + HingeConstraint : _dereq_('./constraints/HingeConstraint'), + LockConstraint : _dereq_('./constraints/LockConstraint'), + Mat3 : _dereq_('./math/Mat3'), + Material : _dereq_('./material/Material'), + NaiveBroadphase : _dereq_('./collision/NaiveBroadphase'), + ObjectCollisionMatrix : _dereq_('./collision/ObjectCollisionMatrix'), + Pool : _dereq_('./utils/Pool'), + Particle : _dereq_('./shapes/Particle'), + Plane : _dereq_('./shapes/Plane'), + PointToPointConstraint : _dereq_('./constraints/PointToPointConstraint'), + Quaternion : _dereq_('./math/Quaternion'), + Ray : _dereq_('./collision/Ray'), + RaycastVehicle : _dereq_('./objects/RaycastVehicle'), + RaycastResult : _dereq_('./collision/RaycastResult'), + RigidVehicle : _dereq_('./objects/RigidVehicle'), + RotationalEquation : _dereq_('./equations/RotationalEquation'), + RotationalMotorEquation : _dereq_('./equations/RotationalMotorEquation'), + SAPBroadphase : _dereq_('./collision/SAPBroadphase'), + SPHSystem : _dereq_('./objects/SPHSystem'), + Shape : _dereq_('./shapes/Shape'), + Solver : _dereq_('./solver/Solver'), + Sphere : _dereq_('./shapes/Sphere'), + SplitSolver : _dereq_('./solver/SplitSolver'), + Spring : _dereq_('./objects/Spring'), + Trimesh : _dereq_('./shapes/Trimesh'), + Vec3 : _dereq_('./math/Vec3'), + Vec3Pool : _dereq_('./utils/Vec3Pool'), + World : _dereq_('./world/World'), +}; + +},{"../package.json":1,"./collision/AABB":3,"./collision/ArrayCollisionMatrix":4,"./collision/Broadphase":5,"./collision/GridBroadphase":6,"./collision/NaiveBroadphase":7,"./collision/ObjectCollisionMatrix":8,"./collision/Ray":9,"./collision/RaycastResult":10,"./collision/SAPBroadphase":11,"./constraints/ConeTwistConstraint":12,"./constraints/Constraint":13,"./constraints/DistanceConstraint":14,"./constraints/HingeConstraint":15,"./constraints/LockConstraint":16,"./constraints/PointToPointConstraint":17,"./equations/ContactEquation":19,"./equations/Equation":20,"./equations/FrictionEquation":21,"./equations/RotationalEquation":22,"./equations/RotationalMotorEquation":23,"./material/ContactMaterial":24,"./material/Material":25,"./math/Mat3":27,"./math/Quaternion":28,"./math/Vec3":30,"./objects/Body":31,"./objects/RaycastVehicle":32,"./objects/RigidVehicle":33,"./objects/SPHSystem":34,"./objects/Spring":35,"./shapes/Box":37,"./shapes/ConvexPolyhedron":38,"./shapes/Cylinder":39,"./shapes/Heightfield":40,"./shapes/Particle":41,"./shapes/Plane":42,"./shapes/Shape":43,"./shapes/Sphere":44,"./shapes/Trimesh":45,"./solver/GSSolver":46,"./solver/Solver":47,"./solver/SplitSolver":48,"./utils/EventTarget":49,"./utils/Pool":51,"./utils/Vec3Pool":54,"./world/Narrowphase":55,"./world/World":56}],3:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); +var Utils = _dereq_('../utils/Utils'); + +module.exports = AABB; + +/** + * Axis aligned bounding box class. + * @class AABB + * @constructor + * @param {Object} [options] + * @param {Vec3} [options.upperBound] + * @param {Vec3} [options.lowerBound] + */ +function AABB(options){ + options = options || {}; + + /** + * The lower bound of the bounding box. + * @property lowerBound + * @type {Vec3} + */ + this.lowerBound = new Vec3(); + if(options.lowerBound){ + this.lowerBound.copy(options.lowerBound); + } + + /** + * The upper bound of the bounding box. + * @property upperBound + * @type {Vec3} + */ + this.upperBound = new Vec3(); + if(options.upperBound){ + this.upperBound.copy(options.upperBound); + } +} + +var tmp = new Vec3(); + +/** + * Set the AABB bounds from a set of points. + * @method setFromPoints + * @param {Array} points An array of Vec3's. + * @param {Vec3} position + * @param {Quaternion} quaternion + * @param {number} skinSize + * @return {AABB} The self object + */ +AABB.prototype.setFromPoints = function(points, position, quaternion, skinSize){ + var l = this.lowerBound, + u = this.upperBound, + q = quaternion; + + // Set to the first point + l.copy(points[0]); + if(q){ + q.vmult(l, l); + } + u.copy(l); + + for(var i = 1; i u.x){ u.x = p.x; } + if(p.x < l.x){ l.x = p.x; } + if(p.y > u.y){ u.y = p.y; } + if(p.y < l.y){ l.y = p.y; } + if(p.z > u.z){ u.z = p.z; } + if(p.z < l.z){ l.z = p.z; } + } + + // Add offset + if (position) { + position.vadd(l, l); + position.vadd(u, u); + } + + if(skinSize){ + l.x -= skinSize; + l.y -= skinSize; + l.z -= skinSize; + u.x += skinSize; + u.y += skinSize; + u.z += skinSize; + } + + return this; +}; + +/** + * Copy bounds from an AABB to this AABB + * @method copy + * @param {AABB} aabb Source to copy from + * @return {AABB} The this object, for chainability + */ +AABB.prototype.copy = function(aabb){ + this.lowerBound.copy(aabb.lowerBound); + this.upperBound.copy(aabb.upperBound); + return this; +}; + +/** + * Clone an AABB + * @method clone + */ +AABB.prototype.clone = function(){ + return new AABB().copy(this); +}; + +/** + * Extend this AABB so that it covers the given AABB too. + * @method extend + * @param {AABB} aabb + */ +AABB.prototype.extend = function(aabb){ + // Extend lower bound + var l = aabb.lowerBound.x; + if(this.lowerBound.x > l){ + this.lowerBound.x = l; + } + + // Upper + var u = aabb.upperBound.x; + if(this.upperBound.x < u){ + this.upperBound.x = u; + } + + // Extend lower bound + var l = aabb.lowerBound.y; + if(this.lowerBound.y > l){ + this.lowerBound.y = l; + } + + // Upper + var u = aabb.upperBound.y; + if(this.upperBound.y < u){ + this.upperBound.y = u; + } + + // Extend lower bound + var l = aabb.lowerBound.z; + if(this.lowerBound.z > l){ + this.lowerBound.z = l; + } + + // Upper + var u = aabb.upperBound.z; + if(this.upperBound.z < u){ + this.upperBound.z = u; + } +}; + +/** + * Returns true if the given AABB overlaps this AABB. + * @method overlaps + * @param {AABB} aabb + * @return {Boolean} + */ +AABB.prototype.overlaps = function(aabb){ + var l1 = this.lowerBound, + u1 = this.upperBound, + l2 = aabb.lowerBound, + u2 = aabb.upperBound; + + // l2 u2 + // |---------| + // |--------| + // l1 u1 + + return ((l2.x <= u1.x && u1.x <= u2.x) || (l1.x <= u2.x && u2.x <= u1.x)) && + ((l2.y <= u1.y && u1.y <= u2.y) || (l1.y <= u2.y && u2.y <= u1.y)) && + ((l2.z <= u1.z && u1.z <= u2.z) || (l1.z <= u2.z && u2.z <= u1.z)); +}; + +/** + * Returns true if the given AABB is fully contained in this AABB. + * @method contains + * @param {AABB} aabb + * @return {Boolean} + */ +AABB.prototype.contains = function(aabb){ + var l1 = this.lowerBound, + u1 = this.upperBound, + l2 = aabb.lowerBound, + u2 = aabb.upperBound; + + // l2 u2 + // |---------| + // |---------------| + // l1 u1 + + return ( + (l1.x <= l2.x && u1.x >= u2.x) && + (l1.y <= l2.y && u1.y >= u2.y) && + (l1.z <= l2.z && u1.z >= u2.z) + ); +}; + +/** + * @method getCorners + * @param {Vec3} a + * @param {Vec3} b + * @param {Vec3} c + * @param {Vec3} d + * @param {Vec3} e + * @param {Vec3} f + * @param {Vec3} g + * @param {Vec3} h + */ +AABB.prototype.getCorners = function(a, b, c, d, e, f, g, h){ + var l = this.lowerBound, + u = this.upperBound; + + a.copy(l); + b.set( u.x, l.y, l.z ); + c.set( u.x, u.y, l.z ); + d.set( l.x, u.y, u.z ); + e.set( u.x, l.y, l.z ); + f.set( l.x, u.y, l.z ); + g.set( l.x, l.y, u.z ); + h.copy(u); +}; + +var transformIntoFrame_corners = [ + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3() +]; + +/** + * Get the representation of an AABB in another frame. + * @method toLocalFrame + * @param {Transform} frame + * @param {AABB} target + * @return {AABB} The "target" AABB object. + */ +AABB.prototype.toLocalFrame = function(frame, target){ + + var corners = transformIntoFrame_corners; + var a = corners[0]; + var b = corners[1]; + var c = corners[2]; + var d = corners[3]; + var e = corners[4]; + var f = corners[5]; + var g = corners[6]; + var h = corners[7]; + + // Get corners in current frame + this.getCorners(a, b, c, d, e, f, g, h); + + // Transform them to new local frame + for(var i=0; i !== 8; i++){ + var corner = corners[i]; + frame.pointToLocal(corner, corner); + } + + return target.setFromPoints(corners); +}; + +/** + * Get the representation of an AABB in the global frame. + * @method toWorldFrame + * @param {Transform} frame + * @param {AABB} target + * @return {AABB} The "target" AABB object. + */ +AABB.prototype.toWorldFrame = function(frame, target){ + + var corners = transformIntoFrame_corners; + var a = corners[0]; + var b = corners[1]; + var c = corners[2]; + var d = corners[3]; + var e = corners[4]; + var f = corners[5]; + var g = corners[6]; + var h = corners[7]; + + // Get corners in current frame + this.getCorners(a, b, c, d, e, f, g, h); + + // Transform them to new local frame + for(var i=0; i !== 8; i++){ + var corner = corners[i]; + frame.pointToWorld(corner, corner); + } + + return target.setFromPoints(corners); +}; + +},{"../math/Vec3":30,"../utils/Utils":53}],4:[function(_dereq_,module,exports){ +module.exports = ArrayCollisionMatrix; + +/** + * Collision "matrix". It's actually a triangular-shaped array of whether two bodies are touching this step, for reference next step + * @class ArrayCollisionMatrix + * @constructor + */ +function ArrayCollisionMatrix() { + + /** + * The matrix storage + * @property matrix + * @type {Array} + */ + this.matrix = []; +} + +/** + * Get an element + * @method get + * @param {Number} i + * @param {Number} j + * @return {Number} + */ +ArrayCollisionMatrix.prototype.get = function(i, j) { + i = i.index; + j = j.index; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + return this.matrix[(i*(i + 1)>>1) + j-1]; +}; + +/** + * Set an element + * @method set + * @param {Number} i + * @param {Number} j + * @param {Number} value + */ +ArrayCollisionMatrix.prototype.set = function(i, j, value) { + i = i.index; + j = j.index; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + this.matrix[(i*(i + 1)>>1) + j-1] = value ? 1 : 0; +}; + +/** + * Sets all elements to zero + * @method reset + */ +ArrayCollisionMatrix.prototype.reset = function() { + for (var i=0, l=this.matrix.length; i!==l; i++) { + this.matrix[i]=0; + } +}; + +/** + * Sets the max number of objects + * @method setNumObjects + * @param {Number} n + */ +ArrayCollisionMatrix.prototype.setNumObjects = function(n) { + this.matrix.length = n*(n-1)>>1; +}; + +},{}],5:[function(_dereq_,module,exports){ +var Body = _dereq_('../objects/Body'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Shape = _dereq_('../shapes/Shape'); +var Plane = _dereq_('../shapes/Plane'); + +module.exports = Broadphase; + +/** + * Base class for broadphase implementations + * @class Broadphase + * @constructor + * @author schteppe + */ +function Broadphase(){ + /** + * The world to search for collisions in. + * @property world + * @type {World} + */ + this.world = null; + + /** + * If set to true, the broadphase uses bounding boxes for intersection test, else it uses bounding spheres. + * @property useBoundingBoxes + * @type {Boolean} + */ + this.useBoundingBoxes = false; + + /** + * Set to true if the objects in the world moved. + * @property {Boolean} dirty + */ + this.dirty = true; +} + +/** + * Get the collision pairs from the world + * @method collisionPairs + * @param {World} world The world to search in + * @param {Array} p1 Empty array to be filled with body objects + * @param {Array} p2 Empty array to be filled with body objects + */ +Broadphase.prototype.collisionPairs = function(world,p1,p2){ + throw new Error("collisionPairs not implemented for this BroadPhase class!"); +}; + +/** + * Check if a body pair needs to be intersection tested at all. + * @method needBroadphaseCollision + * @param {Body} bodyA + * @param {Body} bodyB + * @return {bool} + */ +var Broadphase_needBroadphaseCollision_STATIC_OR_KINEMATIC = Body.STATIC | Body.KINEMATIC; +Broadphase.prototype.needBroadphaseCollision = function(bodyA,bodyB){ + + // Check collision filter masks + if( (bodyA.collisionFilterGroup & bodyB.collisionFilterMask)===0 || (bodyB.collisionFilterGroup & bodyA.collisionFilterMask)===0){ + return false; + } + + // Check types + if(((bodyA.type & Broadphase_needBroadphaseCollision_STATIC_OR_KINEMATIC)!==0 || bodyA.sleepState === Body.SLEEPING) && + ((bodyB.type & Broadphase_needBroadphaseCollision_STATIC_OR_KINEMATIC)!==0 || bodyB.sleepState === Body.SLEEPING)) { + // Both bodies are static, kinematic or sleeping. Skip. + return false; + } + + return true; +}; + +/** + * Check if the bounding volumes of two bodies intersect. + * @method intersectionTest + * @param {Body} bodyA + * @param {Body} bodyB + * @param {array} pairs1 + * @param {array} pairs2 + */ +Broadphase.prototype.intersectionTest = function(bodyA, bodyB, pairs1, pairs2){ + if(this.useBoundingBoxes){ + this.doBoundingBoxBroadphase(bodyA,bodyB,pairs1,pairs2); + } else { + this.doBoundingSphereBroadphase(bodyA,bodyB,pairs1,pairs2); + } +}; + +/** + * Check if the bounding spheres of two bodies are intersecting. + * @method doBoundingSphereBroadphase + * @param {Body} bodyA + * @param {Body} bodyB + * @param {Array} pairs1 bodyA is appended to this array if intersection + * @param {Array} pairs2 bodyB is appended to this array if intersection + */ +var Broadphase_collisionPairs_r = new Vec3(), // Temp objects + Broadphase_collisionPairs_normal = new Vec3(), + Broadphase_collisionPairs_quat = new Quaternion(), + Broadphase_collisionPairs_relpos = new Vec3(); +Broadphase.prototype.doBoundingSphereBroadphase = function(bodyA,bodyB,pairs1,pairs2){ + var r = Broadphase_collisionPairs_r; + bodyB.position.vsub(bodyA.position,r); + var boundingRadiusSum2 = Math.pow(bodyA.boundingRadius + bodyB.boundingRadius, 2); + var norm2 = r.norm2(); + if(norm2 < boundingRadiusSum2){ + pairs1.push(bodyA); + pairs2.push(bodyB); + } +}; + +/** + * Check if the bounding boxes of two bodies are intersecting. + * @method doBoundingBoxBroadphase + * @param {Body} bodyA + * @param {Body} bodyB + * @param {Array} pairs1 + * @param {Array} pairs2 + */ +Broadphase.prototype.doBoundingBoxBroadphase = function(bodyA,bodyB,pairs1,pairs2){ + if(bodyA.aabbNeedsUpdate){ + bodyA.computeAABB(); + } + if(bodyB.aabbNeedsUpdate){ + bodyB.computeAABB(); + } + + // Check AABB / AABB + if(bodyA.aabb.overlaps(bodyB.aabb)){ + pairs1.push(bodyA); + pairs2.push(bodyB); + } +}; + +/** + * Removes duplicate pairs from the pair arrays. + * @method makePairsUnique + * @param {Array} pairs1 + * @param {Array} pairs2 + */ +var Broadphase_makePairsUnique_temp = { keys:[] }, + Broadphase_makePairsUnique_p1 = [], + Broadphase_makePairsUnique_p2 = []; +Broadphase.prototype.makePairsUnique = function(pairs1,pairs2){ + var t = Broadphase_makePairsUnique_temp, + p1 = Broadphase_makePairsUnique_p1, + p2 = Broadphase_makePairsUnique_p2, + N = pairs1.length; + + for(var i=0; i!==N; i++){ + p1[i] = pairs1[i]; + p2[i] = pairs2[i]; + } + + pairs1.length = 0; + pairs2.length = 0; + + for(var i=0; i!==N; i++){ + var id1 = p1[i].id, + id2 = p2[i].id; + var key = id1 < id2 ? id1+","+id2 : id2+","+id1; + t[key] = i; + t.keys.push(key); + } + + for(var i=0; i!==t.keys.length; i++){ + var key = t.keys.pop(), + pairIndex = t[key]; + pairs1.push(p1[pairIndex]); + pairs2.push(p2[pairIndex]); + delete t[key]; + } +}; + +/** + * To be implemented by subcasses + * @method setWorld + * @param {World} world + */ +Broadphase.prototype.setWorld = function(world){ +}; + +/** + * Check if the bounding spheres of two bodies overlap. + * @method boundingSphereCheck + * @param {Body} bodyA + * @param {Body} bodyB + * @return {boolean} + */ +var bsc_dist = new Vec3(); +Broadphase.boundingSphereCheck = function(bodyA,bodyB){ + var dist = bsc_dist; + bodyA.position.vsub(bodyB.position,dist); + return Math.pow(bodyA.shape.boundingSphereRadius + bodyB.shape.boundingSphereRadius,2) > dist.norm2(); +}; + +/** + * Returns all the bodies within the AABB. + * @method aabbQuery + * @param {World} world + * @param {AABB} aabb + * @param {array} result An array to store resulting bodies in. + * @return {array} + */ +Broadphase.prototype.aabbQuery = function(world, aabb, result){ + console.warn('.aabbQuery is not implemented in this Broadphase subclass.'); + return []; +}; +},{"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Plane":42,"../shapes/Shape":43}],6:[function(_dereq_,module,exports){ +module.exports = GridBroadphase; + +var Broadphase = _dereq_('./Broadphase'); +var Vec3 = _dereq_('../math/Vec3'); +var Shape = _dereq_('../shapes/Shape'); + +/** + * Axis aligned uniform grid broadphase. + * @class GridBroadphase + * @constructor + * @extends Broadphase + * @todo Needs support for more than just planes and spheres. + * @param {Vec3} aabbMin + * @param {Vec3} aabbMax + * @param {Number} nx Number of boxes along x + * @param {Number} ny Number of boxes along y + * @param {Number} nz Number of boxes along z + */ +function GridBroadphase(aabbMin,aabbMax,nx,ny,nz){ + Broadphase.apply(this); + this.nx = nx || 10; + this.ny = ny || 10; + this.nz = nz || 10; + this.aabbMin = aabbMin || new Vec3(100,100,100); + this.aabbMax = aabbMax || new Vec3(-100,-100,-100); + var nbins = this.nx * this.ny * this.nz; + if (nbins <= 0) { + throw "GridBroadphase: Each dimension's n must be >0"; + } + this.bins = []; + this.binLengths = []; //Rather than continually resizing arrays (thrashing the memory), just record length and allow them to grow + this.bins.length = nbins; + this.binLengths.length = nbins; + for (var i=0;i= nx) { xoff0 = nx - 1; } + if (yoff0 < 0) { yoff0 = 0; } else if (yoff0 >= ny) { yoff0 = ny - 1; } + if (zoff0 < 0) { zoff0 = 0; } else if (zoff0 >= nz) { zoff0 = nz - 1; } + if (xoff1 < 0) { xoff1 = 0; } else if (xoff1 >= nx) { xoff1 = nx - 1; } + if (yoff1 < 0) { yoff1 = 0; } else if (yoff1 >= ny) { yoff1 = ny - 1; } + if (zoff1 < 0) { zoff1 = 0; } else if (zoff1 >= nz) { zoff1 = nz - 1; } + + xoff0 *= xstep; + yoff0 *= ystep; + zoff0 *= zstep; + xoff1 *= xstep; + yoff1 *= ystep; + zoff1 *= zstep; + + for (var xoff = xoff0; xoff <= xoff1; xoff += xstep) { + for (var yoff = yoff0; yoff <= yoff1; yoff += ystep) { + for (var zoff = zoff0; zoff <= zoff1; zoff += zstep) { + var idx = xoff+yoff+zoff; + bins[idx][binLengths[idx]++] = bi; + } + } + } + } + + // Put all bodies into the bins + for(var i=0; i!==N; i++){ + var bi = bodies[i]; + var si = bi.shape; + + switch(si.type){ + case SPHERE: + // Put in bin + // check if overlap with other bins + var x = bi.position.x, + y = bi.position.y, + z = bi.position.z; + var r = si.radius; + + addBoxToBins(x-r, y-r, z-r, x+r, y+r, z+r, bi); + break; + + case PLANE: + if(si.worldNormalNeedsUpdate){ + si.computeWorldNormal(bi.quaternion); + } + var planeNormal = si.worldNormal; + + //Relative position from origin of plane object to the first bin + //Incremented as we iterate through the bins + var xreset = xmin + binsizeX*0.5 - bi.position.x, + yreset = ymin + binsizeY*0.5 - bi.position.y, + zreset = zmin + binsizeZ*0.5 - bi.position.z; + + var d = GridBroadphase_collisionPairs_d; + d.set(xreset, yreset, zreset); + + for (var xi = 0, xoff = 0; xi !== nx; xi++, xoff += xstep, d.y = yreset, d.x += binsizeX) { + for (var yi = 0, yoff = 0; yi !== ny; yi++, yoff += ystep, d.z = zreset, d.y += binsizeY) { + for (var zi = 0, zoff = 0; zi !== nz; zi++, zoff += zstep, d.z += binsizeZ) { + if (d.dot(planeNormal) < binRadius) { + var idx = xoff + yoff + zoff; + bins[idx][binLengths[idx]++] = bi; + } + } + } + } + break; + + default: + if (bi.aabbNeedsUpdate) { + bi.computeAABB(); + } + + addBoxToBins( + bi.aabb.lowerBound.x, + bi.aabb.lowerBound.y, + bi.aabb.lowerBound.z, + bi.aabb.upperBound.x, + bi.aabb.upperBound.y, + bi.aabb.upperBound.z, + bi); + break; + } + } + + // Check each bin + for(var i=0; i!==Nbins; i++){ + var binLength = binLengths[i]; + //Skip bins with no potential collisions + if (binLength > 1) { + var bin = bins[i]; + + // Do N^2 broadphase inside + for(var xi=0; xi!==binLength; xi++){ + var bi = bin[xi]; + for(var yi=0; yi!==xi; yi++){ + var bj = bin[yi]; + if(this.needBroadphaseCollision(bi,bj)){ + this.intersectionTest(bi,bj,pairs1,pairs2); + } + } + } + } + } + +// for (var zi = 0, zoff=0; zi < nz; zi++, zoff+= zstep) { +// console.log("layer "+zi); +// for (var yi = 0, yoff=0; yi < ny; yi++, yoff += ystep) { +// var row = ''; +// for (var xi = 0, xoff=0; xi < nx; xi++, xoff += xstep) { +// var idx = xoff + yoff + zoff; +// row += ' ' + binLengths[idx]; +// } +// console.log(row); +// } +// } + + this.makePairsUnique(pairs1,pairs2); +}; + +},{"../math/Vec3":30,"../shapes/Shape":43,"./Broadphase":5}],7:[function(_dereq_,module,exports){ +module.exports = NaiveBroadphase; + +var Broadphase = _dereq_('./Broadphase'); +var AABB = _dereq_('./AABB'); + +/** + * Naive broadphase implementation, used in lack of better ones. + * @class NaiveBroadphase + * @constructor + * @description The naive broadphase looks at all possible pairs without restriction, therefore it has complexity N^2 (which is bad) + * @extends Broadphase + */ +function NaiveBroadphase(){ + Broadphase.apply(this); +} +NaiveBroadphase.prototype = new Broadphase(); +NaiveBroadphase.prototype.constructor = NaiveBroadphase; + +/** + * Get all the collision pairs in the physics world + * @method collisionPairs + * @param {World} world + * @param {Array} pairs1 + * @param {Array} pairs2 + */ +NaiveBroadphase.prototype.collisionPairs = function(world,pairs1,pairs2){ + var bodies = world.bodies, + n = bodies.length, + i,j,bi,bj; + + // Naive N^2 ftw! + for(i=0; i!==n; i++){ + for(j=0; j!==i; j++){ + + bi = bodies[i]; + bj = bodies[j]; + + if(!this.needBroadphaseCollision(bi,bj)){ + continue; + } + + this.intersectionTest(bi,bj,pairs1,pairs2); + } + } +}; + +var tmpAABB = new AABB(); + +/** + * Returns all the bodies within an AABB. + * @method aabbQuery + * @param {World} world + * @param {AABB} aabb + * @param {array} result An array to store resulting bodies in. + * @return {array} + */ +NaiveBroadphase.prototype.aabbQuery = function(world, aabb, result){ + result = result || []; + + for(var i = 0; i < world.bodies.length; i++){ + var b = world.bodies[i]; + + if(b.aabbNeedsUpdate){ + b.computeAABB(); + } + + // Ugly hack until Body gets aabb + if(b.aabb.overlaps(aabb)){ + result.push(b); + } + } + + return result; +}; +},{"./AABB":3,"./Broadphase":5}],8:[function(_dereq_,module,exports){ +module.exports = ObjectCollisionMatrix; + +/** + * Records what objects are colliding with each other + * @class ObjectCollisionMatrix + * @constructor + */ +function ObjectCollisionMatrix() { + + /** + * The matrix storage + * @property matrix + * @type {Object} + */ + this.matrix = {}; +} + +/** + * @method get + * @param {Number} i + * @param {Number} j + * @return {Number} + */ +ObjectCollisionMatrix.prototype.get = function(i, j) { + i = i.id; + j = j.id; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + return i+'-'+j in this.matrix; +}; + +/** + * @method set + * @param {Number} i + * @param {Number} j + * @param {Number} value + */ +ObjectCollisionMatrix.prototype.set = function(i, j, value) { + i = i.id; + j = j.id; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + if (value) { + this.matrix[i+'-'+j] = true; + } + else { + delete this.matrix[i+'-'+j]; + } +}; + +/** + * Empty the matrix + * @method reset + */ +ObjectCollisionMatrix.prototype.reset = function() { + this.matrix = {}; +}; + +/** + * Set max number of objects + * @method setNumObjects + * @param {Number} n + */ +ObjectCollisionMatrix.prototype.setNumObjects = function(n) { +}; + +},{}],9:[function(_dereq_,module,exports){ +module.exports = Ray; + +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Transform = _dereq_('../math/Transform'); +var ConvexPolyhedron = _dereq_('../shapes/ConvexPolyhedron'); +var Box = _dereq_('../shapes/Box'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var Shape = _dereq_('../shapes/Shape'); +var AABB = _dereq_('../collision/AABB'); + +/** + * A line in 3D space that intersects bodies and return points. + * @class Ray + * @constructor + * @param {Vec3} from + * @param {Vec3} to + */ +function Ray(from, to){ + /** + * @property {Vec3} from + */ + this.from = from ? from.clone() : new Vec3(); + + /** + * @property {Vec3} to + */ + this.to = to ? to.clone() : new Vec3(); + + /** + * @private + * @property {Vec3} _direction + */ + this._direction = new Vec3(); + + /** + * The precision of the ray. Used when checking parallelity etc. + * @property {Number} precision + */ + this.precision = 0.0001; + + /** + * Set to true if you want the Ray to take .collisionResponse flags into account on bodies and shapes. + * @property {Boolean} checkCollisionResponse + */ + this.checkCollisionResponse = true; + + /** + * If set to true, the ray skips any hits with normal.dot(rayDirection) < 0. + * @property {Boolean} skipBackfaces + */ + this.skipBackfaces = false; + + /** + * @property {number} collisionFilterMask + * @default -1 + */ + this.collisionFilterMask = -1; + + /** + * @property {number} collisionFilterGroup + * @default -1 + */ + this.collisionFilterGroup = -1; + + /** + * The intersection mode. Should be Ray.ANY, Ray.ALL or Ray.CLOSEST. + * @property {number} mode + */ + this.mode = Ray.ANY; + + /** + * Current result object. + * @property {RaycastResult} result + */ + this.result = new RaycastResult(); + + /** + * Will be set to true during intersectWorld() if the ray hit anything. + * @property {Boolean} hasHit + */ + this.hasHit = false; + + /** + * Current, user-provided result callback. Will be used if mode is Ray.ALL. + * @property {Function} callback + */ + this.callback = function(result){}; +} +Ray.prototype.constructor = Ray; + +Ray.CLOSEST = 1; +Ray.ANY = 2; +Ray.ALL = 4; + +var tmpAABB = new AABB(); +var tmpArray = []; + +/** + * Do itersection against all bodies in the given World. + * @method intersectWorld + * @param {World} world + * @param {object} options + * @return {Boolean} True if the ray hit anything, otherwise false. + */ +Ray.prototype.intersectWorld = function (world, options) { + this.mode = options.mode || Ray.ANY; + this.result = options.result || new RaycastResult(); + this.skipBackfaces = !!options.skipBackfaces; + this.collisionFilterMask = typeof(options.collisionFilterMask) !== 'undefined' ? options.collisionFilterMask : -1; + this.collisionFilterGroup = typeof(options.collisionFilterGroup) !== 'undefined' ? options.collisionFilterGroup : -1; + if(options.from){ + this.from.copy(options.from); + } + if(options.to){ + this.to.copy(options.to); + } + this.callback = options.callback || function(){}; + this.hasHit = false; + + this.result.reset(); + this._updateDirection(); + + this.getAABB(tmpAABB); + tmpArray.length = 0; + world.broadphase.aabbQuery(world, tmpAABB, tmpArray); + this.intersectBodies(tmpArray); + + return this.hasHit; +}; + +var v1 = new Vec3(), + v2 = new Vec3(); + +/* + * As per "Barycentric Technique" as named here http://www.blackpawn.com/texts/pointinpoly/default.html But without the division + */ +Ray.pointInTriangle = pointInTriangle; +function pointInTriangle(p, a, b, c) { + c.vsub(a,v0); + b.vsub(a,v1); + p.vsub(a,v2); + + var dot00 = v0.dot( v0 ); + var dot01 = v0.dot( v1 ); + var dot02 = v0.dot( v2 ); + var dot11 = v1.dot( v1 ); + var dot12 = v1.dot( v2 ); + + var u,v; + + return ( (u = dot11 * dot02 - dot01 * dot12) >= 0 ) && + ( (v = dot00 * dot12 - dot01 * dot02) >= 0 ) && + ( u + v < ( dot00 * dot11 - dot01 * dot01 ) ); +} + +/** + * Shoot a ray at a body, get back information about the hit. + * @method intersectBody + * @private + * @param {Body} body + * @param {RaycastResult} [result] Deprecated - set the result property of the Ray instead. + */ +var intersectBody_xi = new Vec3(); +var intersectBody_qi = new Quaternion(); +Ray.prototype.intersectBody = function (body, result) { + if(result){ + this.result = result; + this._updateDirection(); + } + var checkCollisionResponse = this.checkCollisionResponse; + + if(checkCollisionResponse && !body.collisionResponse){ + return; + } + + if((this.collisionFilterGroup & body.collisionFilterMask)===0 || (body.collisionFilterGroup & this.collisionFilterMask)===0){ + return; + } + + var xi = intersectBody_xi; + var qi = intersectBody_qi; + + for (var i = 0, N = body.shapes.length; i < N; i++) { + var shape = body.shapes[i]; + + if(checkCollisionResponse && !shape.collisionResponse){ + continue; // Skip + } + + body.quaternion.mult(body.shapeOrientations[i], qi); + body.quaternion.vmult(body.shapeOffsets[i], xi); + xi.vadd(body.position, xi); + + this.intersectShape( + shape, + qi, + xi, + body + ); + + if(this.result._shouldStop){ + break; + } + } +}; + +/** + * @method intersectBodies + * @param {Array} bodies An array of Body objects. + * @param {RaycastResult} [result] Deprecated + */ +Ray.prototype.intersectBodies = function (bodies, result) { + if(result){ + this.result = result; + this._updateDirection(); + } + + for ( var i = 0, l = bodies.length; !this.result._shouldStop && i < l; i ++ ) { + this.intersectBody(bodies[i]); + } +}; + +/** + * Updates the _direction vector. + * @private + * @method _updateDirection + */ +Ray.prototype._updateDirection = function(){ + this.to.vsub(this.from, this._direction); + this._direction.normalize(); +}; + +/** + * @method intersectShape + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectShape = function(shape, quat, position, body){ + var from = this.from; + + + // Checking boundingSphere + var distance = distanceFromIntersection(from, this._direction, position); + if ( distance > shape.boundingSphereRadius ) { + return; + } + + var intersectMethod = this[shape.type]; + if(intersectMethod){ + intersectMethod.call(this, shape, quat, position, body); + } +}; + +var vector = new Vec3(); +var normal = new Vec3(); +var intersectPoint = new Vec3(); + +var a = new Vec3(); +var b = new Vec3(); +var c = new Vec3(); +var d = new Vec3(); + +var tmpRaycastResult = new RaycastResult(); + +/** + * @method intersectBox + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectBox = function(shape, quat, position, body){ + return this.intersectConvex(shape.convexPolyhedronRepresentation, quat, position, body); +}; +Ray.prototype[Shape.types.BOX] = Ray.prototype.intersectBox; + +/** + * @method intersectPlane + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectPlane = function(shape, quat, position, body){ + var from = this.from; + var to = this.to; + var direction = this._direction; + + // Get plane normal + var worldNormal = new Vec3(0, 0, 1); + quat.vmult(worldNormal, worldNormal); + + var len = new Vec3(); + from.vsub(position, len); + var planeToFrom = len.dot(worldNormal); + to.vsub(position, len); + var planeToTo = len.dot(worldNormal); + + if(planeToFrom * planeToTo > 0){ + // "from" and "to" are on the same side of the plane... bail out + return; + } + + if(from.distanceTo(to) < planeToFrom){ + return; + } + + var n_dot_dir = worldNormal.dot(direction); + + if (Math.abs(n_dot_dir) < this.precision) { + // No intersection + return; + } + + var planePointToFrom = new Vec3(); + var dir_scaled_with_t = new Vec3(); + var hitPointWorld = new Vec3(); + + from.vsub(position, planePointToFrom); + var t = -worldNormal.dot(planePointToFrom) / n_dot_dir; + direction.scale(t, dir_scaled_with_t); + from.vadd(dir_scaled_with_t, hitPointWorld); + + this.reportIntersection(worldNormal, hitPointWorld, shape, body, -1); +}; +Ray.prototype[Shape.types.PLANE] = Ray.prototype.intersectPlane; + +/** + * Get the world AABB of the ray. + * @method getAABB + * @param {AABB} aabb + */ +Ray.prototype.getAABB = function(result){ + var to = this.to; + var from = this.from; + result.lowerBound.x = Math.min(to.x, from.x); + result.lowerBound.y = Math.min(to.y, from.y); + result.lowerBound.z = Math.min(to.z, from.z); + result.upperBound.x = Math.max(to.x, from.x); + result.upperBound.y = Math.max(to.y, from.y); + result.upperBound.z = Math.max(to.z, from.z); +}; + +var intersectConvexOptions = { + faceList: [0] +}; + +/** + * @method intersectHeightfield + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectHeightfield = function(shape, quat, position, body){ + var data = shape.data, + w = shape.elementSize, + worldPillarOffset = new Vec3(); + + // Convert the ray to local heightfield coordinates + var localRay = new Ray(this.from, this.to); + Transform.pointToLocalFrame(position, quat, localRay.from, localRay.from); + Transform.pointToLocalFrame(position, quat, localRay.to, localRay.to); + + // Get the index of the data points to test against + var index = []; + var iMinX = null; + var iMinY = null; + var iMaxX = null; + var iMaxY = null; + + var inside = shape.getIndexOfPosition(localRay.from.x, localRay.from.y, index, false); + if(inside){ + iMinX = index[0]; + iMinY = index[1]; + iMaxX = index[0]; + iMaxY = index[1]; + } + inside = shape.getIndexOfPosition(localRay.to.x, localRay.to.y, index, false); + if(inside){ + if (iMinX === null || index[0] < iMinX) { iMinX = index[0]; } + if (iMaxX === null || index[0] > iMaxX) { iMaxX = index[0]; } + if (iMinY === null || index[1] < iMinY) { iMinY = index[1]; } + if (iMaxY === null || index[1] > iMaxY) { iMaxY = index[1]; } + } + + if(iMinX === null){ + return; + } + + var minMax = []; + shape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); + var min = minMax[0]; + var max = minMax[1]; + + // // Bail out if the ray can't touch the bounding box + // // TODO + // var aabb = new AABB(); + // this.getAABB(aabb); + // if(aabb.intersects()){ + // return; + // } + + for(var i = iMinX; i <= iMaxX; i++){ + for(var j = iMinY; j <= iMaxY; j++){ + + if(this.result._shouldStop){ + return; + } + + // Lower triangle + shape.getConvexTrianglePillar(i, j, false); + Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset); + this.intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, intersectConvexOptions); + + if(this.result._shouldStop){ + return; + } + + // Upper triangle + shape.getConvexTrianglePillar(i, j, true); + Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset); + this.intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, intersectConvexOptions); + } + } +}; +Ray.prototype[Shape.types.HEIGHTFIELD] = Ray.prototype.intersectHeightfield; + +var Ray_intersectSphere_intersectionPoint = new Vec3(); +var Ray_intersectSphere_normal = new Vec3(); + +/** + * @method intersectSphere + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectSphere = function(shape, quat, position, body){ + var from = this.from, + to = this.to, + r = shape.radius; + + var a = Math.pow(to.x - from.x, 2) + Math.pow(to.y - from.y, 2) + Math.pow(to.z - from.z, 2); + var b = 2 * ((to.x - from.x) * (from.x - position.x) + (to.y - from.y) * (from.y - position.y) + (to.z - from.z) * (from.z - position.z)); + var c = Math.pow(from.x - position.x, 2) + Math.pow(from.y - position.y, 2) + Math.pow(from.z - position.z, 2) - Math.pow(r, 2); + + var delta = Math.pow(b, 2) - 4 * a * c; + + var intersectionPoint = Ray_intersectSphere_intersectionPoint; + var normal = Ray_intersectSphere_normal; + + if(delta < 0){ + // No intersection + return; + + } else if(delta === 0){ + // single intersection point + from.lerp(to, delta, intersectionPoint); + + intersectionPoint.vsub(position, normal); + normal.normalize(); + + this.reportIntersection(normal, intersectionPoint, shape, body, -1); + + } else { + var d1 = (- b - Math.sqrt(delta)) / (2 * a); + var d2 = (- b + Math.sqrt(delta)) / (2 * a); + + if(d1 >= 0 && d1 <= 1){ + from.lerp(to, d1, intersectionPoint); + intersectionPoint.vsub(position, normal); + normal.normalize(); + this.reportIntersection(normal, intersectionPoint, shape, body, -1); + } + + if(this.result._shouldStop){ + return; + } + + if(d2 >= 0 && d2 <= 1){ + from.lerp(to, d2, intersectionPoint); + intersectionPoint.vsub(position, normal); + normal.normalize(); + this.reportIntersection(normal, intersectionPoint, shape, body, -1); + } + } +}; +Ray.prototype[Shape.types.SPHERE] = Ray.prototype.intersectSphere; + + +var intersectConvex_normal = new Vec3(); +var intersectConvex_minDistNormal = new Vec3(); +var intersectConvex_minDistIntersect = new Vec3(); +var intersectConvex_vector = new Vec3(); + +/** + * @method intersectConvex + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + * @param {object} [options] + * @param {array} [options.faceList] + */ +Ray.prototype.intersectConvex = function intersectConvex( + shape, + quat, + position, + body, + options +){ + var minDistNormal = intersectConvex_minDistNormal; + var normal = intersectConvex_normal; + var vector = intersectConvex_vector; + var minDistIntersect = intersectConvex_minDistIntersect; + var faceList = (options && options.faceList) || null; + + // Checking faces + var faces = shape.faces, + vertices = shape.vertices, + normals = shape.faceNormals; + var direction = this._direction; + + var from = this.from; + var to = this.to; + var fromToDistance = from.distanceTo(to); + + var minDist = -1; + var Nfaces = faceList ? faceList.length : faces.length; + var result = this.result; + + for (var j = 0; !result._shouldStop && j < Nfaces; j++) { + var fi = faceList ? faceList[j] : j; + + var face = faces[fi]; + var faceNormal = normals[fi]; + var q = quat; + var x = position; + + // determine if ray intersects the plane of the face + // note: this works regardless of the direction of the face normal + + // Get plane point in world coordinates... + vector.copy(vertices[face[0]]); + q.vmult(vector,vector); + vector.vadd(x,vector); + + // ...but make it relative to the ray from. We'll fix this later. + vector.vsub(from,vector); + + // Get plane normal + q.vmult(faceNormal,normal); + + // If this dot product is negative, we have something interesting + var dot = direction.dot(normal); + + // Bail out if ray and plane are parallel + if ( Math.abs( dot ) < this.precision ){ + continue; + } + + // calc distance to plane + var scalar = normal.dot(vector) / dot; + + // if negative distance, then plane is behind ray + if (scalar < 0){ + continue; + } + + // if (dot < 0) { + + // Intersection point is from + direction * scalar + direction.mult(scalar,intersectPoint); + intersectPoint.vadd(from,intersectPoint); + + // a is the point we compare points b and c with. + a.copy(vertices[face[0]]); + q.vmult(a,a); + x.vadd(a,a); + + for(var i = 1; !result._shouldStop && i < face.length - 1; i++){ + // Transform 3 vertices to world coords + b.copy(vertices[face[i]]); + c.copy(vertices[face[i+1]]); + q.vmult(b,b); + q.vmult(c,c); + x.vadd(b,b); + x.vadd(c,c); + + var distance = intersectPoint.distanceTo(from); + + if(!(pointInTriangle(intersectPoint, a, b, c) || pointInTriangle(intersectPoint, b, a, c)) || distance > fromToDistance){ + continue; + } + + this.reportIntersection(normal, intersectPoint, shape, body, fi); + } + // } + } +}; +Ray.prototype[Shape.types.CONVEXPOLYHEDRON] = Ray.prototype.intersectConvex; + +var intersectTrimesh_normal = new Vec3(); +var intersectTrimesh_localDirection = new Vec3(); +var intersectTrimesh_localFrom = new Vec3(); +var intersectTrimesh_localTo = new Vec3(); +var intersectTrimesh_worldNormal = new Vec3(); +var intersectTrimesh_worldIntersectPoint = new Vec3(); +var intersectTrimesh_localAABB = new AABB(); +var intersectTrimesh_triangles = []; +var intersectTrimesh_treeTransform = new Transform(); + +/** + * @method intersectTrimesh + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + * @param {object} [options] + * @todo Optimize by transforming the world to local space first. + * @todo Use Octree lookup + */ +Ray.prototype.intersectTrimesh = function intersectTrimesh( + mesh, + quat, + position, + body, + options +){ + var normal = intersectTrimesh_normal; + var triangles = intersectTrimesh_triangles; + var treeTransform = intersectTrimesh_treeTransform; + var minDistNormal = intersectConvex_minDistNormal; + var vector = intersectConvex_vector; + var minDistIntersect = intersectConvex_minDistIntersect; + var localAABB = intersectTrimesh_localAABB; + var localDirection = intersectTrimesh_localDirection; + var localFrom = intersectTrimesh_localFrom; + var localTo = intersectTrimesh_localTo; + var worldIntersectPoint = intersectTrimesh_worldIntersectPoint; + var worldNormal = intersectTrimesh_worldNormal; + var faceList = (options && options.faceList) || null; + + // Checking faces + var indices = mesh.indices, + vertices = mesh.vertices, + normals = mesh.faceNormals; + + var from = this.from; + var to = this.to; + var direction = this._direction; + + var minDist = -1; + treeTransform.position.copy(position); + treeTransform.quaternion.copy(quat); + + // Transform ray to local space! + Transform.vectorToLocalFrame(position, quat, direction, localDirection); + //body.vectorToLocalFrame(direction, localDirection); + Transform.pointToLocalFrame(position, quat, from, localFrom); + //body.pointToLocalFrame(from, localFrom); + Transform.pointToLocalFrame(position, quat, to, localTo); + //body.pointToLocalFrame(to, localTo); + var fromToDistanceSquared = localFrom.distanceSquared(localTo); + + mesh.tree.rayQuery(this, treeTransform, triangles); + + for (var i = 0, N = triangles.length; !this.result._shouldStop && i !== N; i++) { + var trianglesIndex = triangles[i]; + + mesh.getNormal(trianglesIndex, normal); + + // determine if ray intersects the plane of the face + // note: this works regardless of the direction of the face normal + + // Get plane point in world coordinates... + mesh.getVertex(indices[trianglesIndex * 3], a); + + // ...but make it relative to the ray from. We'll fix this later. + a.vsub(localFrom,vector); + + // Get plane normal + // quat.vmult(normal, normal); + + // If this dot product is negative, we have something interesting + var dot = localDirection.dot(normal); + + // Bail out if ray and plane are parallel + // if (Math.abs( dot ) < this.precision){ + // continue; + // } + + // calc distance to plane + var scalar = normal.dot(vector) / dot; + + // if negative distance, then plane is behind ray + if (scalar < 0){ + continue; + } + + // Intersection point is from + direction * scalar + localDirection.scale(scalar,intersectPoint); + intersectPoint.vadd(localFrom,intersectPoint); + + // Get triangle vertices + mesh.getVertex(indices[trianglesIndex * 3 + 1], b); + mesh.getVertex(indices[trianglesIndex * 3 + 2], c); + + var squaredDistance = intersectPoint.distanceSquared(localFrom); + + if(!(pointInTriangle(intersectPoint, b, a, c) || pointInTriangle(intersectPoint, a, b, c)) || squaredDistance > fromToDistanceSquared){ + continue; + } + + // transform intersectpoint and normal to world + Transform.vectorToWorldFrame(quat, normal, worldNormal); + //body.vectorToWorldFrame(normal, worldNormal); + Transform.pointToWorldFrame(position, quat, intersectPoint, worldIntersectPoint); + //body.pointToWorldFrame(intersectPoint, worldIntersectPoint); + this.reportIntersection(worldNormal, worldIntersectPoint, mesh, body, trianglesIndex); + } + triangles.length = 0; +}; +Ray.prototype[Shape.types.TRIMESH] = Ray.prototype.intersectTrimesh; + + +/** + * @method reportIntersection + * @private + * @param {Vec3} normal + * @param {Vec3} hitPointWorld + * @param {Shape} shape + * @param {Body} body + * @return {boolean} True if the intersections should continue + */ +Ray.prototype.reportIntersection = function(normal, hitPointWorld, shape, body, hitFaceIndex){ + var from = this.from; + var to = this.to; + var distance = from.distanceTo(hitPointWorld); + var result = this.result; + + // Skip back faces? + if(this.skipBackfaces && normal.dot(this._direction) > 0){ + return; + } + + result.hitFaceIndex = typeof(hitFaceIndex) !== 'undefined' ? hitFaceIndex : -1; + + switch(this.mode){ + case Ray.ALL: + this.hasHit = true; + result.set( + from, + to, + normal, + hitPointWorld, + shape, + body, + distance + ); + result.hasHit = true; + this.callback(result); + break; + + case Ray.CLOSEST: + + // Store if closer than current closest + if(distance < result.distance || !result.hasHit){ + this.hasHit = true; + result.hasHit = true; + result.set( + from, + to, + normal, + hitPointWorld, + shape, + body, + distance + ); + } + break; + + case Ray.ANY: + + // Report and stop. + this.hasHit = true; + result.hasHit = true; + result.set( + from, + to, + normal, + hitPointWorld, + shape, + body, + distance + ); + result._shouldStop = true; + break; + } +}; + +var v0 = new Vec3(), + intersect = new Vec3(); +function distanceFromIntersection(from, direction, position) { + + // v0 is vector from from to position + position.vsub(from,v0); + var dot = v0.dot(direction); + + // intersect = direction*dot + from + direction.mult(dot,intersect); + intersect.vadd(from,intersect); + + var distance = position.distanceTo(intersect); + + return distance; +} + + +},{"../collision/AABB":3,"../collision/RaycastResult":10,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../shapes/Box":37,"../shapes/ConvexPolyhedron":38,"../shapes/Shape":43}],10:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); + +module.exports = RaycastResult; + +/** + * Storage for Ray casting data. + * @class RaycastResult + * @constructor + */ +function RaycastResult(){ + + /** + * @property {Vec3} rayFromWorld + */ + this.rayFromWorld = new Vec3(); + + /** + * @property {Vec3} rayToWorld + */ + this.rayToWorld = new Vec3(); + + /** + * @property {Vec3} hitNormalWorld + */ + this.hitNormalWorld = new Vec3(); + + /** + * @property {Vec3} hitPointWorld + */ + this.hitPointWorld = new Vec3(); + + /** + * @property {boolean} hasHit + */ + this.hasHit = false; + + /** + * The hit shape, or null. + * @property {Shape} shape + */ + this.shape = null; + + /** + * The hit body, or null. + * @property {Body} body + */ + this.body = null; + + /** + * The index of the hit triangle, if the hit shape was a trimesh. + * @property {number} hitFaceIndex + * @default -1 + */ + this.hitFaceIndex = -1; + + /** + * Distance to the hit. Will be set to -1 if there was no hit. + * @property {number} distance + * @default -1 + */ + this.distance = -1; + + /** + * If the ray should stop traversing the bodies. + * @private + * @property {Boolean} _shouldStop + * @default false + */ + this._shouldStop = false; +} + +/** + * Reset all result data. + * @method reset + */ +RaycastResult.prototype.reset = function () { + this.rayFromWorld.setZero(); + this.rayToWorld.setZero(); + this.hitNormalWorld.setZero(); + this.hitPointWorld.setZero(); + this.hasHit = false; + this.shape = null; + this.body = null; + this.hitFaceIndex = -1; + this.distance = -1; + this._shouldStop = false; +}; + +/** + * @method abort + */ +RaycastResult.prototype.abort = function(){ + this._shouldStop = true; +}; + +/** + * @method set + * @param {Vec3} rayFromWorld + * @param {Vec3} rayToWorld + * @param {Vec3} hitNormalWorld + * @param {Vec3} hitPointWorld + * @param {Shape} shape + * @param {Body} body + * @param {number} distance + */ +RaycastResult.prototype.set = function( + rayFromWorld, + rayToWorld, + hitNormalWorld, + hitPointWorld, + shape, + body, + distance +){ + this.rayFromWorld.copy(rayFromWorld); + this.rayToWorld.copy(rayToWorld); + this.hitNormalWorld.copy(hitNormalWorld); + this.hitPointWorld.copy(hitPointWorld); + this.shape = shape; + this.body = body; + this.distance = distance; +}; +},{"../math/Vec3":30}],11:[function(_dereq_,module,exports){ +var Shape = _dereq_('../shapes/Shape'); +var Broadphase = _dereq_('../collision/Broadphase'); + +module.exports = SAPBroadphase; + +/** + * Sweep and prune broadphase along one axis. + * + * @class SAPBroadphase + * @constructor + * @param {World} [world] + * @extends Broadphase + */ +function SAPBroadphase(world){ + Broadphase.apply(this); + + /** + * List of bodies currently in the broadphase. + * @property axisList + * @type {Array} + */ + this.axisList = []; + + /** + * The world to search in. + * @property world + * @type {World} + */ + this.world = null; + + /** + * Axis to sort the bodies along. Set to 0 for x axis, and 1 for y axis. For best performance, choose an axis that the bodies are spread out more on. + * @property axisIndex + * @type {Number} + */ + this.axisIndex = 0; + + var axisList = this.axisList; + + this._addBodyHandler = function(e){ + axisList.push(e.body); + }; + + this._removeBodyHandler = function(e){ + var idx = axisList.indexOf(e.body); + if(idx !== -1){ + axisList.splice(idx,1); + } + }; + + if(world){ + this.setWorld(world); + } +} +SAPBroadphase.prototype = new Broadphase(); + +/** + * Change the world + * @method setWorld + * @param {World} world + */ +SAPBroadphase.prototype.setWorld = function(world){ + // Clear the old axis array + this.axisList.length = 0; + + // Add all bodies from the new world + for(var i=0; i=0;j--) { + if(a[j].aabb.lowerBound.x <= v.aabb.lowerBound.x){ + break; + } + a[j+1] = a[j]; + } + a[j+1] = v; + } + return a; +}; + +/** + * @static + * @method insertionSortY + * @param {Array} a + * @return {Array} + */ +SAPBroadphase.insertionSortY = function(a) { + for(var i=1,l=a.length;i=0;j--) { + if(a[j].aabb.lowerBound.y <= v.aabb.lowerBound.y){ + break; + } + a[j+1] = a[j]; + } + a[j+1] = v; + } + return a; +}; + +/** + * @static + * @method insertionSortZ + * @param {Array} a + * @return {Array} + */ +SAPBroadphase.insertionSortZ = function(a) { + for(var i=1,l=a.length;i=0;j--) { + if(a[j].aabb.lowerBound.z <= v.aabb.lowerBound.z){ + break; + } + a[j+1] = a[j]; + } + a[j+1] = v; + } + return a; +}; + +/** + * Collect all collision pairs + * @method collisionPairs + * @param {World} world + * @param {Array} p1 + * @param {Array} p2 + */ +SAPBroadphase.prototype.collisionPairs = function(world,p1,p2){ + var bodies = this.axisList, + N = bodies.length, + axisIndex = this.axisIndex, + i, j; + + if(this.dirty){ + this.sortList(); + this.dirty = false; + } + + // Look through the list + for(i=0; i !== N; i++){ + var bi = bodies[i]; + + for(j=i+1; j < N; j++){ + var bj = bodies[j]; + + if(!this.needBroadphaseCollision(bi,bj)){ + continue; + } + + if(!SAPBroadphase.checkBounds(bi,bj,axisIndex)){ + break; + } + + this.intersectionTest(bi,bj,p1,p2); + } + } +}; + +SAPBroadphase.prototype.sortList = function(){ + var axisList = this.axisList; + var axisIndex = this.axisIndex; + var N = axisList.length; + + // Update AABBs + for(var i = 0; i!==N; i++){ + var bi = axisList[i]; + if(bi.aabbNeedsUpdate){ + bi.computeAABB(); + } + } + + // Sort the list + if(axisIndex === 0){ + SAPBroadphase.insertionSortX(axisList); + } else if(axisIndex === 1){ + SAPBroadphase.insertionSortY(axisList); + } else if(axisIndex === 2){ + SAPBroadphase.insertionSortZ(axisList); + } +}; + +/** + * Check if the bounds of two bodies overlap, along the given SAP axis. + * @static + * @method checkBounds + * @param {Body} bi + * @param {Body} bj + * @param {Number} axisIndex + * @return {Boolean} + */ +SAPBroadphase.checkBounds = function(bi, bj, axisIndex){ + var biPos; + var bjPos; + + if(axisIndex === 0){ + biPos = bi.position.x; + bjPos = bj.position.x; + } else if(axisIndex === 1){ + biPos = bi.position.y; + bjPos = bj.position.y; + } else if(axisIndex === 2){ + biPos = bi.position.z; + bjPos = bj.position.z; + } + + var ri = bi.boundingRadius, + rj = bj.boundingRadius, + boundA1 = biPos - ri, + boundA2 = biPos + ri, + boundB1 = bjPos - rj, + boundB2 = bjPos + rj; + + return boundB1 < boundA2; +}; + +/** + * Computes the variance of the body positions and estimates the best + * axis to use. Will automatically set property .axisIndex. + * @method autoDetectAxis + */ +SAPBroadphase.prototype.autoDetectAxis = function(){ + var sumX=0, + sumX2=0, + sumY=0, + sumY2=0, + sumZ=0, + sumZ2=0, + bodies = this.axisList, + N = bodies.length, + invN=1/N; + + for(var i=0; i!==N; i++){ + var b = bodies[i]; + + var centerX = b.position.x; + sumX += centerX; + sumX2 += centerX*centerX; + + var centerY = b.position.y; + sumY += centerY; + sumY2 += centerY*centerY; + + var centerZ = b.position.z; + sumZ += centerZ; + sumZ2 += centerZ*centerZ; + } + + var varianceX = sumX2 - sumX*sumX*invN, + varianceY = sumY2 - sumY*sumY*invN, + varianceZ = sumZ2 - sumZ*sumZ*invN; + + if(varianceX > varianceY){ + if(varianceX > varianceZ){ + this.axisIndex = 0; + } else{ + this.axisIndex = 2; + } + } else if(varianceY > varianceZ){ + this.axisIndex = 1; + } else{ + this.axisIndex = 2; + } +}; + +/** + * Returns all the bodies within an AABB. + * @method aabbQuery + * @param {World} world + * @param {AABB} aabb + * @param {array} result An array to store resulting bodies in. + * @return {array} + */ +SAPBroadphase.prototype.aabbQuery = function(world, aabb, result){ + result = result || []; + + if(this.dirty){ + this.sortList(); + this.dirty = false; + } + + var axisIndex = this.axisIndex, axis = 'x'; + if(axisIndex === 1){ axis = 'y'; } + if(axisIndex === 2){ axis = 'z'; } + + var axisList = this.axisList; + var lower = aabb.lowerBound[axis]; + var upper = aabb.upperBound[axis]; + for(var i = 0; i < axisList.length; i++){ + var b = axisList[i]; + + if(b.aabbNeedsUpdate){ + b.computeAABB(); + } + + if(b.aabb.overlaps(aabb)){ + result.push(b); + } + } + + return result; +}; +},{"../collision/Broadphase":5,"../shapes/Shape":43}],12:[function(_dereq_,module,exports){ +module.exports = ConeTwistConstraint; + +var Constraint = _dereq_('./Constraint'); +var PointToPointConstraint = _dereq_('./PointToPointConstraint'); +var ConeEquation = _dereq_('../equations/ConeEquation'); +var RotationalEquation = _dereq_('../equations/RotationalEquation'); +var ContactEquation = _dereq_('../equations/ContactEquation'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * @class ConeTwistConstraint + * @constructor + * @author schteppe + * @param {Body} bodyA + * @param {Body} bodyB + * @param {object} [options] + * @param {Vec3} [options.pivotA] + * @param {Vec3} [options.pivotB] + * @param {Vec3} [options.axisA] + * @param {Vec3} [options.axisB] + * @param {Number} [options.maxForce=1e6] + * @extends PointToPointConstraint + */ +function ConeTwistConstraint(bodyA, bodyB, options){ + options = options || {}; + var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6; + + // Set pivot point in between + var pivotA = options.pivotA ? options.pivotA.clone() : new Vec3(); + var pivotB = options.pivotB ? options.pivotB.clone() : new Vec3(); + this.axisA = options.axisA ? options.axisA.clone() : new Vec3(); + this.axisB = options.axisB ? options.axisB.clone() : new Vec3(); + + PointToPointConstraint.call(this, bodyA, pivotA, bodyB, pivotB, maxForce); + + this.collideConnected = !!options.collideConnected; + + this.angle = typeof(options.angle) !== 'undefined' ? options.angle : 0; + + /** + * @property {ConeEquation} coneEquation + */ + var c = this.coneEquation = new ConeEquation(bodyA,bodyB,options); + + /** + * @property {RotationalEquation} twistEquation + */ + var t = this.twistEquation = new RotationalEquation(bodyA,bodyB,options); + this.twistAngle = typeof(options.twistAngle) !== 'undefined' ? options.twistAngle : 0; + + // Make the cone equation push the bodies toward the cone axis, not outward + c.maxForce = 0; + c.minForce = -maxForce; + + // Make the twist equation add torque toward the initial position + t.maxForce = 0; + t.minForce = -maxForce; + + this.equations.push(c, t); +} +ConeTwistConstraint.prototype = new PointToPointConstraint(); +ConeTwistConstraint.constructor = ConeTwistConstraint; + +var ConeTwistConstraint_update_tmpVec1 = new Vec3(); +var ConeTwistConstraint_update_tmpVec2 = new Vec3(); + +ConeTwistConstraint.prototype.update = function(){ + var bodyA = this.bodyA, + bodyB = this.bodyB, + cone = this.coneEquation, + twist = this.twistEquation; + + PointToPointConstraint.prototype.update.call(this); + + // Update the axes to the cone constraint + bodyA.vectorToWorldFrame(this.axisA, cone.axisA); + bodyB.vectorToWorldFrame(this.axisB, cone.axisB); + + // Update the world axes in the twist constraint + this.axisA.tangents(twist.axisA, twist.axisA); + bodyA.vectorToWorldFrame(twist.axisA, twist.axisA); + + this.axisB.tangents(twist.axisB, twist.axisB); + bodyB.vectorToWorldFrame(twist.axisB, twist.axisB); + + cone.angle = this.angle; + twist.maxAngle = this.twistAngle; +}; + + +},{"../equations/ConeEquation":18,"../equations/ContactEquation":19,"../equations/RotationalEquation":22,"../math/Vec3":30,"./Constraint":13,"./PointToPointConstraint":17}],13:[function(_dereq_,module,exports){ +module.exports = Constraint; + +var Utils = _dereq_('../utils/Utils'); + +/** + * Constraint base class + * @class Constraint + * @author schteppe + * @constructor + * @param {Body} bodyA + * @param {Body} bodyB + * @param {object} [options] + * @param {boolean} [options.collideConnected=true] + * @param {boolean} [options.wakeUpBodies=true] + */ +function Constraint(bodyA, bodyB, options){ + options = Utils.defaults(options,{ + collideConnected : true, + wakeUpBodies : true, + }); + + /** + * Equations to be solved in this constraint + * @property equations + * @type {Array} + */ + this.equations = []; + + /** + * @property {Body} bodyA + */ + this.bodyA = bodyA; + + /** + * @property {Body} bodyB + */ + this.bodyB = bodyB; + + /** + * @property {Number} id + */ + this.id = Constraint.idCounter++; + + /** + * Set to true if you want the bodies to collide when they are connected. + * @property collideConnected + * @type {boolean} + */ + this.collideConnected = options.collideConnected; + + if(options.wakeUpBodies){ + if(bodyA){ + bodyA.wakeUp(); + } + if(bodyB){ + bodyB.wakeUp(); + } + } +} + +/** + * Update all the equations with data. + * @method update + */ +Constraint.prototype.update = function(){ + throw new Error("method update() not implmemented in this Constraint subclass!"); +}; + +/** + * Enables all equations in the constraint. + * @method enable + */ +Constraint.prototype.enable = function(){ + var eqs = this.equations; + for(var i=0; i + // G = [0 axisA 0 -axisB] + + GA.rotational.copy(axisA); + axisB.negate(GB.rotational); + + var GW = this.computeGW() - this.targetVelocity, + GiMf = this.computeGiMf(); + + var B = - GW * b - h * GiMf; + + return B; +}; + +},{"../math/Mat3":27,"../math/Vec3":30,"./Equation":20}],24:[function(_dereq_,module,exports){ +var Utils = _dereq_('../utils/Utils'); + +module.exports = ContactMaterial; + +/** + * Defines what happens when two materials meet. + * @class ContactMaterial + * @constructor + * @param {Material} m1 + * @param {Material} m2 + * @param {object} [options] + * @param {Number} [options.friction=0.3] + * @param {Number} [options.restitution=0.3] + * @param {number} [options.contactEquationStiffness=1e7] + * @param {number} [options.contactEquationRelaxation=3] + * @param {number} [options.frictionEquationStiffness=1e7] + * @param {Number} [options.frictionEquationRelaxation=3] + */ +function ContactMaterial(m1, m2, options){ + options = Utils.defaults(options, { + friction: 0.3, + restitution: 0.3, + contactEquationStiffness: 1e7, + contactEquationRelaxation: 3, + frictionEquationStiffness: 1e7, + frictionEquationRelaxation: 3 + }); + + /** + * Identifier of this material + * @property {Number} id + */ + this.id = ContactMaterial.idCounter++; + + /** + * Participating materials + * @property {Array} materials + * @todo Should be .materialA and .materialB instead + */ + this.materials = [m1, m2]; + + /** + * Friction coefficient + * @property {Number} friction + */ + this.friction = options.friction; + + /** + * Restitution coefficient + * @property {Number} restitution + */ + this.restitution = options.restitution; + + /** + * Stiffness of the produced contact equations + * @property {Number} contactEquationStiffness + */ + this.contactEquationStiffness = options.contactEquationStiffness; + + /** + * Relaxation time of the produced contact equations + * @property {Number} contactEquationRelaxation + */ + this.contactEquationRelaxation = options.contactEquationRelaxation; + + /** + * Stiffness of the produced friction equations + * @property {Number} frictionEquationStiffness + */ + this.frictionEquationStiffness = options.frictionEquationStiffness; + + /** + * Relaxation time of the produced friction equations + * @property {Number} frictionEquationRelaxation + */ + this.frictionEquationRelaxation = options.frictionEquationRelaxation; +} + +ContactMaterial.idCounter = 0; + +},{"../utils/Utils":53}],25:[function(_dereq_,module,exports){ +module.exports = Material; + +/** + * Defines a physics material. + * @class Material + * @constructor + * @param {object} [options] + * @author schteppe + */ +function Material(options){ + var name = ''; + options = options || {}; + + // Backwards compatibility fix + if(typeof(options) === 'string'){ + name = options; + options = {}; + } else if(typeof(options) === 'object') { + name = ''; + } + + /** + * @property name + * @type {String} + */ + this.name = name; + + /** + * material id. + * @property id + * @type {number} + */ + this.id = Material.idCounter++; + + /** + * Friction for this material. If non-negative, it will be used instead of the friction given by ContactMaterials. If there's no matching ContactMaterial, the value from .defaultContactMaterial in the World will be used. + * @property {number} friction + */ + this.friction = typeof(options.friction) !== 'undefined' ? options.friction : -1; + + /** + * Restitution for this material. If non-negative, it will be used instead of the restitution given by ContactMaterials. If there's no matching ContactMaterial, the value from .defaultContactMaterial in the World will be used. + * @property {number} restitution + */ + this.restitution = typeof(options.restitution) !== 'undefined' ? options.restitution : -1; +} + +Material.idCounter = 0; + +},{}],26:[function(_dereq_,module,exports){ +module.exports = JacobianElement; + +var Vec3 = _dereq_('./Vec3'); + +/** + * An element containing 6 entries, 3 spatial and 3 rotational degrees of freedom. + * @class JacobianElement + * @constructor + */ +function JacobianElement(){ + + /** + * @property {Vec3} spatial + */ + this.spatial = new Vec3(); + + /** + * @property {Vec3} rotational + */ + this.rotational = new Vec3(); +} + +/** + * Multiply with other JacobianElement + * @method multiplyElement + * @param {JacobianElement} element + * @return {Number} + */ +JacobianElement.prototype.multiplyElement = function(element){ + return element.spatial.dot(this.spatial) + element.rotational.dot(this.rotational); +}; + +/** + * Multiply with two vectors + * @method multiplyVectors + * @param {Vec3} spatial + * @param {Vec3} rotational + * @return {Number} + */ +JacobianElement.prototype.multiplyVectors = function(spatial,rotational){ + return spatial.dot(this.spatial) + rotational.dot(this.rotational); +}; + +},{"./Vec3":30}],27:[function(_dereq_,module,exports){ +module.exports = Mat3; + +var Vec3 = _dereq_('./Vec3'); + +/** + * A 3x3 matrix. + * @class Mat3 + * @constructor + * @param array elements Array of nine elements. Optional. + * @author schteppe / http://github.com/schteppe + */ +function Mat3(elements){ + /** + * A vector of length 9, containing all matrix elements + * @property {Array} elements + */ + if(elements){ + this.elements = elements; + } else { + this.elements = [0,0,0,0,0,0,0,0,0]; + } +} + +/** + * Sets the matrix to identity + * @method identity + * @todo Should perhaps be renamed to setIdentity() to be more clear. + * @todo Create another function that immediately creates an identity matrix eg. eye() + */ +Mat3.prototype.identity = function(){ + var e = this.elements; + e[0] = 1; + e[1] = 0; + e[2] = 0; + + e[3] = 0; + e[4] = 1; + e[5] = 0; + + e[6] = 0; + e[7] = 0; + e[8] = 1; +}; + +/** + * Set all elements to zero + * @method setZero + */ +Mat3.prototype.setZero = function(){ + var e = this.elements; + e[0] = 0; + e[1] = 0; + e[2] = 0; + e[3] = 0; + e[4] = 0; + e[5] = 0; + e[6] = 0; + e[7] = 0; + e[8] = 0; +}; + +/** + * Sets the matrix diagonal elements from a Vec3 + * @method setTrace + * @param {Vec3} vec3 + */ +Mat3.prototype.setTrace = function(vec3){ + var e = this.elements; + e[0] = vec3.x; + e[4] = vec3.y; + e[8] = vec3.z; +}; + +/** + * Gets the matrix diagonal elements + * @method getTrace + * @return {Vec3} + */ +Mat3.prototype.getTrace = function(target){ + var target = target || new Vec3(); + var e = this.elements; + target.x = e[0]; + target.y = e[4]; + target.z = e[8]; +}; + +/** + * Matrix-Vector multiplication + * @method vmult + * @param {Vec3} v The vector to multiply with + * @param {Vec3} target Optional, target to save the result in. + */ +Mat3.prototype.vmult = function(v,target){ + target = target || new Vec3(); + + var e = this.elements, + x = v.x, + y = v.y, + z = v.z; + target.x = e[0]*x + e[1]*y + e[2]*z; + target.y = e[3]*x + e[4]*y + e[5]*z; + target.z = e[6]*x + e[7]*y + e[8]*z; + + return target; +}; + +/** + * Matrix-scalar multiplication + * @method smult + * @param {Number} s + */ +Mat3.prototype.smult = function(s){ + for(var i=0; i1 acos and sqrt will produce errors, this cant happen if quaternion is normalised + var angle = 2 * Math.acos(this.w); + var s = Math.sqrt(1-this.w*this.w); // assuming quaternion normalised then w is less than 1, so term always positive. + if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt + // if s close to zero then direction of axis not important + targetAxis.x = this.x; // if it is important that axis is normalised then replace with x=1; y=z=0; + targetAxis.y = this.y; + targetAxis.z = this.z; + } else { + targetAxis.x = this.x / s; // normalise axis + targetAxis.y = this.y / s; + targetAxis.z = this.z / s; + } + return [targetAxis,angle]; +}; + +var sfv_t1 = new Vec3(), + sfv_t2 = new Vec3(); + +/** + * Set the quaternion value given two vectors. The resulting rotation will be the needed rotation to rotate u to v. + * @method setFromVectors + * @param {Vec3} u + * @param {Vec3} v + */ +Quaternion.prototype.setFromVectors = function(u,v){ + if(u.isAntiparallelTo(v)){ + var t1 = sfv_t1; + var t2 = sfv_t2; + + u.tangents(t1,t2); + this.setFromAxisAngle(t1,Math.PI); + } else { + var a = u.cross(v); + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = Math.sqrt(Math.pow(u.norm(),2) * Math.pow(v.norm(),2)) + u.dot(v); + this.normalize(); + } +}; + +/** + * Quaternion multiplication + * @method mult + * @param {Quaternion} q + * @param {Quaternion} target Optional. + * @return {Quaternion} + */ +var Quaternion_mult_va = new Vec3(); +var Quaternion_mult_vb = new Vec3(); +var Quaternion_mult_vaxvb = new Vec3(); +Quaternion.prototype.mult = function(q,target){ + target = target || new Quaternion(); + var w = this.w, + va = Quaternion_mult_va, + vb = Quaternion_mult_vb, + vaxvb = Quaternion_mult_vaxvb; + + va.set(this.x,this.y,this.z); + vb.set(q.x,q.y,q.z); + target.w = w*q.w - va.dot(vb); + va.cross(vb,vaxvb); + + target.x = w * vb.x + q.w*va.x + vaxvb.x; + target.y = w * vb.y + q.w*va.y + vaxvb.y; + target.z = w * vb.z + q.w*va.z + vaxvb.z; + + return target; +}; + +/** + * Get the inverse quaternion rotation. + * @method inverse + * @param {Quaternion} target + * @return {Quaternion} + */ +Quaternion.prototype.inverse = function(target){ + var x = this.x, y = this.y, z = this.z, w = this.w; + target = target || new Quaternion(); + + this.conjugate(target); + var inorm2 = 1/(x*x + y*y + z*z + w*w); + target.x *= inorm2; + target.y *= inorm2; + target.z *= inorm2; + target.w *= inorm2; + + return target; +}; + +/** + * Get the quaternion conjugate + * @method conjugate + * @param {Quaternion} target + * @return {Quaternion} + */ +Quaternion.prototype.conjugate = function(target){ + target = target || new Quaternion(); + + target.x = -this.x; + target.y = -this.y; + target.z = -this.z; + target.w = this.w; + + return target; +}; + +/** + * Normalize the quaternion. Note that this changes the values of the quaternion. + * @method normalize + */ +Quaternion.prototype.normalize = function(){ + var l = Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w); + if ( l === 0 ) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + } else { + l = 1 / l; + this.x *= l; + this.y *= l; + this.z *= l; + this.w *= l; + } +}; + +/** + * Approximation of quaternion normalization. Works best when quat is already almost-normalized. + * @method normalizeFast + * @see http://jsperf.com/fast-quaternion-normalization + * @author unphased, https://github.com/unphased + */ +Quaternion.prototype.normalizeFast = function () { + var f = (3.0-(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w))/2.0; + if ( f === 0 ) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + } else { + this.x *= f; + this.y *= f; + this.z *= f; + this.w *= f; + } +}; + +/** + * Multiply the quaternion by a vector + * @method vmult + * @param {Vec3} v + * @param {Vec3} target Optional + * @return {Vec3} + */ +Quaternion.prototype.vmult = function(v,target){ + target = target || new Vec3(); + + var x = v.x, + y = v.y, + z = v.z; + + var qx = this.x, + qy = this.y, + qz = this.z, + qw = this.w; + + // q*v + var ix = qw * x + qy * z - qz * y, + iy = qw * y + qz * x - qx * z, + iz = qw * z + qx * y - qy * x, + iw = -qx * x - qy * y - qz * z; + + target.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + target.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + target.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + + return target; +}; + +/** + * Copies value of source to this quaternion. + * @method copy + * @param {Quaternion} source + * @return {Quaternion} this + */ +Quaternion.prototype.copy = function(source){ + this.x = source.x; + this.y = source.y; + this.z = source.z; + this.w = source.w; + return this; +}; + +/** + * Convert the quaternion to euler angle representation. Order: YZX, as this page describes: http://www.euclideanspace.com/maths/standards/index.htm + * @method toEuler + * @param {Vec3} target + * @param string order Three-character string e.g. "YZX", which also is default. + */ +Quaternion.prototype.toEuler = function(target,order){ + order = order || "YZX"; + + var heading, attitude, bank; + var x = this.x, y = this.y, z = this.z, w = this.w; + + switch(order){ + case "YZX": + var test = x*y + z*w; + if (test > 0.499) { // singularity at north pole + heading = 2 * Math.atan2(x,w); + attitude = Math.PI/2; + bank = 0; + } + if (test < -0.499) { // singularity at south pole + heading = -2 * Math.atan2(x,w); + attitude = - Math.PI/2; + bank = 0; + } + if(isNaN(heading)){ + var sqx = x*x; + var sqy = y*y; + var sqz = z*z; + heading = Math.atan2(2*y*w - 2*x*z , 1 - 2*sqy - 2*sqz); // Heading + attitude = Math.asin(2*test); // attitude + bank = Math.atan2(2*x*w - 2*y*z , 1 - 2*sqx - 2*sqz); // bank + } + break; + default: + throw new Error("Euler order "+order+" not supported yet."); + } + + target.y = heading; + target.z = attitude; + target.x = bank; +}; + +/** + * See http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m + * @method setFromEuler + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {String} order The order to apply angles: 'XYZ' or 'YXZ' or any other combination + */ +Quaternion.prototype.setFromEuler = function ( x, y, z, order ) { + order = order || "XYZ"; + + var c1 = Math.cos( x / 2 ); + var c2 = Math.cos( y / 2 ); + var c3 = Math.cos( z / 2 ); + var s1 = Math.sin( x / 2 ); + var s2 = Math.sin( y / 2 ); + var s3 = Math.sin( z / 2 ); + + if ( order === 'XYZ' ) { + + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + + } else if ( order === 'YXZ' ) { + + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + + } else if ( order === 'ZXY' ) { + + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + + } else if ( order === 'ZYX' ) { + + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + + } else if ( order === 'YZX' ) { + + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + + } else if ( order === 'XZY' ) { + + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + + } + + return this; + +}; + +Quaternion.prototype.clone = function(){ + return new Quaternion(this.x, this.y, this.z, this.w); +}; +},{"./Vec3":30}],29:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('./Vec3'); +var Quaternion = _dereq_('./Quaternion'); + +module.exports = Transform; + +/** + * @class Transform + * @constructor + */ +function Transform(options) { + options = options || {}; + + /** + * @property {Vec3} position + */ + this.position = new Vec3(); + if(options.position){ + this.position.copy(options.position); + } + + /** + * @property {Quaternion} quaternion + */ + this.quaternion = new Quaternion(); + if(options.quaternion){ + this.quaternion.copy(options.quaternion); + } +} + +var tmpQuat = new Quaternion(); + +/** + * @static + * @method pointToLocaFrame + * @param {Vec3} position + * @param {Quaternion} quaternion + * @param {Vec3} worldPoint + * @param {Vec3} result + */ +Transform.pointToLocalFrame = function(position, quaternion, worldPoint, result){ + var result = result || new Vec3(); + worldPoint.vsub(position, result); + quaternion.conjugate(tmpQuat); + tmpQuat.vmult(result, result); + return result; +}; + +/** + * Get a global point in local transform coordinates. + * @method pointToLocal + * @param {Vec3} point + * @param {Vec3} result + * @return {Vec3} The "result" vector object + */ +Transform.prototype.pointToLocal = function(worldPoint, result){ + return Transform.pointToLocalFrame(this.position, this.quaternion, worldPoint, result); +}; + +/** + * @static + * @method pointToWorldFrame + * @param {Vec3} position + * @param {Vec3} quaternion + * @param {Vec3} localPoint + * @param {Vec3} result + */ +Transform.pointToWorldFrame = function(position, quaternion, localPoint, result){ + var result = result || new Vec3(); + quaternion.vmult(localPoint, result); + result.vadd(position, result); + return result; +}; + +/** + * Get a local point in global transform coordinates. + * @method pointToWorld + * @param {Vec3} point + * @param {Vec3} result + * @return {Vec3} The "result" vector object + */ +Transform.prototype.pointToWorld = function(localPoint, result){ + return Transform.pointToWorldFrame(this.position, this.quaternion, localPoint, result); +}; + + +Transform.prototype.vectorToWorldFrame = function(localVector, result){ + var result = result || new Vec3(); + this.quaternion.vmult(localVector, result); + return result; +}; + +Transform.vectorToWorldFrame = function(quaternion, localVector, result){ + quaternion.vmult(localVector, result); + return result; +}; + +Transform.vectorToLocalFrame = function(position, quaternion, worldVector, result){ + var result = result || new Vec3(); + quaternion.w *= -1; + quaternion.vmult(worldVector, result); + quaternion.w *= -1; + return result; +}; + +},{"./Quaternion":28,"./Vec3":30}],30:[function(_dereq_,module,exports){ +module.exports = Vec3; + +var Mat3 = _dereq_('./Mat3'); + +/** + * 3-dimensional vector + * @class Vec3 + * @constructor + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @author schteppe + * @example + * var v = new Vec3(1, 2, 3); + * console.log('x=' + v.x); // x=1 + */ +function Vec3(x,y,z){ + /** + * @property x + * @type {Number} + */ + this.x = x||0.0; + + /** + * @property y + * @type {Number} + */ + this.y = y||0.0; + + /** + * @property z + * @type {Number} + */ + this.z = z||0.0; +} + +/** + * @static + * @property {Vec3} ZERO + */ +Vec3.ZERO = new Vec3(0, 0, 0); + +/** + * @static + * @property {Vec3} UNIT_X + */ +Vec3.UNIT_X = new Vec3(1, 0, 0); + +/** + * @static + * @property {Vec3} UNIT_Y + */ +Vec3.UNIT_Y = new Vec3(0, 1, 0); + +/** + * @static + * @property {Vec3} UNIT_Z + */ +Vec3.UNIT_Z = new Vec3(0, 0, 1); + +/** + * Vector cross product + * @method cross + * @param {Vec3} v + * @param {Vec3} target Optional. Target to save in. + * @return {Vec3} + */ +Vec3.prototype.cross = function(v,target){ + var vx=v.x, vy=v.y, vz=v.z, x=this.x, y=this.y, z=this.z; + target = target || new Vec3(); + + target.x = (y * vz) - (z * vy); + target.y = (z * vx) - (x * vz); + target.z = (x * vy) - (y * vx); + + return target; +}; + +/** + * Set the vectors' 3 elements + * @method set + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return Vec3 + */ +Vec3.prototype.set = function(x,y,z){ + this.x = x; + this.y = y; + this.z = z; + return this; +}; + +/** + * Set all components of the vector to zero. + * @method setZero + */ +Vec3.prototype.setZero = function(){ + this.x = this.y = this.z = 0; +}; + +/** + * Vector addition + * @method vadd + * @param {Vec3} v + * @param {Vec3} target Optional. + * @return {Vec3} + */ +Vec3.prototype.vadd = function(v,target){ + if(target){ + target.x = v.x + this.x; + target.y = v.y + this.y; + target.z = v.z + this.z; + } else { + return new Vec3(this.x + v.x, + this.y + v.y, + this.z + v.z); + } +}; + +/** + * Vector subtraction + * @method vsub + * @param {Vec3} v + * @param {Vec3} target Optional. Target to save in. + * @return {Vec3} + */ +Vec3.prototype.vsub = function(v,target){ + if(target){ + target.x = this.x - v.x; + target.y = this.y - v.y; + target.z = this.z - v.z; + } else { + return new Vec3(this.x-v.x, + this.y-v.y, + this.z-v.z); + } +}; + +/** + * Get the cross product matrix a_cross from a vector, such that a x b = a_cross * b = c + * @method crossmat + * @see http://www8.cs.umu.se/kurser/TDBD24/VT06/lectures/Lecture6.pdf + * @return {Mat3} + */ +Vec3.prototype.crossmat = function(){ + return new Mat3([ 0, -this.z, this.y, + this.z, 0, -this.x, + -this.y, this.x, 0]); +}; + +/** + * Normalize the vector. Note that this changes the values in the vector. + * @method normalize + * @return {Number} Returns the norm of the vector + */ +Vec3.prototype.normalize = function(){ + var x=this.x, y=this.y, z=this.z; + var n = Math.sqrt(x*x + y*y + z*z); + if(n>0.0){ + var invN = 1/n; + this.x *= invN; + this.y *= invN; + this.z *= invN; + } else { + // Make something up + this.x = 0; + this.y = 0; + this.z = 0; + } + return n; +}; + +/** + * Get the version of this vector that is of length 1. + * @method unit + * @param {Vec3} target Optional target to save in + * @return {Vec3} Returns the unit vector + */ +Vec3.prototype.unit = function(target){ + target = target || new Vec3(); + var x=this.x, y=this.y, z=this.z; + var ninv = Math.sqrt(x*x + y*y + z*z); + if(ninv>0.0){ + ninv = 1.0/ninv; + target.x = x * ninv; + target.y = y * ninv; + target.z = z * ninv; + } else { + target.x = 1; + target.y = 0; + target.z = 0; + } + return target; +}; + +/** + * Get the length of the vector + * @method norm + * @return {Number} + * @deprecated Use .length() instead + */ +Vec3.prototype.norm = function(){ + var x=this.x, y=this.y, z=this.z; + return Math.sqrt(x*x + y*y + z*z); +}; + +/** + * Get the length of the vector + * @method length + * @return {Number} + */ +Vec3.prototype.length = Vec3.prototype.norm; + +/** + * Get the squared length of the vector + * @method norm2 + * @return {Number} + * @deprecated Use .lengthSquared() instead. + */ +Vec3.prototype.norm2 = function(){ + return this.dot(this); +}; + +/** + * Get the squared length of the vector. + * @method lengthSquared + * @return {Number} + */ +Vec3.prototype.lengthSquared = Vec3.prototype.norm2; + +/** + * Get distance from this point to another point + * @method distanceTo + * @param {Vec3} p + * @return {Number} + */ +Vec3.prototype.distanceTo = function(p){ + var x=this.x, y=this.y, z=this.z; + var px=p.x, py=p.y, pz=p.z; + return Math.sqrt((px-x)*(px-x)+ + (py-y)*(py-y)+ + (pz-z)*(pz-z)); +}; + +/** + * Get squared distance from this point to another point + * @method distanceSquared + * @param {Vec3} p + * @return {Number} + */ +Vec3.prototype.distanceSquared = function(p){ + var x=this.x, y=this.y, z=this.z; + var px=p.x, py=p.y, pz=p.z; + return (px-x)*(px-x) + (py-y)*(py-y) + (pz-z)*(pz-z); +}; + +/** + * Multiply all the components of the vector with a scalar. + * @deprecated Use .scale instead + * @method mult + * @param {Number} scalar + * @param {Vec3} target The vector to save the result in. + * @return {Vec3} + * @deprecated Use .scale() instead + */ +Vec3.prototype.mult = function(scalar,target){ + target = target || new Vec3(); + var x = this.x, + y = this.y, + z = this.z; + target.x = scalar * x; + target.y = scalar * y; + target.z = scalar * z; + return target; +}; + +/** + * Multiply the vector with a scalar. + * @method scale + * @param {Number} scalar + * @param {Vec3} target + * @return {Vec3} + */ +Vec3.prototype.scale = Vec3.prototype.mult; + +/** + * Calculate dot product + * @method dot + * @param {Vec3} v + * @return {Number} + */ +Vec3.prototype.dot = function(v){ + return this.x * v.x + this.y * v.y + this.z * v.z; +}; + +/** + * @method isZero + * @return bool + */ +Vec3.prototype.isZero = function(){ + return this.x===0 && this.y===0 && this.z===0; +}; + +/** + * Make the vector point in the opposite direction. + * @method negate + * @param {Vec3} target Optional target to save in + * @return {Vec3} + */ +Vec3.prototype.negate = function(target){ + target = target || new Vec3(); + target.x = -this.x; + target.y = -this.y; + target.z = -this.z; + return target; +}; + +/** + * Compute two artificial tangents to the vector + * @method tangents + * @param {Vec3} t1 Vector object to save the first tangent in + * @param {Vec3} t2 Vector object to save the second tangent in + */ +var Vec3_tangents_n = new Vec3(); +var Vec3_tangents_randVec = new Vec3(); +Vec3.prototype.tangents = function(t1,t2){ + var norm = this.norm(); + if(norm>0.0){ + var n = Vec3_tangents_n; + var inorm = 1/norm; + n.set(this.x*inorm,this.y*inorm,this.z*inorm); + var randVec = Vec3_tangents_randVec; + if(Math.abs(n.x) < 0.9){ + randVec.set(1,0,0); + n.cross(randVec,t1); + } else { + randVec.set(0,1,0); + n.cross(randVec,t1); + } + n.cross(t1,t2); + } else { + // The normal length is zero, make something up + t1.set(1, 0, 0); + t2.set(0, 1, 0); + } +}; + +/** + * Converts to a more readable format + * @method toString + * @return string + */ +Vec3.prototype.toString = function(){ + return this.x+","+this.y+","+this.z; +}; + +/** + * Converts to an array + * @method toArray + * @return Array + */ +Vec3.prototype.toArray = function(){ + return [this.x, this.y, this.z]; +}; + +/** + * Copies value of source to this vector. + * @method copy + * @param {Vec3} source + * @return {Vec3} this + */ +Vec3.prototype.copy = function(source){ + this.x = source.x; + this.y = source.y; + this.z = source.z; + return this; +}; + + +/** + * Do a linear interpolation between two vectors + * @method lerp + * @param {Vec3} v + * @param {Number} t A number between 0 and 1. 0 will make this function return u, and 1 will make it return v. Numbers in between will generate a vector in between them. + * @param {Vec3} target + */ +Vec3.prototype.lerp = function(v,t,target){ + var x=this.x, y=this.y, z=this.z; + target.x = x + (v.x-x)*t; + target.y = y + (v.y-y)*t; + target.z = z + (v.z-z)*t; +}; + +/** + * Check if a vector equals is almost equal to another one. + * @method almostEquals + * @param {Vec3} v + * @param {Number} precision + * @return bool + */ +Vec3.prototype.almostEquals = function(v,precision){ + if(precision===undefined){ + precision = 1e-6; + } + if( Math.abs(this.x-v.x)>precision || + Math.abs(this.y-v.y)>precision || + Math.abs(this.z-v.z)>precision){ + return false; + } + return true; +}; + +/** + * Check if a vector is almost zero + * @method almostZero + * @param {Number} precision + */ +Vec3.prototype.almostZero = function(precision){ + if(precision===undefined){ + precision = 1e-6; + } + if( Math.abs(this.x)>precision || + Math.abs(this.y)>precision || + Math.abs(this.z)>precision){ + return false; + } + return true; +}; + +var antip_neg = new Vec3(); + +/** + * Check if the vector is anti-parallel to another vector. + * @method isAntiparallelTo + * @param {Vec3} v + * @param {Number} precision Set to zero for exact comparisons + * @return {Boolean} + */ +Vec3.prototype.isAntiparallelTo = function(v,precision){ + this.negate(antip_neg); + return antip_neg.almostEquals(v,precision); +}; + +/** + * Clone the vector + * @method clone + * @return {Vec3} + */ +Vec3.prototype.clone = function(){ + return new Vec3(this.x, this.y, this.z); +}; +},{"./Mat3":27}],31:[function(_dereq_,module,exports){ +module.exports = Body; + +var EventTarget = _dereq_('../utils/EventTarget'); +var Shape = _dereq_('../shapes/Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Mat3 = _dereq_('../math/Mat3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Material = _dereq_('../material/Material'); +var AABB = _dereq_('../collision/AABB'); +var Box = _dereq_('../shapes/Box'); + +/** + * Base class for all body types. + * @class Body + * @constructor + * @extends EventTarget + * @param {object} [options] + * @param {Vec3} [options.position] + * @param {Vec3} [options.velocity] + * @param {Vec3} [options.angularVelocity] + * @param {Quaternion} [options.quaternion] + * @param {number} [options.mass] + * @param {Material} [options.material] + * @param {number} [options.type] + * @param {number} [options.linearDamping=0.01] + * @param {number} [options.angularDamping=0.01] + * @param {boolean} [options.allowSleep=true] + * @param {number} [options.sleepSpeedLimit=0.1] + * @param {number} [options.sleepTimeLimit=1] + * @param {number} [options.collisionFilterGroup=1] + * @param {number} [options.collisionFilterMask=1] + * @param {boolean} [options.fixedRotation=false] + * @param {Body} [options.shape] + * @example + * var body = new Body({ + * mass: 1 + * }); + * var shape = new Sphere(1); + * body.addShape(shape); + * world.add(body); + */ +function Body(options){ + options = options || {}; + + EventTarget.apply(this); + + this.id = Body.idCounter++; + + /** + * Reference to the world the body is living in + * @property world + * @type {World} + */ + this.world = null; + + /** + * Callback function that is used BEFORE stepping the system. Use it to apply forces, for example. Inside the function, "this" will refer to this Body object. + * @property preStep + * @type {Function} + * @deprecated Use World events instead + */ + this.preStep = null; + + /** + * Callback function that is used AFTER stepping the system. Inside the function, "this" will refer to this Body object. + * @property postStep + * @type {Function} + * @deprecated Use World events instead + */ + this.postStep = null; + + this.vlambda = new Vec3(); + + /** + * @property {Number} collisionFilterGroup + */ + this.collisionFilterGroup = typeof(options.collisionFilterGroup) === 'number' ? options.collisionFilterGroup : 1; + + /** + * @property {Number} collisionFilterMask + */ + this.collisionFilterMask = typeof(options.collisionFilterMask) === 'number' ? options.collisionFilterMask : 1; + + /** + * Whether to produce contact forces when in contact with other bodies. Note that contacts will be generated, but they will be disabled. + * @property {Number} collisionResponse + */ + this.collisionResponse = true; + + /** + * @property position + * @type {Vec3} + */ + this.position = new Vec3(); + + if(options.position){ + this.position.copy(options.position); + } + + /** + * @property {Vec3} previousPosition + */ + this.previousPosition = new Vec3(); + + /** + * Initial position of the body + * @property initPosition + * @type {Vec3} + */ + this.initPosition = new Vec3(); + + /** + * @property velocity + * @type {Vec3} + */ + this.velocity = new Vec3(); + + if(options.velocity){ + this.velocity.copy(options.velocity); + } + + /** + * @property initVelocity + * @type {Vec3} + */ + this.initVelocity = new Vec3(); + + /** + * Linear force on the body + * @property force + * @type {Vec3} + */ + this.force = new Vec3(); + + var mass = typeof(options.mass) === 'number' ? options.mass : 0; + + /** + * @property mass + * @type {Number} + * @default 0 + */ + this.mass = mass; + + /** + * @property invMass + * @type {Number} + */ + this.invMass = mass > 0 ? 1.0 / mass : 0; + + /** + * @property material + * @type {Material} + */ + this.material = options.material || null; + + /** + * @property linearDamping + * @type {Number} + */ + this.linearDamping = typeof(options.linearDamping) === 'number' ? options.linearDamping : 0.01; + + /** + * One of: Body.DYNAMIC, Body.STATIC and Body.KINEMATIC. + * @property type + * @type {Number} + */ + this.type = (mass <= 0.0 ? Body.STATIC : Body.DYNAMIC); + if(typeof(options.type) === typeof(Body.STATIC)){ + this.type = options.type; + } + + /** + * If true, the body will automatically fall to sleep. + * @property allowSleep + * @type {Boolean} + * @default true + */ + this.allowSleep = typeof(options.allowSleep) !== 'undefined' ? options.allowSleep : true; + + /** + * Current sleep state. + * @property sleepState + * @type {Number} + */ + this.sleepState = 0; + + /** + * If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy. + * @property sleepSpeedLimit + * @type {Number} + * @default 0.1 + */ + this.sleepSpeedLimit = typeof(options.sleepSpeedLimit) !== 'undefined' ? options.sleepSpeedLimit : 0.1; + + /** + * If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping. + * @property sleepTimeLimit + * @type {Number} + * @default 1 + */ + this.sleepTimeLimit = typeof(options.sleepTimeLimit) !== 'undefined' ? options.sleepTimeLimit : 1; + + this.timeLastSleepy = 0; + + this._wakeUpAfterNarrowphase = false; + + + /** + * Rotational force on the body, around center of mass + * @property {Vec3} torque + */ + this.torque = new Vec3(); + + /** + * Orientation of the body + * @property quaternion + * @type {Quaternion} + */ + this.quaternion = new Quaternion(); + + if(options.quaternion){ + this.quaternion.copy(options.quaternion); + } + + /** + * @property initQuaternion + * @type {Quaternion} + */ + this.initQuaternion = new Quaternion(); + + /** + * @property angularVelocity + * @type {Vec3} + */ + this.angularVelocity = new Vec3(); + + if(options.angularVelocity){ + this.angularVelocity.copy(options.angularVelocity); + } + + /** + * @property initAngularVelocity + * @type {Vec3} + */ + this.initAngularVelocity = new Vec3(); + + this.interpolatedPosition = new Vec3(); + this.interpolatedQuaternion = new Quaternion(); + + /** + * @property shapes + * @type {array} + */ + this.shapes = []; + + /** + * @property shapeOffsets + * @type {array} + */ + this.shapeOffsets = []; + + /** + * @property shapeOrientations + * @type {array} + */ + this.shapeOrientations = []; + + /** + * @property inertia + * @type {Vec3} + */ + this.inertia = new Vec3(); + + /** + * @property {Vec3} invInertia + */ + this.invInertia = new Vec3(); + + /** + * @property {Mat3} invInertiaWorld + */ + this.invInertiaWorld = new Mat3(); + + this.invMassSolve = 0; + + /** + * @property {Vec3} invInertiaSolve + */ + this.invInertiaSolve = new Vec3(); + + /** + * @property {Mat3} invInertiaWorldSolve + */ + this.invInertiaWorldSolve = new Mat3(); + + /** + * Set to true if you don't want the body to rotate. Make sure to run .updateMassProperties() after changing this. + * @property {Boolean} fixedRotation + * @default false + */ + this.fixedRotation = typeof(options.fixedRotation) !== "undefined" ? options.fixedRotation : false; + + /** + * @property {Number} angularDamping + */ + this.angularDamping = typeof(options.angularDamping) !== 'undefined' ? options.angularDamping : 0.01; + + /** + * @property aabb + * @type {AABB} + */ + this.aabb = new AABB(); + + /** + * Indicates if the AABB needs to be updated before use. + * @property aabbNeedsUpdate + * @type {Boolean} + */ + this.aabbNeedsUpdate = true; + + this.wlambda = new Vec3(); + + if(options.shape){ + this.addShape(options.shape); + } + + this.updateMassProperties(); +} +Body.prototype = new EventTarget(); +Body.prototype.constructor = Body; + +/** + * A dynamic body is fully simulated. Can be moved manually by the user, but normally they move according to forces. A dynamic body can collide with all body types. A dynamic body always has finite, non-zero mass. + * @static + * @property DYNAMIC + * @type {Number} + */ +Body.DYNAMIC = 1; + +/** + * A static body does not move during simulation and behaves as if it has infinite mass. Static bodies can be moved manually by setting the position of the body. The velocity of a static body is always zero. Static bodies do not collide with other static or kinematic bodies. + * @static + * @property STATIC + * @type {Number} + */ +Body.STATIC = 2; + +/** + * A kinematic body moves under simulation according to its velocity. They do not respond to forces. They can be moved manually, but normally a kinematic body is moved by setting its velocity. A kinematic body behaves as if it has infinite mass. Kinematic bodies do not collide with other static or kinematic bodies. + * @static + * @property KINEMATIC + * @type {Number} + */ +Body.KINEMATIC = 4; + + + +/** + * @static + * @property AWAKE + * @type {number} + */ +Body.AWAKE = 0; + +/** + * @static + * @property SLEEPY + * @type {number} + */ +Body.SLEEPY = 1; + +/** + * @static + * @property SLEEPING + * @type {number} + */ +Body.SLEEPING = 2; + +Body.idCounter = 0; + +/** + * Wake the body up. + * @method wakeUp + */ +Body.prototype.wakeUp = function(){ + var s = this.sleepState; + this.sleepState = 0; + if(s === Body.SLEEPING){ + this.dispatchEvent({type:"wakeup"}); + } +}; + +/** + * Force body sleep + * @method sleep + */ +Body.prototype.sleep = function(){ + this.sleepState = Body.SLEEPING; + this.velocity.set(0,0,0); + this.angularVelocity.set(0,0,0); +}; + +Body.sleepyEvent = { + type: "sleepy" +}; + +Body.sleepEvent = { + type: "sleep" +}; + +/** + * Called every timestep to update internal sleep timer and change sleep state if needed. + * @method sleepTick + * @param {Number} time The world time in seconds + */ +Body.prototype.sleepTick = function(time){ + if(this.allowSleep){ + var sleepState = this.sleepState; + var speedSquared = this.velocity.norm2() + this.angularVelocity.norm2(); + var speedLimitSquared = Math.pow(this.sleepSpeedLimit,2); + if(sleepState===Body.AWAKE && speedSquared < speedLimitSquared){ + this.sleepState = Body.SLEEPY; // Sleepy + this.timeLastSleepy = time; + this.dispatchEvent(Body.sleepyEvent); + } else if(sleepState===Body.SLEEPY && speedSquared > speedLimitSquared){ + this.wakeUp(); // Wake up + } else if(sleepState===Body.SLEEPY && (time - this.timeLastSleepy ) > this.sleepTimeLimit){ + this.sleep(); // Sleeping + this.dispatchEvent(Body.sleepEvent); + } + } +}; + +/** + * If the body is sleeping, it should be immovable / have infinite mass during solve. We solve it by having a separate "solve mass". + * @method updateSolveMassProperties + */ +Body.prototype.updateSolveMassProperties = function(){ + if(this.sleepState === Body.SLEEPING || this.type === Body.KINEMATIC){ + this.invMassSolve = 0; + this.invInertiaSolve.setZero(); + this.invInertiaWorldSolve.setZero(); + } else { + this.invMassSolve = this.invMass; + this.invInertiaSolve.copy(this.invInertia); + this.invInertiaWorldSolve.copy(this.invInertiaWorld); + } +}; + +/** + * Convert a world point to local body frame. + * @method pointToLocalFrame + * @param {Vec3} worldPoint + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.pointToLocalFrame = function(worldPoint,result){ + var result = result || new Vec3(); + worldPoint.vsub(this.position,result); + this.quaternion.conjugate().vmult(result,result); + return result; +}; + +/** + * Convert a world vector to local body frame. + * @method vectorToLocalFrame + * @param {Vec3} worldPoint + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.vectorToLocalFrame = function(worldVector, result){ + var result = result || new Vec3(); + this.quaternion.conjugate().vmult(worldVector,result); + return result; +}; + +/** + * Convert a local body point to world frame. + * @method pointToWorldFrame + * @param {Vec3} localPoint + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.pointToWorldFrame = function(localPoint,result){ + var result = result || new Vec3(); + this.quaternion.vmult(localPoint,result); + result.vadd(this.position,result); + return result; +}; + +/** + * Convert a local body point to world frame. + * @method vectorToWorldFrame + * @param {Vec3} localVector + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.vectorToWorldFrame = function(localVector, result){ + var result = result || new Vec3(); + this.quaternion.vmult(localVector, result); + return result; +}; + +var tmpVec = new Vec3(); +var tmpQuat = new Quaternion(); + +/** + * Add a shape to the body with a local offset and orientation. + * @method addShape + * @param {Shape} shape + * @param {Vec3} offset + * @param {Quaternion} quaternion + * @return {Body} The body object, for chainability. + */ +Body.prototype.addShape = function(shape, _offset, _orientation){ + var offset = new Vec3(); + var orientation = new Quaternion(); + + if(_offset){ + offset.copy(_offset); + } + if(_orientation){ + orientation.copy(_orientation); + } + + this.shapes.push(shape); + this.shapeOffsets.push(offset); + this.shapeOrientations.push(orientation); + this.updateMassProperties(); + this.updateBoundingRadius(); + + this.aabbNeedsUpdate = true; + + return this; +}; + +/** + * Update the bounding radius of the body. Should be done if any of the shapes are changed. + * @method updateBoundingRadius + */ +Body.prototype.updateBoundingRadius = function(){ + var shapes = this.shapes, + shapeOffsets = this.shapeOffsets, + N = shapes.length, + radius = 0; + + for(var i=0; i!==N; i++){ + var shape = shapes[i]; + shape.updateBoundingSphereRadius(); + var offset = shapeOffsets[i].norm(), + r = shape.boundingSphereRadius; + if(offset + r > radius){ + radius = offset + r; + } + } + + this.boundingRadius = radius; +}; + +var computeAABB_shapeAABB = new AABB(); + +/** + * Updates the .aabb + * @method computeAABB + * @todo rename to updateAABB() + */ +Body.prototype.computeAABB = function(){ + var shapes = this.shapes, + shapeOffsets = this.shapeOffsets, + shapeOrientations = this.shapeOrientations, + N = shapes.length, + offset = tmpVec, + orientation = tmpQuat, + bodyQuat = this.quaternion, + aabb = this.aabb, + shapeAABB = computeAABB_shapeAABB; + + for(var i=0; i!==N; i++){ + var shape = shapes[i]; + + // Get shape world quaternion + shapeOrientations[i].mult(bodyQuat, orientation); + + // Get shape world position + orientation.vmult(shapeOffsets[i], offset); + offset.vadd(this.position, offset); + + // vec2.rotate(offset, shapeOffsets[i], bodyAngle); + // vec2.add(offset, offset, this.position); + + // Get shape AABB + shape.calculateWorldAABB(offset, orientation, shapeAABB.lowerBound, shapeAABB.upperBound); + + if(i === 0){ + aabb.copy(shapeAABB); + } else { + aabb.extend(shapeAABB); + } + } + + this.aabbNeedsUpdate = false; +}; + +var uiw_m1 = new Mat3(), + uiw_m2 = new Mat3(), + uiw_m3 = new Mat3(); + +/** + * Update .inertiaWorld and .invInertiaWorld + * @method updateInertiaWorld + */ +Body.prototype.updateInertiaWorld = function(force){ + var I = this.invInertia; + if (I.x === I.y && I.y === I.z && !force) { + // If inertia M = s*I, where I is identity and s a scalar, then + // R*M*R' = R*(s*I)*R' = s*R*I*R' = s*R*R' = s*I = M + // where R is the rotation matrix. + // In other words, we don't have to transform the inertia if all + // inertia diagonal entries are equal. + } else { + var m1 = uiw_m1, + m2 = uiw_m2, + m3 = uiw_m3; + m1.setRotationFromQuaternion(this.quaternion); + m1.transpose(m2); + m1.scale(I,m1); + m1.mmult(m2,this.invInertiaWorld); + //m3.getTrace(this.invInertiaWorld); + } + + /* + this.quaternion.vmult(this.inertia,this.inertiaWorld); + this.quaternion.vmult(this.invInertia,this.invInertiaWorld); + */ +}; + +/** + * Apply force to a world point. This could for example be a point on the Body surface. Applying force this way will add to Body.force and Body.torque. + * @method applyForce + * @param {Vec3} force The amount of force to add. + * @param {Vec3} worldPoint A world point to apply the force on. + */ +var Body_applyForce_r = new Vec3(); +var Body_applyForce_rotForce = new Vec3(); +Body.prototype.applyForce = function(force,worldPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + // Compute point position relative to the body center + var r = Body_applyForce_r; + worldPoint.vsub(this.position,r); + + // Compute produced rotational force + var rotForce = Body_applyForce_rotForce; + r.cross(force,rotForce); + + // Add linear force + this.force.vadd(force,this.force); + + // Add rotational force + this.torque.vadd(rotForce,this.torque); +}; + +/** + * Apply force to a local point in the body. + * @method applyLocalForce + * @param {Vec3} force The force vector to apply, defined locally in the body frame. + * @param {Vec3} localPoint A local point in the body to apply the force on. + */ +var Body_applyLocalForce_worldForce = new Vec3(); +var Body_applyLocalForce_worldPoint = new Vec3(); +Body.prototype.applyLocalForce = function(localForce, localPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + var worldForce = Body_applyLocalForce_worldForce; + var worldPoint = Body_applyLocalForce_worldPoint; + + // Transform the force vector to world space + this.vectorToWorldFrame(localForce, worldForce); + this.pointToWorldFrame(localPoint, worldPoint); + + this.applyForce(worldForce, worldPoint); +}; + +/** + * Apply impulse to a world point. This could for example be a point on the Body surface. An impulse is a force added to a body during a short period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity. + * @method applyImpulse + * @param {Vec3} impulse The amount of impulse to add. + * @param {Vec3} worldPoint A world point to apply the force on. + */ +var Body_applyImpulse_r = new Vec3(); +var Body_applyImpulse_velo = new Vec3(); +var Body_applyImpulse_rotVelo = new Vec3(); +Body.prototype.applyImpulse = function(impulse, worldPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + // Compute point position relative to the body center + var r = Body_applyImpulse_r; + worldPoint.vsub(this.position,r); + + // Compute produced central impulse velocity + var velo = Body_applyImpulse_velo; + velo.copy(impulse); + velo.mult(this.invMass,velo); + + // Add linear impulse + this.velocity.vadd(velo, this.velocity); + + // Compute produced rotational impulse velocity + var rotVelo = Body_applyImpulse_rotVelo; + r.cross(impulse,rotVelo); + + /* + rotVelo.x *= this.invInertia.x; + rotVelo.y *= this.invInertia.y; + rotVelo.z *= this.invInertia.z; + */ + this.invInertiaWorld.vmult(rotVelo,rotVelo); + + // Add rotational Impulse + this.angularVelocity.vadd(rotVelo, this.angularVelocity); +}; + +/** + * Apply locally-defined impulse to a local point in the body. + * @method applyLocalImpulse + * @param {Vec3} force The force vector to apply, defined locally in the body frame. + * @param {Vec3} localPoint A local point in the body to apply the force on. + */ +var Body_applyLocalImpulse_worldImpulse = new Vec3(); +var Body_applyLocalImpulse_worldPoint = new Vec3(); +Body.prototype.applyLocalImpulse = function(localImpulse, localPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + var worldImpulse = Body_applyLocalImpulse_worldImpulse; + var worldPoint = Body_applyLocalImpulse_worldPoint; + + // Transform the force vector to world space + this.vectorToWorldFrame(localImpulse, worldImpulse); + this.pointToWorldFrame(localPoint, worldPoint); + + this.applyImpulse(worldImpulse, worldPoint); +}; + +var Body_updateMassProperties_halfExtents = new Vec3(); + +/** + * Should be called whenever you change the body shape or mass. + * @method updateMassProperties + */ +Body.prototype.updateMassProperties = function(){ + var halfExtents = Body_updateMassProperties_halfExtents; + + this.invMass = this.mass > 0 ? 1.0 / this.mass : 0; + var I = this.inertia; + var fixed = this.fixedRotation; + + // Approximate with AABB box + this.computeAABB(); + halfExtents.set( + (this.aabb.upperBound.x-this.aabb.lowerBound.x) / 2, + (this.aabb.upperBound.y-this.aabb.lowerBound.y) / 2, + (this.aabb.upperBound.z-this.aabb.lowerBound.z) / 2 + ); + Box.calculateInertia(halfExtents, this.mass, I); + + this.invInertia.set( + I.x > 0 && !fixed ? 1.0 / I.x : 0, + I.y > 0 && !fixed ? 1.0 / I.y : 0, + I.z > 0 && !fixed ? 1.0 / I.z : 0 + ); + this.updateInertiaWorld(true); +}; + +/** + * Get world velocity of a point in the body. + * @method getVelocityAtWorldPoint + * @param {Vec3} worldPoint + * @param {Vec3} result + * @return {Vec3} The result vector. + */ +Body.prototype.getVelocityAtWorldPoint = function(worldPoint, result){ + var r = new Vec3(); + worldPoint.vsub(this.position, r); + this.angularVelocity.cross(r, result); + this.velocity.vadd(result, result); + return result; +}; + +},{"../collision/AABB":3,"../material/Material":25,"../math/Mat3":27,"../math/Quaternion":28,"../math/Vec3":30,"../shapes/Box":37,"../shapes/Shape":43,"../utils/EventTarget":49}],32:[function(_dereq_,module,exports){ +var Body = _dereq_('./Body'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var Ray = _dereq_('../collision/Ray'); +var WheelInfo = _dereq_('../objects/WheelInfo'); + +module.exports = RaycastVehicle; + +/** + * Vehicle helper class that casts rays from the wheel positions towards the ground and applies forces. + * @class RaycastVehicle + * @constructor + * @param {object} [options] + * @param {Body} [options.chassisBody] The car chassis body. + * @param {integer} [options.indexRightAxis] Axis to use for right. x=0, y=1, z=2 + * @param {integer} [options.indexLeftAxis] + * @param {integer} [options.indexUpAxis] + */ +function RaycastVehicle(options){ + + /** + * @property {Body} chassisBody + */ + this.chassisBody = options.chassisBody; + + /** + * An array of WheelInfo objects. + * @property {array} wheelInfos + */ + this.wheelInfos = []; + + /** + * Will be set to true if the car is sliding. + * @property {boolean} sliding + */ + this.sliding = false; + + /** + * @property {World} world + */ + this.world = null; + + /** + * Index of the right axis, 0=x, 1=y, 2=z + * @property {integer} indexRightAxis + * @default 1 + */ + this.indexRightAxis = typeof(options.indexRightAxis) !== 'undefined' ? options.indexRightAxis : 1; + + /** + * Index of the forward axis, 0=x, 1=y, 2=z + * @property {integer} indexForwardAxis + * @default 0 + */ + this.indexForwardAxis = typeof(options.indexForwardAxis) !== 'undefined' ? options.indexForwardAxis : 0; + + /** + * Index of the up axis, 0=x, 1=y, 2=z + * @property {integer} indexUpAxis + * @default 2 + */ + this.indexUpAxis = typeof(options.indexUpAxis) !== 'undefined' ? options.indexUpAxis : 2; +} + +var tmpVec1 = new Vec3(); +var tmpVec2 = new Vec3(); +var tmpVec3 = new Vec3(); +var tmpVec4 = new Vec3(); +var tmpVec5 = new Vec3(); +var tmpVec6 = new Vec3(); +var tmpRay = new Ray(); + +/** + * Add a wheel. For information about the options, see WheelInfo. + * @method addWheel + * @param {object} [options] + */ +RaycastVehicle.prototype.addWheel = function(options){ + options = options || {}; + + var info = new WheelInfo(options); + var index = this.wheelInfos.length; + this.wheelInfos.push(info); + + return index; +}; + +/** + * Set the steering value of a wheel. + * @method setSteeringValue + * @param {number} value + * @param {integer} wheelIndex + */ +RaycastVehicle.prototype.setSteeringValue = function(value, wheelIndex){ + var wheel = this.wheelInfos[wheelIndex]; + wheel.steering = value; +}; + +var torque = new Vec3(); + +/** + * Set the wheel force to apply on one of the wheels each time step + * @method applyEngineForce + * @param {number} value + * @param {integer} wheelIndex + */ +RaycastVehicle.prototype.applyEngineForce = function(value, wheelIndex){ + this.wheelInfos[wheelIndex].engineForce = value; +}; + +/** + * Set the braking force of a wheel + * @method setBrake + * @param {number} brake + * @param {integer} wheelIndex + */ +RaycastVehicle.prototype.setBrake = function(brake, wheelIndex){ + this.wheelInfos[wheelIndex].brake = brake; +}; + +/** + * Add the vehicle including its constraints to the world. + * @method addToWorld + * @param {World} world + */ +RaycastVehicle.prototype.addToWorld = function(world){ + var constraints = this.constraints; + world.add(this.chassisBody); + var that = this; + this.preStepCallback = function(){ + that.updateVehicle(world.dt); + }; + world.addEventListener('preStep', this.preStepCallback); + this.world = world; +}; + +/** + * Get one of the wheel axles, world-oriented. + * @private + * @method getVehicleAxisWorld + * @param {integer} axisIndex + * @param {Vec3} result + */ +RaycastVehicle.prototype.getVehicleAxisWorld = function(axisIndex, result){ + result.set( + axisIndex === 0 ? 1 : 0, + axisIndex === 1 ? 1 : 0, + axisIndex === 2 ? 1 : 0 + ); + this.chassisBody.vectorToWorldFrame(result, result); +}; + +RaycastVehicle.prototype.updateVehicle = function(timeStep){ + var wheelInfos = this.wheelInfos; + var numWheels = wheelInfos.length; + var chassisBody = this.chassisBody; + + for (var i = 0; i < numWheels; i++) { + this.updateWheelTransform(i); + } + + this.currentVehicleSpeedKmHour = 3.6 * chassisBody.velocity.norm(); + + var forwardWorld = new Vec3(); + this.getVehicleAxisWorld(this.indexForwardAxis, forwardWorld); + + if (forwardWorld.dot(chassisBody.velocity) < 0){ + this.currentVehicleSpeedKmHour *= -1; + } + + // simulate suspension + for (var i = 0; i < numWheels; i++) { + this.castRay(wheelInfos[i]); + } + + this.updateSuspension(timeStep); + + var impulse = new Vec3(); + var relpos = new Vec3(); + for (var i = 0; i < numWheels; i++) { + //apply suspension force + var wheel = wheelInfos[i]; + var suspensionForce = wheel.suspensionForce; + if (suspensionForce > wheel.maxSuspensionForce) { + suspensionForce = wheel.maxSuspensionForce; + } + wheel.raycastResult.hitNormalWorld.scale(suspensionForce * timeStep, impulse); + + wheel.raycastResult.hitPointWorld.vsub(chassisBody.position, relpos); + chassisBody.applyImpulse(impulse, wheel.raycastResult.hitPointWorld/*relpos*/); + } + + this.updateFriction(timeStep); + + var hitNormalWorldScaledWithProj = new Vec3(); + var fwd = new Vec3(); + var vel = new Vec3(); + for (i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + //var relpos = new Vec3(); + //wheel.chassisConnectionPointWorld.vsub(chassisBody.position, relpos); + chassisBody.getVelocityAtWorldPoint(wheel.chassisConnectionPointWorld, vel); + + // Hack to get the rotation in the correct direction + var m = 1; + switch(this.indexUpAxis){ + case 1: + m = -1; + break; + } + + if (wheel.isInContact) { + + this.getVehicleAxisWorld(this.indexForwardAxis, fwd); + var proj = fwd.dot(wheel.raycastResult.hitNormalWorld); + wheel.raycastResult.hitNormalWorld.scale(proj, hitNormalWorldScaledWithProj); + + fwd.vsub(hitNormalWorldScaledWithProj, fwd); + + var proj2 = fwd.dot(vel); + wheel.deltaRotation = m * proj2 * timeStep / wheel.radius; + } + + if((wheel.sliding || !wheel.isInContact) && wheel.engineForce !== 0 && wheel.useCustomSlidingRotationalSpeed){ + // Apply custom rotation when accelerating and sliding + wheel.deltaRotation = (wheel.engineForce > 0 ? 1 : -1) * wheel.customSlidingRotationalSpeed * timeStep; + } + + // Lock wheels + if(Math.abs(wheel.brake) > Math.abs(wheel.engineForce)){ + wheel.deltaRotation = 0; + } + + wheel.rotation += wheel.deltaRotation; // Use the old value + wheel.deltaRotation *= 0.99; // damping of rotation when not in contact + } +}; + +RaycastVehicle.prototype.updateSuspension = function(deltaTime) { + var chassisBody = this.chassisBody; + var chassisMass = chassisBody.mass; + var wheelInfos = this.wheelInfos; + var numWheels = wheelInfos.length; + + for (var w_it = 0; w_it < numWheels; w_it++){ + var wheel = wheelInfos[w_it]; + + if (wheel.isInContact){ + var force; + + // Spring + var susp_length = wheel.suspensionRestLength; + var current_length = wheel.suspensionLength; + var length_diff = (susp_length - current_length); + + force = wheel.suspensionStiffness * length_diff * wheel.clippedInvContactDotSuspension; + + // Damper + var projected_rel_vel = wheel.suspensionRelativeVelocity; + var susp_damping; + if (projected_rel_vel < 0) { + susp_damping = wheel.dampingCompression; + } else { + susp_damping = wheel.dampingRelaxation; + } + force -= susp_damping * projected_rel_vel; + + wheel.suspensionForce = force * chassisMass; + if (wheel.suspensionForce < 0) { + wheel.suspensionForce = 0; + } + } else { + wheel.suspensionForce = 0; + } + } +}; + +/** + * Remove the vehicle including its constraints from the world. + * @method removeFromWorld + * @param {World} world + */ +RaycastVehicle.prototype.removeFromWorld = function(world){ + var constraints = this.constraints; + world.remove(this.chassisBody); + world.removeEventListener('preStep', this.preStepCallback); + this.world = null; +}; + +var castRay_rayvector = new Vec3(); +var castRay_target = new Vec3(); +RaycastVehicle.prototype.castRay = function(wheel) { + var rayvector = castRay_rayvector; + var target = castRay_target; + + this.updateWheelTransformWorld(wheel); + var chassisBody = this.chassisBody; + + var depth = -1; + + var raylen = wheel.suspensionRestLength + wheel.radius; + + wheel.directionWorld.scale(raylen, rayvector); + var source = wheel.chassisConnectionPointWorld; + source.vadd(rayvector, target); + var raycastResult = wheel.raycastResult; + + var param = 0; + + raycastResult.reset(); + // Turn off ray collision with the chassis temporarily + var oldState = chassisBody.collisionResponse; + chassisBody.collisionResponse = false; + + // Cast ray against world + this.world.rayTest(source, target, raycastResult); + chassisBody.collisionResponse = oldState; + + var object = raycastResult.body; + + wheel.raycastResult.groundObject = 0; + + if (object) { + depth = raycastResult.distance; + wheel.raycastResult.hitNormalWorld = raycastResult.hitNormalWorld; + wheel.isInContact = true; + + var hitDistance = raycastResult.distance; + wheel.suspensionLength = hitDistance - wheel.radius; + + // clamp on max suspension travel + var minSuspensionLength = wheel.suspensionRestLength - wheel.maxSuspensionTravel; + var maxSuspensionLength = wheel.suspensionRestLength + wheel.maxSuspensionTravel; + if (wheel.suspensionLength < minSuspensionLength) { + wheel.suspensionLength = minSuspensionLength; + } + if (wheel.suspensionLength > maxSuspensionLength) { + wheel.suspensionLength = maxSuspensionLength; + wheel.raycastResult.reset(); + } + + var denominator = wheel.raycastResult.hitNormalWorld.dot(wheel.directionWorld); + + var chassis_velocity_at_contactPoint = new Vec3(); + chassisBody.getVelocityAtWorldPoint(wheel.raycastResult.hitPointWorld, chassis_velocity_at_contactPoint); + + var projVel = wheel.raycastResult.hitNormalWorld.dot( chassis_velocity_at_contactPoint ); + + if (denominator >= -0.1) { + wheel.suspensionRelativeVelocity = 0; + wheel.clippedInvContactDotSuspension = 1 / 0.1; + } else { + var inv = -1 / denominator; + wheel.suspensionRelativeVelocity = projVel * inv; + wheel.clippedInvContactDotSuspension = inv; + } + + } else { + + //put wheel info as in rest position + wheel.suspensionLength = wheel.suspensionRestLength + 0 * wheel.maxSuspensionTravel; + wheel.suspensionRelativeVelocity = 0.0; + wheel.directionWorld.scale(-1, wheel.raycastResult.hitNormalWorld); + wheel.clippedInvContactDotSuspension = 1.0; + } + + return depth; +}; + +RaycastVehicle.prototype.updateWheelTransformWorld = function(wheel){ + wheel.isInContact = false; + var chassisBody = this.chassisBody; + chassisBody.pointToWorldFrame(wheel.chassisConnectionPointLocal, wheel.chassisConnectionPointWorld); + chassisBody.vectorToWorldFrame(wheel.directionLocal, wheel.directionWorld); + chassisBody.vectorToWorldFrame(wheel.axleLocal, wheel.axleWorld); +}; + + +/** + * Update one of the wheel transform. + * Note when rendering wheels: during each step, wheel transforms are updated BEFORE the chassis; ie. their position becomes invalid after the step. Thus when you render wheels, you must update wheel transforms before rendering them. See raycastVehicle demo for an example. + * @method updateWheelTransform + * @param {integer} wheelIndex The wheel index to update. + */ +RaycastVehicle.prototype.updateWheelTransform = function(wheelIndex){ + var up = tmpVec4; + var right = tmpVec5; + var fwd = tmpVec6; + + var wheel = this.wheelInfos[wheelIndex]; + this.updateWheelTransformWorld(wheel); + + wheel.directionLocal.scale(-1, up); + right.copy(wheel.axleLocal); + up.cross(right, fwd); + fwd.normalize(); + right.normalize(); + + // Rotate around steering over the wheelAxle + var steering = wheel.steering; + var steeringOrn = new Quaternion(); + steeringOrn.setFromAxisAngle(up, steering); + + var rotatingOrn = new Quaternion(); + rotatingOrn.setFromAxisAngle(right, wheel.rotation); + + // World rotation of the wheel + var q = wheel.worldTransform.quaternion; + this.chassisBody.quaternion.mult(steeringOrn, q); + q.mult(rotatingOrn, q); + + q.normalize(); + + // world position of the wheel + var p = wheel.worldTransform.position; + p.copy(wheel.directionWorld); + p.scale(wheel.suspensionLength, p); + p.vadd(wheel.chassisConnectionPointWorld, p); +}; + +var directions = [ + new Vec3(1, 0, 0), + new Vec3(0, 1, 0), + new Vec3(0, 0, 1) +]; + +/** + * Get the world transform of one of the wheels + * @method getWheelTransformWorld + * @param {integer} wheelIndex + * @return {Transform} + */ +RaycastVehicle.prototype.getWheelTransformWorld = function(wheelIndex) { + return this.wheelInfos[wheelIndex].worldTransform; +}; + + +var updateFriction_surfNormalWS_scaled_proj = new Vec3(); +var updateFriction_axle = []; +var updateFriction_forwardWS = []; +var sideFrictionStiffness2 = 1; +RaycastVehicle.prototype.updateFriction = function(timeStep) { + var surfNormalWS_scaled_proj = updateFriction_surfNormalWS_scaled_proj; + + //calculate the impulse, so that the wheels don't move sidewards + var wheelInfos = this.wheelInfos; + var numWheels = wheelInfos.length; + var chassisBody = this.chassisBody; + var forwardWS = updateFriction_forwardWS; + var axle = updateFriction_axle; + + var numWheelsOnGround = 0; + + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + + var groundObject = wheel.raycastResult.body; + if (groundObject){ + numWheelsOnGround++; + } + + wheel.sideImpulse = 0; + wheel.forwardImpulse = 0; + if(!forwardWS[i]){ + forwardWS[i] = new Vec3(); + } + if(!axle[i]){ + axle[i] = new Vec3(); + } + } + + for (var i = 0; i < numWheels; i++){ + var wheel = wheelInfos[i]; + + var groundObject = wheel.raycastResult.body; + + if (groundObject) { + var axlei = axle[i]; + var wheelTrans = this.getWheelTransformWorld(i); + + // Get world axle + wheelTrans.vectorToWorldFrame(directions[this.indexRightAxis], axlei); + + var surfNormalWS = wheel.raycastResult.hitNormalWorld; + var proj = axlei.dot(surfNormalWS); + surfNormalWS.scale(proj, surfNormalWS_scaled_proj); + axlei.vsub(surfNormalWS_scaled_proj, axlei); + axlei.normalize(); + + surfNormalWS.cross(axlei, forwardWS[i]); + forwardWS[i].normalize(); + + wheel.sideImpulse = resolveSingleBilateral( + chassisBody, + wheel.raycastResult.hitPointWorld, + groundObject, + wheel.raycastResult.hitPointWorld, + axlei + ); + + wheel.sideImpulse *= sideFrictionStiffness2; + } + } + + var sideFactor = 1; + var fwdFactor = 0.5; + + this.sliding = false; + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + var groundObject = wheel.raycastResult.body; + + var rollingFriction = 0; + + wheel.slipInfo = 1; + if (groundObject) { + var defaultRollingFrictionImpulse = 0; + var maxImpulse = wheel.brake ? wheel.brake : defaultRollingFrictionImpulse; + + // btWheelContactPoint contactPt(chassisBody,groundObject,wheelInfraycastInfo.hitPointWorld,forwardWS[wheel],maxImpulse); + // rollingFriction = calcRollingFriction(contactPt); + rollingFriction = calcRollingFriction(chassisBody, groundObject, wheel.raycastResult.hitPointWorld, forwardWS[i], maxImpulse); + + rollingFriction += wheel.engineForce * timeStep; + + // rollingFriction = 0; + var factor = maxImpulse / rollingFriction; + wheel.slipInfo *= factor; + } + + //switch between active rolling (throttle), braking and non-active rolling friction (nthrottle/break) + + wheel.forwardImpulse = 0; + wheel.skidInfo = 1; + + if (groundObject) { + wheel.skidInfo = 1; + + var maximp = wheel.suspensionForce * timeStep * wheel.frictionSlip; + var maximpSide = maximp; + + var maximpSquared = maximp * maximpSide; + + wheel.forwardImpulse = rollingFriction;//wheelInfo.engineForce* timeStep; + + var x = wheel.forwardImpulse * fwdFactor; + var y = wheel.sideImpulse * sideFactor; + + var impulseSquared = x * x + y * y; + + wheel.sliding = false; + if (impulseSquared > maximpSquared) { + this.sliding = true; + wheel.sliding = true; + + var factor = maximp / Math.sqrt(impulseSquared); + + wheel.skidInfo *= factor; + } + } + } + + if (this.sliding) { + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + if (wheel.sideImpulse !== 0) { + if (wheel.skidInfo < 1){ + wheel.forwardImpulse *= wheel.skidInfo; + wheel.sideImpulse *= wheel.skidInfo; + } + } + } + } + + // apply the impulses + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + + var rel_pos = new Vec3(); + //wheel.raycastResult.hitPointWorld.vsub(chassisBody.position, rel_pos); + // cannons applyimpulse is using world coord for the position + rel_pos.copy(wheel.raycastResult.hitPointWorld); + + if (wheel.forwardImpulse !== 0) { + var impulse = new Vec3(); + forwardWS[i].scale(wheel.forwardImpulse, impulse); + chassisBody.applyImpulse(impulse, rel_pos); + } + + if (wheel.sideImpulse !== 0){ + var groundObject = wheel.raycastResult.body; + + var rel_pos2 = new Vec3(); + //wheel.raycastResult.hitPointWorld.vsub(groundObject.position, rel_pos2); + rel_pos2.copy(wheel.raycastResult.hitPointWorld); + var sideImp = new Vec3(); + axle[i].scale(wheel.sideImpulse, sideImp); + + // Scale the relative position in the up direction with rollInfluence. + // If rollInfluence is 1, the impulse will be applied on the hitPoint (easy to roll over), if it is zero it will be applied in the same plane as the center of mass (not easy to roll over). + chassisBody.pointToLocalFrame(rel_pos, rel_pos); + rel_pos['xyz'[this.indexUpAxis]] *= wheel.rollInfluence; + chassisBody.pointToWorldFrame(rel_pos, rel_pos); + chassisBody.applyImpulse(sideImp, rel_pos); + + //apply friction impulse on the ground + sideImp.scale(-1, sideImp); + groundObject.applyImpulse(sideImp, rel_pos2); + } + } +}; + +var calcRollingFriction_vel1 = new Vec3(); +var calcRollingFriction_vel2 = new Vec3(); +var calcRollingFriction_vel = new Vec3(); + +function calcRollingFriction(body0, body1, frictionPosWorld, frictionDirectionWorld, maxImpulse) { + var j1 = 0; + var contactPosWorld = frictionPosWorld; + + // var rel_pos1 = new Vec3(); + // var rel_pos2 = new Vec3(); + var vel1 = calcRollingFriction_vel1; + var vel2 = calcRollingFriction_vel2; + var vel = calcRollingFriction_vel; + // contactPosWorld.vsub(body0.position, rel_pos1); + // contactPosWorld.vsub(body1.position, rel_pos2); + + body0.getVelocityAtWorldPoint(contactPosWorld, vel1); + body1.getVelocityAtWorldPoint(contactPosWorld, vel2); + vel1.vsub(vel2, vel); + + var vrel = frictionDirectionWorld.dot(vel); + + var denom0 = computeImpulseDenominator(body0, frictionPosWorld, frictionDirectionWorld); + var denom1 = computeImpulseDenominator(body1, frictionPosWorld, frictionDirectionWorld); + var relaxation = 1; + var jacDiagABInv = relaxation / (denom0 + denom1); + + // calculate j that moves us to zero relative velocity + j1 = -vrel * jacDiagABInv; + + if (maxImpulse < j1) { + j1 = maxImpulse; + } + if (j1 < -maxImpulse) { + j1 = -maxImpulse; + } + + return j1; +} + +var computeImpulseDenominator_r0 = new Vec3(); +var computeImpulseDenominator_c0 = new Vec3(); +var computeImpulseDenominator_vec = new Vec3(); +var computeImpulseDenominator_m = new Vec3(); +function computeImpulseDenominator(body, pos, normal) { + var r0 = computeImpulseDenominator_r0; + var c0 = computeImpulseDenominator_c0; + var vec = computeImpulseDenominator_vec; + var m = computeImpulseDenominator_m; + + pos.vsub(body.position, r0); + r0.cross(normal, c0); + body.invInertiaWorld.vmult(c0, m); + m.cross(r0, vec); + + return body.invMass + normal.dot(vec); +} + + +var resolveSingleBilateral_vel1 = new Vec3(); +var resolveSingleBilateral_vel2 = new Vec3(); +var resolveSingleBilateral_vel = new Vec3(); + +//bilateral constraint between two dynamic objects +function resolveSingleBilateral(body1, pos1, body2, pos2, normal, impulse){ + var normalLenSqr = normal.norm2(); + if (normalLenSqr > 1.1){ + return 0; // no impulse + } + // var rel_pos1 = new Vec3(); + // var rel_pos2 = new Vec3(); + // pos1.vsub(body1.position, rel_pos1); + // pos2.vsub(body2.position, rel_pos2); + + var vel1 = resolveSingleBilateral_vel1; + var vel2 = resolveSingleBilateral_vel2; + var vel = resolveSingleBilateral_vel; + body1.getVelocityAtWorldPoint(pos1, vel1); + body2.getVelocityAtWorldPoint(pos2, vel2); + + vel1.vsub(vel2, vel); + + var rel_vel = normal.dot(vel); + + var contactDamping = 0.2; + var massTerm = 1 / (body1.invMass + body2.invMass); + var impulse = - contactDamping * rel_vel * massTerm; + + return impulse; +} +},{"../collision/Ray":9,"../collision/RaycastResult":10,"../math/Quaternion":28,"../math/Vec3":30,"../objects/WheelInfo":36,"./Body":31}],33:[function(_dereq_,module,exports){ +var Body = _dereq_('./Body'); +var Sphere = _dereq_('../shapes/Sphere'); +var Box = _dereq_('../shapes/Box'); +var Vec3 = _dereq_('../math/Vec3'); +var HingeConstraint = _dereq_('../constraints/HingeConstraint'); + +module.exports = RigidVehicle; + +/** + * Simple vehicle helper class with spherical rigid body wheels. + * @class RigidVehicle + * @constructor + * @param {Body} [options.chassisBody] + */ +function RigidVehicle(options){ + this.wheelBodies = []; + + /** + * @property coordinateSystem + * @type {Vec3} + */ + this.coordinateSystem = typeof(options.coordinateSystem)==='undefined' ? new Vec3(1, 2, 3) : options.coordinateSystem.clone(); + + /** + * @property {Body} chassisBody + */ + this.chassisBody = options.chassisBody; + + if(!this.chassisBody){ + // No chassis body given. Create it! + var chassisShape = new Box(new Vec3(5, 2, 0.5)); + this.chassisBody = new Body(1, chassisShape); + } + + /** + * @property constraints + * @type {Array} + */ + this.constraints = []; + + this.wheelAxes = []; + this.wheelForces = []; +} + +/** + * Add a wheel + * @method addWheel + * @param {object} options + * @param {boolean} [options.isFrontWheel] + * @param {Vec3} [options.position] Position of the wheel, locally in the chassis body. + * @param {Vec3} [options.direction] Slide direction of the wheel along the suspension. + * @param {Vec3} [options.axis] Axis of rotation of the wheel, locally defined in the chassis. + * @param {Body} [options.body] The wheel body. + */ +RigidVehicle.prototype.addWheel = function(options){ + options = options || {}; + var wheelBody = options.body; + if(!wheelBody){ + wheelBody = new Body(1, new Sphere(1.2)); + } + this.wheelBodies.push(wheelBody); + this.wheelForces.push(0); + + // Position constrain wheels + var zero = new Vec3(); + var position = typeof(options.position) !== 'undefined' ? options.position.clone() : new Vec3(); + + // Set position locally to the chassis + var worldPosition = new Vec3(); + this.chassisBody.pointToWorldFrame(position, worldPosition); + wheelBody.position.set(worldPosition.x, worldPosition.y, worldPosition.z); + + // Constrain wheel + var axis = typeof(options.axis) !== 'undefined' ? options.axis.clone() : new Vec3(0, 1, 0); + this.wheelAxes.push(axis); + + var hingeConstraint = new HingeConstraint(this.chassisBody, wheelBody, { + pivotA: position, + axisA: axis, + pivotB: Vec3.ZERO, + axisB: axis, + collideConnected: false + }); + this.constraints.push(hingeConstraint); + + return this.wheelBodies.length - 1; +}; + +/** + * Set the steering value of a wheel. + * @method setSteeringValue + * @param {number} value + * @param {integer} wheelIndex + * @todo check coordinateSystem + */ +RigidVehicle.prototype.setSteeringValue = function(value, wheelIndex){ + // Set angle of the hinge axis + var axis = this.wheelAxes[wheelIndex]; + + var c = Math.cos(value), + s = Math.sin(value), + x = axis.x, + y = axis.y; + this.constraints[wheelIndex].axisA.set( + c*x -s*y, + s*x +c*y, + 0 + ); +}; + +/** + * Set the target rotational speed of the hinge constraint. + * @method setMotorSpeed + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.setMotorSpeed = function(value, wheelIndex){ + var hingeConstraint = this.constraints[wheelIndex]; + hingeConstraint.enableMotor(); + hingeConstraint.motorTargetVelocity = value; +}; + +/** + * Set the target rotational speed of the hinge constraint. + * @method disableMotor + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.disableMotor = function(wheelIndex){ + var hingeConstraint = this.constraints[wheelIndex]; + hingeConstraint.disableMotor(); +}; + +var torque = new Vec3(); + +/** + * Set the wheel force to apply on one of the wheels each time step + * @method setWheelForce + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.setWheelForce = function(value, wheelIndex){ + this.wheelForces[wheelIndex] = value; +}; + +/** + * Apply a torque on one of the wheels. + * @method applyWheelForce + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.applyWheelForce = function(value, wheelIndex){ + var axis = this.wheelAxes[wheelIndex]; + var wheelBody = this.wheelBodies[wheelIndex]; + var bodyTorque = wheelBody.torque; + + axis.scale(value, torque); + wheelBody.vectorToWorldFrame(torque, torque); + bodyTorque.vadd(torque, bodyTorque); +}; + +/** + * Add the vehicle including its constraints to the world. + * @method addToWorld + * @param {World} world + */ +RigidVehicle.prototype.addToWorld = function(world){ + var constraints = this.constraints; + var bodies = this.wheelBodies.concat([this.chassisBody]); + + for (var i = 0; i < bodies.length; i++) { + world.add(bodies[i]); + } + + for (var i = 0; i < constraints.length; i++) { + world.addConstraint(constraints[i]); + } + + world.addEventListener('preStep', this._update.bind(this)); +}; + +RigidVehicle.prototype._update = function(){ + var wheelForces = this.wheelForces; + for (var i = 0; i < wheelForces.length; i++) { + this.applyWheelForce(wheelForces[i], i); + } +}; + +/** + * Remove the vehicle including its constraints from the world. + * @method removeFromWorld + * @param {World} world + */ +RigidVehicle.prototype.removeFromWorld = function(world){ + var constraints = this.constraints; + var bodies = this.wheelBodies.concat([this.chassisBody]); + + for (var i = 0; i < bodies.length; i++) { + world.remove(bodies[i]); + } + + for (var i = 0; i < constraints.length; i++) { + world.removeConstraint(constraints[i]); + } +}; + +var worldAxis = new Vec3(); + +/** + * Get current rotational velocity of a wheel + * @method getWheelSpeed + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.getWheelSpeed = function(wheelIndex){ + var axis = this.wheelAxes[wheelIndex]; + var wheelBody = this.wheelBodies[wheelIndex]; + var w = wheelBody.angularVelocity; + this.chassisBody.vectorToWorldFrame(axis, worldAxis); + return w.dot(worldAxis); +}; + +},{"../constraints/HingeConstraint":15,"../math/Vec3":30,"../shapes/Box":37,"../shapes/Sphere":44,"./Body":31}],34:[function(_dereq_,module,exports){ +module.exports = SPHSystem; + +var Shape = _dereq_('../shapes/Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Particle = _dereq_('../shapes/Particle'); +var Body = _dereq_('../objects/Body'); +var Material = _dereq_('../material/Material'); + +/** + * Smoothed-particle hydrodynamics system + * @class SPHSystem + * @constructor + */ +function SPHSystem(){ + this.particles = []; + + /** + * Density of the system (kg/m3). + * @property {number} density + */ + this.density = 1; + + /** + * Distance below which two particles are considered to be neighbors. + * It should be adjusted so there are about 15-20 neighbor particles within this radius. + * @property {number} smoothingRadius + */ + this.smoothingRadius = 1; + this.speedOfSound = 1; + + /** + * Viscosity of the system. + * @property {number} viscosity + */ + this.viscosity = 0.01; + this.eps = 0.000001; + + // Stuff Computed per particle + this.pressures = []; + this.densities = []; + this.neighbors = []; +} + +/** + * Add a particle to the system. + * @method add + * @param {Body} particle + */ +SPHSystem.prototype.add = function(particle){ + this.particles.push(particle); + if(this.neighbors.length < this.particles.length){ + this.neighbors.push([]); + } +}; + +/** + * Remove a particle from the system. + * @method remove + * @param {Body} particle + */ +SPHSystem.prototype.remove = function(particle){ + var idx = this.particles.indexOf(particle); + if(idx !== -1){ + this.particles.splice(idx,1); + if(this.neighbors.length > this.particles.length){ + this.neighbors.pop(); + } + } +}; + +/** + * Get neighbors within smoothing volume, save in the array neighbors + * @method getNeighbors + * @param {Body} particle + * @param {Array} neighbors + */ +var SPHSystem_getNeighbors_dist = new Vec3(); +SPHSystem.prototype.getNeighbors = function(particle,neighbors){ + var N = this.particles.length, + id = particle.id, + R2 = this.smoothingRadius * this.smoothingRadius, + dist = SPHSystem_getNeighbors_dist; + for(var i=0; i!==N; i++){ + var p = this.particles[i]; + p.position.vsub(particle.position,dist); + if(id!==p.id && dist.norm2() < R2){ + neighbors.push(p); + } + } +}; + +// Temp vectors for calculation +var SPHSystem_update_dist = new Vec3(), + SPHSystem_update_a_pressure = new Vec3(), + SPHSystem_update_a_visc = new Vec3(), + SPHSystem_update_gradW = new Vec3(), + SPHSystem_update_r_vec = new Vec3(), + SPHSystem_update_u = new Vec3(); // Relative velocity +SPHSystem.prototype.update = function(){ + var N = this.particles.length, + dist = SPHSystem_update_dist, + cs = this.speedOfSound, + eps = this.eps; + + for(var i=0; i!==N; i++){ + var p = this.particles[i]; // Current particle + var neighbors = this.neighbors[i]; + + // Get neighbors + neighbors.length = 0; + this.getNeighbors(p,neighbors); + neighbors.push(this.particles[i]); // Add current too + var numNeighbors = neighbors.length; + + // Accumulate density for the particle + var sum = 0.0; + for(var j=0; j!==numNeighbors; j++){ + + //printf("Current particle has position %f %f %f\n",objects[id].pos.x(),objects[id].pos.y(),objects[id].pos.z()); + p.position.vsub(neighbors[j].position, dist); + var len = dist.norm(); + + var weight = this.w(len); + sum += neighbors[j].mass * weight; + } + + // Save + this.densities[i] = sum; + this.pressures[i] = cs * cs * (this.densities[i] - this.density); + } + + // Add forces + + // Sum to these accelerations + var a_pressure= SPHSystem_update_a_pressure; + var a_visc = SPHSystem_update_a_visc; + var gradW = SPHSystem_update_gradW; + var r_vec = SPHSystem_update_r_vec; + var u = SPHSystem_update_u; + + for(var i=0; i!==N; i++){ + + var particle = this.particles[i]; + + a_pressure.set(0,0,0); + a_visc.set(0,0,0); + + // Init vars + var Pij; + var nabla; + var Vij; + + // Sum up for all other neighbors + var neighbors = this.neighbors[i]; + var numNeighbors = neighbors.length; + + //printf("Neighbors: "); + for(var j=0; j!==numNeighbors; j++){ + + var neighbor = neighbors[j]; + //printf("%d ",nj); + + // Get r once for all.. + particle.position.vsub(neighbor.position,r_vec); + var r = r_vec.norm(); + + // Pressure contribution + Pij = -neighbor.mass * (this.pressures[i] / (this.densities[i]*this.densities[i] + eps) + this.pressures[j] / (this.densities[j]*this.densities[j] + eps)); + this.gradw(r_vec, gradW); + // Add to pressure acceleration + gradW.mult(Pij , gradW); + a_pressure.vadd(gradW, a_pressure); + + // Viscosity contribution + neighbor.velocity.vsub(particle.velocity, u); + u.mult( 1.0 / (0.0001+this.densities[i] * this.densities[j]) * this.viscosity * neighbor.mass , u ); + nabla = this.nablaw(r); + u.mult(nabla,u); + // Add to viscosity acceleration + a_visc.vadd( u, a_visc ); + } + + // Calculate force + a_visc.mult(particle.mass, a_visc); + a_pressure.mult(particle.mass, a_pressure); + + // Add force to particles + particle.force.vadd(a_visc, particle.force); + particle.force.vadd(a_pressure, particle.force); + } +}; + +// Calculate the weight using the W(r) weightfunction +SPHSystem.prototype.w = function(r){ + // 315 + var h = this.smoothingRadius; + return 315.0/(64.0*Math.PI*Math.pow(h,9)) * Math.pow(h*h-r*r,3); +}; + +// calculate gradient of the weight function +SPHSystem.prototype.gradw = function(rVec,resultVec){ + var r = rVec.norm(), + h = this.smoothingRadius; + rVec.mult(945.0/(32.0*Math.PI*Math.pow(h,9)) * Math.pow((h*h-r*r),2) , resultVec); +}; + +// Calculate nabla(W) +SPHSystem.prototype.nablaw = function(r){ + var h = this.smoothingRadius; + var nabla = 945.0/(32.0*Math.PI*Math.pow(h,9)) * (h*h-r*r)*(7*r*r - 3*h*h); + return nabla; +}; + +},{"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Particle":41,"../shapes/Shape":43}],35:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); + +module.exports = Spring; + +/** + * A spring, connecting two bodies. + * + * @class Spring + * @constructor + * @param {Body} bodyA + * @param {Body} bodyB + * @param {Object} [options] + * @param {number} [options.restLength] A number > 0. Default: 1 + * @param {number} [options.stiffness] A number >= 0. Default: 100 + * @param {number} [options.damping] A number >= 0. Default: 1 + * @param {Vec3} [options.worldAnchorA] Where to hook the spring to body A, in world coordinates. + * @param {Vec3} [options.worldAnchorB] + * @param {Vec3} [options.localAnchorA] Where to hook the spring to body A, in local body coordinates. + * @param {Vec3} [options.localAnchorB] + */ +function Spring(bodyA,bodyB,options){ + options = options || {}; + + /** + * Rest length of the spring. + * @property restLength + * @type {number} + */ + this.restLength = typeof(options.restLength) === "number" ? options.restLength : 1; + + /** + * Stiffness of the spring. + * @property stiffness + * @type {number} + */ + this.stiffness = options.stiffness || 100; + + /** + * Damping of the spring. + * @property damping + * @type {number} + */ + this.damping = options.damping || 1; + + /** + * First connected body. + * @property bodyA + * @type {Body} + */ + this.bodyA = bodyA; + + /** + * Second connected body. + * @property bodyB + * @type {Body} + */ + this.bodyB = bodyB; + + /** + * Anchor for bodyA in local bodyA coordinates. + * @property localAnchorA + * @type {Vec3} + */ + this.localAnchorA = new Vec3(); + + /** + * Anchor for bodyB in local bodyB coordinates. + * @property localAnchorB + * @type {Vec3} + */ + this.localAnchorB = new Vec3(); + + if(options.localAnchorA){ + this.localAnchorA.copy(options.localAnchorA); + } + if(options.localAnchorB){ + this.localAnchorB.copy(options.localAnchorB); + } + if(options.worldAnchorA){ + this.setWorldAnchorA(options.worldAnchorA); + } + if(options.worldAnchorB){ + this.setWorldAnchorB(options.worldAnchorB); + } +} + +/** + * Set the anchor point on body A, using world coordinates. + * @method setWorldAnchorA + * @param {Vec3} worldAnchorA + */ +Spring.prototype.setWorldAnchorA = function(worldAnchorA){ + this.bodyA.pointToLocalFrame(worldAnchorA,this.localAnchorA); +}; + +/** + * Set the anchor point on body B, using world coordinates. + * @method setWorldAnchorB + * @param {Vec3} worldAnchorB + */ +Spring.prototype.setWorldAnchorB = function(worldAnchorB){ + this.bodyB.pointToLocalFrame(worldAnchorB,this.localAnchorB); +}; + +/** + * Get the anchor point on body A, in world coordinates. + * @method getWorldAnchorA + * @param {Vec3} result The vector to store the result in. + */ +Spring.prototype.getWorldAnchorA = function(result){ + this.bodyA.pointToWorldFrame(this.localAnchorA,result); +}; + +/** + * Get the anchor point on body B, in world coordinates. + * @method getWorldAnchorB + * @param {Vec3} result The vector to store the result in. + */ +Spring.prototype.getWorldAnchorB = function(result){ + this.bodyB.pointToWorldFrame(this.localAnchorB,result); +}; + +var applyForce_r = new Vec3(), + applyForce_r_unit = new Vec3(), + applyForce_u = new Vec3(), + applyForce_f = new Vec3(), + applyForce_worldAnchorA = new Vec3(), + applyForce_worldAnchorB = new Vec3(), + applyForce_ri = new Vec3(), + applyForce_rj = new Vec3(), + applyForce_ri_x_f = new Vec3(), + applyForce_rj_x_f = new Vec3(), + applyForce_tmp = new Vec3(); + +/** + * Apply the spring force to the connected bodies. + * @method applyForce + */ +Spring.prototype.applyForce = function(){ + var k = this.stiffness, + d = this.damping, + l = this.restLength, + bodyA = this.bodyA, + bodyB = this.bodyB, + r = applyForce_r, + r_unit = applyForce_r_unit, + u = applyForce_u, + f = applyForce_f, + tmp = applyForce_tmp; + + var worldAnchorA = applyForce_worldAnchorA, + worldAnchorB = applyForce_worldAnchorB, + ri = applyForce_ri, + rj = applyForce_rj, + ri_x_f = applyForce_ri_x_f, + rj_x_f = applyForce_rj_x_f; + + // Get world anchors + this.getWorldAnchorA(worldAnchorA); + this.getWorldAnchorB(worldAnchorB); + + // Get offset points + worldAnchorA.vsub(bodyA.position,ri); + worldAnchorB.vsub(bodyB.position,rj); + + // Compute distance vector between world anchor points + worldAnchorB.vsub(worldAnchorA,r); + var rlen = r.norm(); + r_unit.copy(r); + r_unit.normalize(); + + // Compute relative velocity of the anchor points, u + bodyB.velocity.vsub(bodyA.velocity,u); + // Add rotational velocity + + bodyB.angularVelocity.cross(rj,tmp); + u.vadd(tmp,u); + bodyA.angularVelocity.cross(ri,tmp); + u.vsub(tmp,u); + + // F = - k * ( x - L ) - D * ( u ) + r_unit.mult(-k*(rlen-l) - d*u.dot(r_unit), f); + + // Add forces to bodies + bodyA.force.vsub(f,bodyA.force); + bodyB.force.vadd(f,bodyB.force); + + // Angular force + ri.cross(f,ri_x_f); + rj.cross(f,rj_x_f); + bodyA.torque.vsub(ri_x_f,bodyA.torque); + bodyB.torque.vadd(rj_x_f,bodyB.torque); +}; + +},{"../math/Vec3":30}],36:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); +var Transform = _dereq_('../math/Transform'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var Utils = _dereq_('../utils/Utils'); + +module.exports = WheelInfo; + +/** + * @class WheelInfo + * @constructor + * @param {Object} [options] + * + * @param {Vec3} [options.chassisConnectionPointLocal] + * @param {Vec3} [options.chassisConnectionPointWorld] + * @param {Vec3} [options.directionLocal] + * @param {Vec3} [options.directionWorld] + * @param {Vec3} [options.axleLocal] + * @param {Vec3} [options.axleWorld] + * @param {number} [options.suspensionRestLength=1] + * @param {number} [options.suspensionMaxLength=2] + * @param {number} [options.radius=1] + * @param {number} [options.suspensionStiffness=100] + * @param {number} [options.dampingCompression=10] + * @param {number} [options.dampingRelaxation=10] + * @param {number} [options.frictionSlip=10000] + * @param {number} [options.steering=0] + * @param {number} [options.rotation=0] + * @param {number} [options.deltaRotation=0] + * @param {number} [options.rollInfluence=0.01] + * @param {number} [options.maxSuspensionForce] + * @param {boolean} [options.isFrontWheel=true] + * @param {number} [options.clippedInvContactDotSuspension=1] + * @param {number} [options.suspensionRelativeVelocity=0] + * @param {number} [options.suspensionForce=0] + * @param {number} [options.skidInfo=0] + * @param {number} [options.suspensionLength=0] + * @param {number} [options.maxSuspensionTravel=1] + * @param {boolean} [options.useCustomSlidingRotationalSpeed=false] + * @param {number} [options.customSlidingRotationalSpeed=-0.1] + */ +function WheelInfo(options){ + options = Utils.defaults(options, { + chassisConnectionPointLocal: new Vec3(), + chassisConnectionPointWorld: new Vec3(), + directionLocal: new Vec3(), + directionWorld: new Vec3(), + axleLocal: new Vec3(), + axleWorld: new Vec3(), + suspensionRestLength: 1, + suspensionMaxLength: 2, + radius: 1, + suspensionStiffness: 100, + dampingCompression: 10, + dampingRelaxation: 10, + frictionSlip: 10000, + steering: 0, + rotation: 0, + deltaRotation: 0, + rollInfluence: 0.01, + maxSuspensionForce: Number.MAX_VALUE, + isFrontWheel: true, + clippedInvContactDotSuspension: 1, + suspensionRelativeVelocity: 0, + suspensionForce: 0, + skidInfo: 0, + suspensionLength: 0, + maxSuspensionTravel: 1, + useCustomSlidingRotationalSpeed: false, + customSlidingRotationalSpeed: -0.1 + }); + + /** + * Max travel distance of the suspension, in meters. + * @property {number} maxSuspensionTravel + */ + this.maxSuspensionTravel = options.maxSuspensionTravel; + + /** + * Speed to apply to the wheel rotation when the wheel is sliding. + * @property {number} customSlidingRotationalSpeed + */ + this.customSlidingRotationalSpeed = options.customSlidingRotationalSpeed; + + /** + * If the customSlidingRotationalSpeed should be used. + * @property {Boolean} useCustomSlidingRotationalSpeed + */ + this.useCustomSlidingRotationalSpeed = options.useCustomSlidingRotationalSpeed; + + /** + * @property {Boolean} sliding + */ + this.sliding = false; + + /** + * Connection point, defined locally in the chassis body frame. + * @property {Vec3} chassisConnectionPointLocal + */ + this.chassisConnectionPointLocal = options.chassisConnectionPointLocal.clone(); + + /** + * @property {Vec3} chassisConnectionPointWorld + */ + this.chassisConnectionPointWorld = options.chassisConnectionPointWorld.clone(); + + /** + * @property {Vec3} directionLocal + */ + this.directionLocal = options.directionLocal.clone(); + + /** + * @property {Vec3} directionWorld + */ + this.directionWorld = options.directionWorld.clone(); + + /** + * @property {Vec3} axleLocal + */ + this.axleLocal = options.axleLocal.clone(); + + /** + * @property {Vec3} axleWorld + */ + this.axleWorld = options.axleWorld.clone(); + + /** + * @property {number} suspensionRestLength + */ + this.suspensionRestLength = options.suspensionRestLength; + + /** + * @property {number} suspensionMaxLength + */ + this.suspensionMaxLength = options.suspensionMaxLength; + + /** + * @property {number} radius + */ + this.radius = options.radius; + + /** + * @property {number} suspensionStiffness + */ + this.suspensionStiffness = options.suspensionStiffness; + + /** + * @property {number} dampingCompression + */ + this.dampingCompression = options.dampingCompression; + + /** + * @property {number} dampingRelaxation + */ + this.dampingRelaxation = options.dampingRelaxation; + + /** + * @property {number} frictionSlip + */ + this.frictionSlip = options.frictionSlip; + + /** + * @property {number} steering + */ + this.steering = 0; + + /** + * Rotation value, in radians. + * @property {number} rotation + */ + this.rotation = 0; + + /** + * @property {number} deltaRotation + */ + this.deltaRotation = 0; + + /** + * @property {number} rollInfluence + */ + this.rollInfluence = options.rollInfluence; + + /** + * @property {number} maxSuspensionForce + */ + this.maxSuspensionForce = options.maxSuspensionForce; + + /** + * @property {number} engineForce + */ + this.engineForce = 0; + + /** + * @property {number} brake + */ + this.brake = 0; + + /** + * @property {number} isFrontWheel + */ + this.isFrontWheel = options.isFrontWheel; + + /** + * @property {number} clippedInvContactDotSuspension + */ + this.clippedInvContactDotSuspension = 1; + + /** + * @property {number} suspensionRelativeVelocity + */ + this.suspensionRelativeVelocity = 0; + + /** + * @property {number} suspensionForce + */ + this.suspensionForce = 0; + + /** + * @property {number} skidInfo + */ + this.skidInfo = 0; + + /** + * @property {number} suspensionLength + */ + this.suspensionLength = 0; + + /** + * @property {number} sideImpulse + */ + this.sideImpulse = 0; + + /** + * @property {number} forwardImpulse + */ + this.forwardImpulse = 0; + + /** + * The result from raycasting + * @property {RaycastResult} raycastResult + */ + this.raycastResult = new RaycastResult(); + + /** + * Wheel world transform + * @property {Transform} worldTransform + */ + this.worldTransform = new Transform(); + + /** + * @property {boolean} isInContact + */ + this.isInContact = false; +} + +var chassis_velocity_at_contactPoint = new Vec3(); +var relpos = new Vec3(); +var chassis_velocity_at_contactPoint = new Vec3(); +WheelInfo.prototype.updateWheel = function(chassis){ + var raycastResult = this.raycastResult; + + if (this.isInContact){ + var project= raycastResult.hitNormalWorld.dot(raycastResult.directionWorld); + raycastResult.hitPointWorld.vsub(chassis.position, relpos); + chassis.getVelocityAtWorldPoint(relpos, chassis_velocity_at_contactPoint); + var projVel = raycastResult.hitNormalWorld.dot( chassis_velocity_at_contactPoint ); + if (project >= -0.1) { + this.suspensionRelativeVelocity = 0.0; + this.clippedInvContactDotSuspension = 1.0 / 0.1; + } else { + var inv = -1 / project; + this.suspensionRelativeVelocity = projVel * inv; + this.clippedInvContactDotSuspension = inv; + } + + } else { + // Not in contact : position wheel in a nice (rest length) position + raycastResult.suspensionLength = this.suspensionRestLength; + this.suspensionRelativeVelocity = 0.0; + raycastResult.directionWorld.scale(-1, raycastResult.hitNormalWorld); + this.clippedInvContactDotSuspension = 1.0; + } +}; +},{"../collision/RaycastResult":10,"../math/Transform":29,"../math/Vec3":30,"../utils/Utils":53}],37:[function(_dereq_,module,exports){ +module.exports = Box; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var ConvexPolyhedron = _dereq_('./ConvexPolyhedron'); + +/** + * A 3d box shape. + * @class Box + * @constructor + * @param {Vec3} halfExtents + * @author schteppe + * @extends Shape + */ +function Box(halfExtents){ + Shape.call(this); + + this.type = Shape.types.BOX; + + /** + * @property halfExtents + * @type {Vec3} + */ + this.halfExtents = halfExtents; + + /** + * Used by the contact generator to make contacts with other convex polyhedra for example + * @property convexPolyhedronRepresentation + * @type {ConvexPolyhedron} + */ + this.convexPolyhedronRepresentation = null; + + this.updateConvexPolyhedronRepresentation(); + this.updateBoundingSphereRadius(); +} +Box.prototype = new Shape(); +Box.prototype.constructor = Box; + +/** + * Updates the local convex polyhedron representation used for some collisions. + * @method updateConvexPolyhedronRepresentation + */ +Box.prototype.updateConvexPolyhedronRepresentation = function(){ + var sx = this.halfExtents.x; + var sy = this.halfExtents.y; + var sz = this.halfExtents.z; + var V = Vec3; + + var vertices = [ + new V(-sx,-sy,-sz), + new V( sx,-sy,-sz), + new V( sx, sy,-sz), + new V(-sx, sy,-sz), + new V(-sx,-sy, sz), + new V( sx,-sy, sz), + new V( sx, sy, sz), + new V(-sx, sy, sz) + ]; + + var indices = [ + [3,2,1,0], // -z + [4,5,6,7], // +z + [5,4,0,1], // -y + [2,3,7,6], // +y + [0,4,7,3], // -x + [1,2,6,5], // +x + ]; + + var axes = [ + new V(0, 0, 1), + new V(0, 1, 0), + new V(1, 0, 0) + ]; + + var h = new ConvexPolyhedron(vertices, indices); + this.convexPolyhedronRepresentation = h; + h.material = this.material; +}; + +/** + * @method calculateLocalInertia + * @param {Number} mass + * @param {Vec3} target + * @return {Vec3} + */ +Box.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + Box.calculateInertia(this.halfExtents, mass, target); + return target; +}; + +Box.calculateInertia = function(halfExtents,mass,target){ + var e = halfExtents; + target.x = 1.0 / 12.0 * mass * ( 2*e.y*2*e.y + 2*e.z*2*e.z ); + target.y = 1.0 / 12.0 * mass * ( 2*e.x*2*e.x + 2*e.z*2*e.z ); + target.z = 1.0 / 12.0 * mass * ( 2*e.y*2*e.y + 2*e.x*2*e.x ); +}; + +/** + * Get the box 6 side normals + * @method getSideNormals + * @param {array} sixTargetVectors An array of 6 vectors, to store the resulting side normals in. + * @param {Quaternion} quat Orientation to apply to the normal vectors. If not provided, the vectors will be in respect to the local frame. + * @return {array} + */ +Box.prototype.getSideNormals = function(sixTargetVectors,quat){ + var sides = sixTargetVectors; + var ex = this.halfExtents; + sides[0].set( ex.x, 0, 0); + sides[1].set( 0, ex.y, 0); + sides[2].set( 0, 0, ex.z); + sides[3].set( -ex.x, 0, 0); + sides[4].set( 0, -ex.y, 0); + sides[5].set( 0, 0, -ex.z); + + if(quat!==undefined){ + for(var i=0; i!==sides.length; i++){ + quat.vmult(sides[i],sides[i]); + } + } + + return sides; +}; + +Box.prototype.volume = function(){ + return 8.0 * this.halfExtents.x * this.halfExtents.y * this.halfExtents.z; +}; + +Box.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = this.halfExtents.norm(); +}; + +var worldCornerTempPos = new Vec3(); +var worldCornerTempNeg = new Vec3(); +Box.prototype.forEachWorldCorner = function(pos,quat,callback){ + + var e = this.halfExtents; + var corners = [[ e.x, e.y, e.z], + [ -e.x, e.y, e.z], + [ -e.x, -e.y, e.z], + [ -e.x, -e.y, -e.z], + [ e.x, -e.y, -e.z], + [ e.x, e.y, -e.z], + [ -e.x, e.y, -e.z], + [ e.x, -e.y, e.z]]; + for(var i=0; i max.x){ + max.x = x; + } + if(y > max.y){ + max.y = y; + } + if(z > max.z){ + max.z = z; + } + + if(x < min.x){ + min.x = x; + } + if(y < min.y){ + min.y = y; + } + if(z < min.z){ + min.z = z; + } + } + + // Get each axis max + // min.set(Infinity,Infinity,Infinity); + // max.set(-Infinity,-Infinity,-Infinity); + // this.forEachWorldCorner(pos,quat,function(x,y,z){ + // if(x > max.x){ + // max.x = x; + // } + // if(y > max.y){ + // max.y = y; + // } + // if(z > max.z){ + // max.z = z; + // } + + // if(x < min.x){ + // min.x = x; + // } + // if(y < min.y){ + // min.y = y; + // } + // if(z < min.z){ + // min.z = z; + // } + // }); +}; + +},{"../math/Vec3":30,"./ConvexPolyhedron":38,"./Shape":43}],38:[function(_dereq_,module,exports){ +module.exports = ConvexPolyhedron; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Transform = _dereq_('../math/Transform'); + +/** + * A set of polygons describing a convex shape. + * @class ConvexPolyhedron + * @constructor + * @extends Shape + * @description The shape MUST be convex for the code to work properly. No polygons may be coplanar (contained + * in the same 3D plane), instead these should be merged into one polygon. + * + * @param {array} points An array of Vec3's + * @param {array} faces Array of integer arrays, describing which vertices that is included in each face. + * + * @author qiao / https://github.com/qiao (original author, see https://github.com/qiao/three.js/commit/85026f0c769e4000148a67d45a9e9b9c5108836f) + * @author schteppe / https://github.com/schteppe + * @see http://www.altdevblogaday.com/2011/05/13/contact-generation-between-3d-convex-meshes/ + * @see http://bullet.googlecode.com/svn/trunk/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp + * + * @todo Move the clipping functions to ContactGenerator? + * @todo Automatically merge coplanar polygons in constructor. + */ +function ConvexPolyhedron(points, faces, uniqueAxes) { + var that = this; + Shape.call(this); + this.type = Shape.types.CONVEXPOLYHEDRON; + + /** + * Array of Vec3 + * @property vertices + * @type {Array} + */ + this.vertices = points||[]; + + this.worldVertices = []; // World transformed version of .vertices + this.worldVerticesNeedsUpdate = true; + + /** + * Array of integer arrays, indicating which vertices each face consists of + * @property faces + * @type {Array} + */ + this.faces = faces||[]; + + /** + * Array of Vec3 + * @property faceNormals + * @type {Array} + */ + this.faceNormals = []; + this.computeNormals(); + + this.worldFaceNormalsNeedsUpdate = true; + this.worldFaceNormals = []; // World transformed version of .faceNormals + + /** + * Array of Vec3 + * @property uniqueEdges + * @type {Array} + */ + this.uniqueEdges = []; + + /** + * If given, these locally defined, normalized axes are the only ones being checked when doing separating axis check. + * @property {Array} uniqueAxes + */ + this.uniqueAxes = uniqueAxes ? uniqueAxes.slice() : null; + + this.computeEdges(); + this.updateBoundingSphereRadius(); +} +ConvexPolyhedron.prototype = new Shape(); +ConvexPolyhedron.prototype.constructor = ConvexPolyhedron; + +var computeEdges_tmpEdge = new Vec3(); +/** + * Computes uniqueEdges + * @method computeEdges + */ +ConvexPolyhedron.prototype.computeEdges = function(){ + var faces = this.faces; + var vertices = this.vertices; + var nv = vertices.length; + var edges = this.uniqueEdges; + + edges.length = 0; + + var edge = computeEdges_tmpEdge; + + for(var i=0; i !== faces.length; i++){ + var face = faces[i]; + var numVertices = face.length; + for(var j = 0; j !== numVertices; j++){ + var k = ( j+1 ) % numVertices; + vertices[face[j]].vsub(vertices[face[k]], edge); + edge.normalize(); + var found = false; + for(var p=0; p !== edges.length; p++){ + if (edges[p].almostEquals(edge) || edges[p].almostEquals(edge)){ + found = true; + break; + } + } + + if (!found){ + edges.push(edge.clone()); + } + } + } +}; + +/** + * Compute the normals of the faces. Will reuse existing Vec3 objects in the .faceNormals array if they exist. + * @method computeNormals + */ +ConvexPolyhedron.prototype.computeNormals = function(){ + this.faceNormals.length = this.faces.length; + + // Generate normals + for(var i=0; i dmax){ + dmax = d; + closestFaceB = face; + } + } + var worldVertsB1 = []; + var polyB = hullB.faces[closestFaceB]; + var numVertices = polyB.length; + for(var e0=0; e0=0){ + this.clipFaceAgainstHull(separatingNormal, + posA, + quatA, + worldVertsB1, + minDist, + maxDist, + result); + } +}; + +/** + * Find the separating axis between this hull and another + * @method findSeparatingAxis + * @param {ConvexPolyhedron} hullB + * @param {Vec3} posA + * @param {Quaternion} quatA + * @param {Vec3} posB + * @param {Quaternion} quatB + * @param {Vec3} target The target vector to save the axis in + * @return {bool} Returns false if a separation is found, else true + */ +var fsa_faceANormalWS3 = new Vec3(), + fsa_Worldnormal1 = new Vec3(), + fsa_deltaC = new Vec3(), + fsa_worldEdge0 = new Vec3(), + fsa_worldEdge1 = new Vec3(), + fsa_Cross = new Vec3(); +ConvexPolyhedron.prototype.findSeparatingAxis = function(hullB,posA,quatA,posB,quatB,target, faceListA, faceListB){ + var faceANormalWS3 = fsa_faceANormalWS3, + Worldnormal1 = fsa_Worldnormal1, + deltaC = fsa_deltaC, + worldEdge0 = fsa_worldEdge0, + worldEdge1 = fsa_worldEdge1, + Cross = fsa_Cross; + + var dmin = Number.MAX_VALUE; + var hullA = this; + var curPlaneTests=0; + + if(!hullA.uniqueAxes){ + + var numFacesA = faceListA ? faceListA.length : hullA.faces.length; + + // Test face normals from hullA + for(var i=0; i0.0){ + target.negate(target); + } + + return true; +}; + +var maxminA=[], maxminB=[]; + +/** + * Test separating axis against two hulls. Both hulls are projected onto the axis and the overlap size is returned if there is one. + * @method testSepAxis + * @param {Vec3} axis + * @param {ConvexPolyhedron} hullB + * @param {Vec3} posA + * @param {Quaternion} quatA + * @param {Vec3} posB + * @param {Quaternion} quatB + * @return {number} The overlap depth, or FALSE if no penetration. + */ +ConvexPolyhedron.prototype.testSepAxis = function(axis, hullB, posA, quatA, posB, quatB){ + var hullA=this; + ConvexPolyhedron.project(hullA, axis, posA, quatA, maxminA); + ConvexPolyhedron.project(hullB, axis, posB, quatB, maxminB); + var maxA = maxminA[0]; + var minA = maxminA[1]; + var maxB = maxminB[0]; + var minB = maxminB[1]; + if(maxA= 0, so output intersection + var newv = new Vec3(); + firstVertex.lerp(lastVertex, + n_dot_first / (n_dot_first - n_dot_last), + newv); + outVertices.push(newv); + } + } else { + if(n_dot_last<0){ + // Start >= 0, end < 0 so output intersection and end + var newv = new Vec3(); + firstVertex.lerp(lastVertex, + n_dot_first / (n_dot_first - n_dot_last), + newv); + outVertices.push(newv); + outVertices.push(lastVertex); + } + } + firstVertex = lastVertex; + n_dot_first = n_dot_last; + } + return outVertices; +}; + +// Updates .worldVertices and sets .worldVerticesNeedsUpdate to false. +ConvexPolyhedron.prototype.computeWorldVertices = function(position,quat){ + var N = this.vertices.length; + while(this.worldVertices.length < N){ + this.worldVertices.push( new Vec3() ); + } + + var verts = this.vertices, + worldVerts = this.worldVertices; + for(var i=0; i!==N; i++){ + quat.vmult( verts[i] , worldVerts[i] ); + position.vadd( worldVerts[i] , worldVerts[i] ); + } + + this.worldVerticesNeedsUpdate = false; +}; + +var computeLocalAABB_worldVert = new Vec3(); +ConvexPolyhedron.prototype.computeLocalAABB = function(aabbmin,aabbmax){ + var n = this.vertices.length, + vertices = this.vertices, + worldVert = computeLocalAABB_worldVert; + + aabbmin.set(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + aabbmax.set(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + + for(var i=0; i aabbmax.x){ + aabbmax.x = v.x; + } + if (v.y < aabbmin.y){ + aabbmin.y = v.y; + } else if(v.y > aabbmax.y){ + aabbmax.y = v.y; + } + if (v.z < aabbmin.z){ + aabbmin.z = v.z; + } else if(v.z > aabbmax.z){ + aabbmax.z = v.z; + } + } +}; + +/** + * Updates .worldVertices and sets .worldVerticesNeedsUpdate to false. + * @method computeWorldFaceNormals + * @param {Quaternion} quat + */ +ConvexPolyhedron.prototype.computeWorldFaceNormals = function(quat){ + var N = this.faceNormals.length; + while(this.worldFaceNormals.length < N){ + this.worldFaceNormals.push( new Vec3() ); + } + + var normals = this.faceNormals, + worldNormals = this.worldFaceNormals; + for(var i=0; i!==N; i++){ + quat.vmult( normals[i] , worldNormals[i] ); + } + + this.worldFaceNormalsNeedsUpdate = false; +}; + +/** + * @method updateBoundingSphereRadius + */ +ConvexPolyhedron.prototype.updateBoundingSphereRadius = function(){ + // Assume points are distributed with local (0,0,0) as center + var max2 = 0; + var verts = this.vertices; + for(var i=0, N=verts.length; i!==N; i++) { + var norm2 = verts[i].norm2(); + if(norm2 > max2){ + max2 = norm2; + } + } + this.boundingSphereRadius = Math.sqrt(max2); +}; + +var tempWorldVertex = new Vec3(); + +/** + * @method calculateWorldAABB + * @param {Vec3} pos + * @param {Quaternion} quat + * @param {Vec3} min + * @param {Vec3} max + */ +ConvexPolyhedron.prototype.calculateWorldAABB = function(pos,quat,min,max){ + var n = this.vertices.length, verts = this.vertices; + var minx,miny,minz,maxx,maxy,maxz; + for(var i=0; i maxx || maxx===undefined){ + maxx = v.x; + } + + if (v.y < miny || miny===undefined){ + miny = v.y; + } else if(v.y > maxy || maxy===undefined){ + maxy = v.y; + } + + if (v.z < minz || minz===undefined){ + minz = v.z; + } else if(v.z > maxz || maxz===undefined){ + maxz = v.z; + } + } + min.set(minx,miny,minz); + max.set(maxx,maxy,maxz); +}; + +/** + * Get approximate convex volume + * @method volume + * @return {Number} + */ +ConvexPolyhedron.prototype.volume = function(){ + return 4.0 * Math.PI * this.boundingSphereRadius / 3.0; +}; + +/** + * Get an average of all the vertices positions + * @method getAveragePointLocal + * @param {Vec3} target + * @return {Vec3} + */ +ConvexPolyhedron.prototype.getAveragePointLocal = function(target){ + target = target || new Vec3(); + var n = this.vertices.length, + verts = this.vertices; + for(var i=0; i0) || (r1>0 && r2<0)){ + return false; // Encountered some other sign. Exit. + } else { + } + } + + // If we got here, all dot products were of the same sign. + return positiveResult ? 1 : -1; +}; + +/** + * Get max and min dot product of a convex hull at position (pos,quat) projected onto an axis. Results are saved in the array maxmin. + * @static + * @method project + * @param {ConvexPolyhedron} hull + * @param {Vec3} axis + * @param {Vec3} pos + * @param {Quaternion} quat + * @param {array} result result[0] and result[1] will be set to maximum and minimum, respectively. + */ +var project_worldVertex = new Vec3(); +var project_localAxis = new Vec3(); +var project_localOrigin = new Vec3(); +ConvexPolyhedron.project = function(hull, axis, pos, quat, result){ + var n = hull.vertices.length, + worldVertex = project_worldVertex, + localAxis = project_localAxis, + max = 0, + min = 0, + localOrigin = project_localOrigin, + vs = hull.vertices; + + localOrigin.setZero(); + + // Transform the axis to local + Transform.vectorToLocalFrame(pos, quat, axis, localAxis); + Transform.pointToLocalFrame(pos, quat, localOrigin, localOrigin); + var add = localOrigin.dot(localAxis); + + min = max = vs[0].dot(localAxis); + + for(var i = 1; i < n; i++){ + var val = vs[i].dot(localAxis); + + if(val > max){ + max = val; + } + + if(val < min){ + min = val; + } + } + + min -= add; + max -= add; + + if(min > max){ + // Inconsistent - swap + var temp = min; + min = max; + max = temp; + } + // Output + result[0] = max; + result[1] = min; +}; + +},{"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"./Shape":43}],39:[function(_dereq_,module,exports){ +module.exports = Cylinder; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var ConvexPolyhedron = _dereq_('./ConvexPolyhedron'); + +/** + * @class Cylinder + * @constructor + * @extends ConvexPolyhedron + * @author schteppe / https://github.com/schteppe + * @param {Number} radiusTop + * @param {Number} radiusBottom + * @param {Number} height + * @param {Number} numSegments The number of segments to build the cylinder out of + */ +function Cylinder( radiusTop, radiusBottom, height , numSegments ) { + var N = numSegments, + verts = [], + axes = [], + faces = [], + bottomface = [], + topface = [], + cos = Math.cos, + sin = Math.sin; + + // First bottom point + verts.push(new Vec3(radiusBottom*cos(0), + radiusBottom*sin(0), + -height*0.5)); + bottomface.push(0); + + // First top point + verts.push(new Vec3(radiusTop*cos(0), + radiusTop*sin(0), + height*0.5)); + topface.push(1); + + for(var i=0; i { convex: ..., offset: ... } + // for example: + // _cachedPillars["0_2_1"] + this._cachedPillars = {}; +} +Heightfield.prototype = new Shape(); + +/** + * Call whenever you change the data array. + * @method update + */ +Heightfield.prototype.update = function(){ + this._cachedPillars = {}; +}; + +/** + * Update the .minValue property + * @method updateMinValue + */ +Heightfield.prototype.updateMinValue = function(){ + var data = this.data; + var minValue = data[0][0]; + for(var i=0; i !== data.length; i++){ + for(var j=0; j !== data[i].length; j++){ + var v = data[i][j]; + if(v < minValue){ + minValue = v; + } + } + } + this.minValue = minValue; +}; + +/** + * Update the .maxValue property + * @method updateMaxValue + */ +Heightfield.prototype.updateMaxValue = function(){ + var data = this.data; + var maxValue = data[0][0]; + for(var i=0; i !== data.length; i++){ + for(var j=0; j !== data[i].length; j++){ + var v = data[i][j]; + if(v > maxValue){ + maxValue = v; + } + } + } + this.maxValue = maxValue; +}; + +/** + * Set the height value at an index. Don't forget to update maxValue and minValue after you're done. + * @method setHeightValueAtIndex + * @param {integer} xi + * @param {integer} yi + * @param {number} value + */ +Heightfield.prototype.setHeightValueAtIndex = function(xi, yi, value){ + var data = this.data; + data[xi][yi] = value; + + // Invalidate cache + this.clearCachedConvexTrianglePillar(xi, yi, false); + if(xi > 0){ + this.clearCachedConvexTrianglePillar(xi - 1, yi, true); + this.clearCachedConvexTrianglePillar(xi - 1, yi, false); + } + if(yi > 0){ + this.clearCachedConvexTrianglePillar(xi, yi - 1, true); + this.clearCachedConvexTrianglePillar(xi, yi - 1, false); + } + if(yi > 0 && xi > 0){ + this.clearCachedConvexTrianglePillar(xi - 1, yi - 1, true); + } +}; + +/** + * Get max/min in a rectangle in the matrix data + * @method getRectMinMax + * @param {integer} iMinX + * @param {integer} iMinY + * @param {integer} iMaxX + * @param {integer} iMaxY + * @param {array} [result] An array to store the results in. + * @return {array} The result array, if it was passed in. Minimum will be at position 0 and max at 1. + */ +Heightfield.prototype.getRectMinMax = function (iMinX, iMinY, iMaxX, iMaxY, result) { + result = result || []; + + // Get max and min of the data + var data = this.data, + max = this.minValue; // Set first value + for(var i = iMinX; i <= iMaxX; i++){ + for(var j = iMinY; j <= iMaxY; j++){ + var height = data[i][j]; + if(height > max){ + max = height; + } + } + } + + result[0] = this.minValue; + result[1] = max; +}; + +/** + * Get the index of a local position on the heightfield. The indexes indicate the rectangles, so if your terrain is made of N x N height data points, you will have rectangle indexes ranging from 0 to N-1. + * @method getIndexOfPosition + * @param {number} x + * @param {number} y + * @param {array} result Two-element array + * @param {boolean} clamp If the position should be clamped to the heightfield edge. + * @return {boolean} + */ +Heightfield.prototype.getIndexOfPosition = function (x, y, result, clamp) { + + // Get the index of the data points to test against + var w = this.elementSize; + var data = this.data; + var xi = Math.floor(x / w); + var yi = Math.floor(y / w); + + result[0] = xi; + result[1] = yi; + + if(clamp){ + // Clamp index to edges + if(xi < 0){ xi = 0; } + if(yi < 0){ yi = 0; } + if(xi >= data.length - 1){ xi = data.length - 1; } + if(yi >= data[0].length - 1){ yi = data[0].length - 1; } + } + + // Bail out if we are out of the terrain + if(xi < 0 || yi < 0 || xi >= data.length-1 || yi >= data[0].length-1){ + return false; + } + + return true; +}; + +Heightfield.prototype.getHeightAt = function(x, y, edgeClamp){ + var idx = []; + this.getIndexOfPosition(x, y, idx, edgeClamp); + + // TODO: get upper or lower triangle, then use barycentric interpolation to get the height in the triangle. + var minmax = []; + this.getRectMinMax(idx[0], idx[1] + 1, idx[0], idx[1] + 1, minmax); + + return (minmax[0] + minmax[1]) / 2; // average +}; + +Heightfield.prototype.getCacheConvexTrianglePillarKey = function(xi, yi, getUpperTriangle){ + return xi + '_' + yi + '_' + (getUpperTriangle ? 1 : 0); +}; + +Heightfield.prototype.getCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle){ + return this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)]; +}; + +Heightfield.prototype.setCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle, convex, offset){ + this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)] = { + convex: convex, + offset: offset + }; +}; + +Heightfield.prototype.clearCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle){ + delete this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)]; +}; + +/** + * Get a triangle in the terrain in the form of a triangular convex shape. + * @method getConvexTrianglePillar + * @param {integer} i + * @param {integer} j + * @param {boolean} getUpperTriangle + */ +Heightfield.prototype.getConvexTrianglePillar = function(xi, yi, getUpperTriangle){ + var result = this.pillarConvex; + var offsetResult = this.pillarOffset; + + if(this.cacheEnabled){ + var data = this.getCachedConvexTrianglePillar(xi, yi, getUpperTriangle); + if(data){ + this.pillarConvex = data.convex; + this.pillarOffset = data.offset; + return; + } + + result = new ConvexPolyhedron(); + offsetResult = new Vec3(); + + this.pillarConvex = result; + this.pillarOffset = offsetResult; + } + + var data = this.data; + var elementSize = this.elementSize; + var faces = result.faces; + + // Reuse verts if possible + result.vertices.length = 6; + for (var i = 0; i < 6; i++) { + if(!result.vertices[i]){ + result.vertices[i] = new Vec3(); + } + } + + // Reuse faces if possible + faces.length = 5; + for (var i = 0; i < 5; i++) { + if(!faces[i]){ + faces[i] = []; + } + } + + var verts = result.vertices; + + var h = (Math.min( + data[xi][yi], + data[xi+1][yi], + data[xi][yi+1], + data[xi+1][yi+1] + ) - this.minValue ) / 2 + this.minValue; + + if (!getUpperTriangle) { + + // Center of the triangle pillar - all polygons are given relative to this one + offsetResult.set( + (xi + 0.25) * elementSize, // sort of center of a triangle + (yi + 0.25) * elementSize, + h // vertical center + ); + + // Top triangle verts + verts[0].set( + -0.25 * elementSize, + -0.25 * elementSize, + data[xi][yi] - h + ); + verts[1].set( + 0.75 * elementSize, + -0.25 * elementSize, + data[xi + 1][yi] - h + ); + verts[2].set( + -0.25 * elementSize, + 0.75 * elementSize, + data[xi][yi + 1] - h + ); + + // bottom triangle verts + verts[3].set( + -0.25 * elementSize, + -0.25 * elementSize, + -h-1 + ); + verts[4].set( + 0.75 * elementSize, + -0.25 * elementSize, + -h-1 + ); + verts[5].set( + -0.25 * elementSize, + 0.75 * elementSize, + -h-1 + ); + + // top triangle + faces[0][0] = 0; + faces[0][1] = 1; + faces[0][2] = 2; + + // bottom triangle + faces[1][0] = 5; + faces[1][1] = 4; + faces[1][2] = 3; + + // -x facing quad + faces[2][0] = 0; + faces[2][1] = 2; + faces[2][2] = 5; + faces[2][3] = 3; + + // -y facing quad + faces[3][0] = 1; + faces[3][1] = 0; + faces[3][2] = 3; + faces[3][3] = 4; + + // +xy facing quad + faces[4][0] = 4; + faces[4][1] = 5; + faces[4][2] = 2; + faces[4][3] = 1; + + + } else { + + // Center of the triangle pillar - all polygons are given relative to this one + offsetResult.set( + (xi + 0.75) * elementSize, // sort of center of a triangle + (yi + 0.75) * elementSize, + h // vertical center + ); + + // Top triangle verts + verts[0].set( + 0.25 * elementSize, + 0.25 * elementSize, + data[xi + 1][yi + 1] - h + ); + verts[1].set( + -0.75 * elementSize, + 0.25 * elementSize, + data[xi][yi + 1] - h + ); + verts[2].set( + 0.25 * elementSize, + -0.75 * elementSize, + data[xi + 1][yi] - h + ); + + // bottom triangle verts + verts[3].set( + 0.25 * elementSize, + 0.25 * elementSize, + - h-1 + ); + verts[4].set( + -0.75 * elementSize, + 0.25 * elementSize, + - h-1 + ); + verts[5].set( + 0.25 * elementSize, + -0.75 * elementSize, + - h-1 + ); + + // Top triangle + faces[0][0] = 0; + faces[0][1] = 1; + faces[0][2] = 2; + + // bottom triangle + faces[1][0] = 5; + faces[1][1] = 4; + faces[1][2] = 3; + + // +x facing quad + faces[2][0] = 2; + faces[2][1] = 5; + faces[2][2] = 3; + faces[2][3] = 0; + + // +y facing quad + faces[3][0] = 3; + faces[3][1] = 4; + faces[3][2] = 1; + faces[3][3] = 0; + + // -xy facing quad + faces[4][0] = 1; + faces[4][1] = 4; + faces[4][2] = 5; + faces[4][3] = 2; + } + + result.computeNormals(); + result.computeEdges(); + result.updateBoundingSphereRadius(); + + this.setCachedConvexTrianglePillar(xi, yi, getUpperTriangle, result, offsetResult); +}; + +Heightfield.prototype.calculateLocalInertia = function(mass, target){ + target = target || new Vec3(); + target.set(0, 0, 0); + return target; +}; + +Heightfield.prototype.volume = function(){ + return Number.MAX_VALUE; // The terrain is infinite +}; + +Heightfield.prototype.calculateWorldAABB = function(pos, quat, min, max){ + // TODO: do it properly + min.set(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + max.set(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); +}; + +Heightfield.prototype.updateBoundingSphereRadius = function(){ + // Use the bounding box of the min/max values + var data = this.data, + s = this.elementSize; + this.boundingSphereRadius = new Vec3(data.length * s, data[0].length * s, Math.max(Math.abs(this.maxValue), Math.abs(this.minValue))).norm(); +}; + +},{"../math/Vec3":30,"../utils/Utils":53,"./ConvexPolyhedron":38,"./Shape":43}],41:[function(_dereq_,module,exports){ +module.exports = Particle; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * Particle shape. + * @class Particle + * @constructor + * @author schteppe + * @extends Shape + */ +function Particle(){ + Shape.call(this); + + this.type = Shape.types.PARTICLE; +} +Particle.prototype = new Shape(); +Particle.prototype.constructor = Particle; + +/** + * @method calculateLocalInertia + * @param {Number} mass + * @param {Vec3} target + * @return {Vec3} + */ +Particle.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + target.set(0, 0, 0); + return target; +}; + +Particle.prototype.volume = function(){ + return 0; +}; + +Particle.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = 0; +}; + +Particle.prototype.calculateWorldAABB = function(pos,quat,min,max){ + // Get each axis max + min.copy(pos); + max.copy(pos); +}; + +},{"../math/Vec3":30,"./Shape":43}],42:[function(_dereq_,module,exports){ +module.exports = Plane; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * A plane, facing in the Z direction. The plane has its surface at z=0 and everything below z=0 is assumed to be solid plane. To make the plane face in some other direction than z, you must put it inside a RigidBody and rotate that body. See the demos. + * @class Plane + * @constructor + * @extends Shape + * @author schteppe + */ +function Plane(){ + Shape.call(this); + this.type = Shape.types.PLANE; + + // World oriented normal + this.worldNormal = new Vec3(); + this.worldNormalNeedsUpdate = true; + + this.boundingSphereRadius = Number.MAX_VALUE; +} +Plane.prototype = new Shape(); +Plane.prototype.constructor = Plane; + +Plane.prototype.computeWorldNormal = function(quat){ + var n = this.worldNormal; + n.set(0,0,1); + quat.vmult(n,n); + this.worldNormalNeedsUpdate = false; +}; + +Plane.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + return target; +}; + +Plane.prototype.volume = function(){ + return Number.MAX_VALUE; // The plane is infinite... +}; + +var tempNormal = new Vec3(); +Plane.prototype.calculateWorldAABB = function(pos, quat, min, max){ + // The plane AABB is infinite, except if the normal is pointing along any axis + tempNormal.set(0,0,1); // Default plane normal is z + quat.vmult(tempNormal,tempNormal); + var maxVal = Number.MAX_VALUE; + min.set(-maxVal, -maxVal, -maxVal); + max.set(maxVal, maxVal, maxVal); + + if(tempNormal.x === 1){ max.x = pos.x; } + if(tempNormal.y === 1){ max.y = pos.y; } + if(tempNormal.z === 1){ max.z = pos.z; } + + if(tempNormal.x === -1){ min.x = pos.x; } + if(tempNormal.y === -1){ min.y = pos.y; } + if(tempNormal.z === -1){ min.z = pos.z; } +}; + +Plane.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = Number.MAX_VALUE; +}; +},{"../math/Vec3":30,"./Shape":43}],43:[function(_dereq_,module,exports){ +module.exports = Shape; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Material = _dereq_('../material/Material'); + +/** + * Base class for shapes + * @class Shape + * @constructor + * @author schteppe + * @todo Should have a mechanism for caching bounding sphere radius instead of calculating it each time + */ +function Shape(){ + + /** + * Identifyer of the Shape. + * @property {number} id + */ + this.id = Shape.idCounter++; + + /** + * The type of this shape. Must be set to an int > 0 by subclasses. + * @property type + * @type {Number} + * @see Shape.types + */ + this.type = 0; + + /** + * The local bounding sphere radius of this shape. + * @property {Number} boundingSphereRadius + */ + this.boundingSphereRadius = 0; + + /** + * Whether to produce contact forces when in contact with other bodies. Note that contacts will be generated, but they will be disabled. + * @property {boolean} collisionResponse + */ + this.collisionResponse = true; + + /** + * @property {Material} material + */ + this.material = null; +} +Shape.prototype.constructor = Shape; + +/** + * Computes the bounding sphere radius. The result is stored in the property .boundingSphereRadius + * @method updateBoundingSphereRadius + * @return {Number} + */ +Shape.prototype.updateBoundingSphereRadius = function(){ + throw "computeBoundingSphereRadius() not implemented for shape type "+this.type; +}; + +/** + * Get the volume of this shape + * @method volume + * @return {Number} + */ +Shape.prototype.volume = function(){ + throw "volume() not implemented for shape type "+this.type; +}; + +/** + * Calculates the inertia in the local frame for this shape. + * @method calculateLocalInertia + * @return {Vec3} + * @see http://en.wikipedia.org/wiki/List_of_moments_of_inertia + */ +Shape.prototype.calculateLocalInertia = function(mass,target){ + throw "calculateLocalInertia() not implemented for shape type "+this.type; +}; + +Shape.idCounter = 0; + +/** + * The available shape types. + * @static + * @property types + * @type {Object} + */ +Shape.types = { + SPHERE:1, + PLANE:2, + BOX:4, + COMPOUND:8, + CONVEXPOLYHEDRON:16, + HEIGHTFIELD:32, + PARTICLE:64, + CYLINDER:128, + TRIMESH:256 +}; + + +},{"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"./Shape":43}],44:[function(_dereq_,module,exports){ +module.exports = Sphere; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * Spherical shape + * @class Sphere + * @constructor + * @extends Shape + * @param {Number} radius The radius of the sphere, a non-negative number. + * @author schteppe / http://github.com/schteppe + */ +function Sphere(radius){ + Shape.call(this); + + /** + * @property {Number} radius + */ + this.radius = radius!==undefined ? Number(radius) : 1.0; + this.type = Shape.types.SPHERE; + + if(this.radius < 0){ + throw new Error('The sphere radius cannot be negative.'); + } + + this.updateBoundingSphereRadius(); +} +Sphere.prototype = new Shape(); +Sphere.prototype.constructor = Sphere; + +Sphere.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + var I = 2.0*mass*this.radius*this.radius/5.0; + target.x = I; + target.y = I; + target.z = I; + return target; +}; + +Sphere.prototype.volume = function(){ + return 4.0 * Math.PI * this.radius / 3.0; +}; + +Sphere.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = this.radius; +}; + +Sphere.prototype.calculateWorldAABB = function(pos,quat,min,max){ + var r = this.radius; + var axes = ['x','y','z']; + for(var i=0; i u.x){ + u.x = v.x; + } + + if(v.y < l.y){ + l.y = v.y; + } else if(v.y > u.y){ + u.y = v.y; + } + + if(v.z < l.z){ + l.z = v.z; + } else if(v.z > u.z){ + u.z = v.z; + } + } +}; + + +/** + * Update the .aabb property + * @method updateAABB + */ +Trimesh.prototype.updateAABB = function(){ + this.computeLocalAABB(this.aabb); +}; + +/** + * Will update the .boundingSphereRadius property + * @method updateBoundingSphereRadius + */ +Trimesh.prototype.updateBoundingSphereRadius = function(){ + // Assume points are distributed with local (0,0,0) as center + var max2 = 0; + var vertices = this.vertices; + var v = new Vec3(); + for(var i=0, N=vertices.length / 3; i !== N; i++) { + this.getVertex(i, v); + var norm2 = v.norm2(); + if(norm2 > max2){ + max2 = norm2; + } + } + this.boundingSphereRadius = Math.sqrt(max2); +}; + +var tempWorldVertex = new Vec3(); +var calculateWorldAABB_frame = new Transform(); +var calculateWorldAABB_aabb = new AABB(); + +/** + * @method calculateWorldAABB + * @param {Vec3} pos + * @param {Quaternion} quat + * @param {Vec3} min + * @param {Vec3} max + */ +Trimesh.prototype.calculateWorldAABB = function(pos,quat,min,max){ + /* + var n = this.vertices.length / 3, + verts = this.vertices; + var minx,miny,minz,maxx,maxy,maxz; + + var v = tempWorldVertex; + for(var i=0; i maxx || maxx===undefined){ + maxx = v.x; + } + + if (v.y < miny || miny===undefined){ + miny = v.y; + } else if(v.y > maxy || maxy===undefined){ + maxy = v.y; + } + + if (v.z < minz || minz===undefined){ + minz = v.z; + } else if(v.z > maxz || maxz===undefined){ + maxz = v.z; + } + } + min.set(minx,miny,minz); + max.set(maxx,maxy,maxz); + */ + + // Faster approximation using local AABB + var frame = calculateWorldAABB_frame; + var result = calculateWorldAABB_aabb; + frame.position = pos; + frame.quaternion = quat; + this.aabb.toWorldFrame(frame, result); + min.copy(result.lowerBound); + max.copy(result.upperBound); +}; + +/** + * Get approximate volume + * @method volume + * @return {Number} + */ +Trimesh.prototype.volume = function(){ + return 4.0 * Math.PI * this.boundingSphereRadius / 3.0; +}; + +/** + * Create a Trimesh instance, shaped as a torus. + * @static + * @method createTorus + * @param {number} [radius=1] + * @param {number} [tube=0.5] + * @param {number} [radialSegments=8] + * @param {number} [tubularSegments=6] + * @param {number} [arc=6.283185307179586] + * @return {Trimesh} A torus + */ +Trimesh.createTorus = function (radius, tube, radialSegments, tubularSegments, arc) { + radius = radius || 1; + tube = tube || 0.5; + radialSegments = radialSegments || 8; + tubularSegments = tubularSegments || 6; + arc = arc || Math.PI * 2; + + var vertices = []; + var indices = []; + + for ( var j = 0; j <= radialSegments; j ++ ) { + for ( var i = 0; i <= tubularSegments; i ++ ) { + var u = i / tubularSegments * arc; + var v = j / radialSegments * Math.PI * 2; + + var x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); + var y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); + var z = tube * Math.sin( v ); + + vertices.push( x, y, z ); + } + } + + for ( var j = 1; j <= radialSegments; j ++ ) { + for ( var i = 1; i <= tubularSegments; i ++ ) { + var a = ( tubularSegments + 1 ) * j + i - 1; + var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; + var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; + var d = ( tubularSegments + 1 ) * j + i; + + indices.push(a, b, d); + indices.push(b, c, d); + } + } + + return new Trimesh(vertices, indices); +}; + +},{"../collision/AABB":3,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../utils/Octree":50,"./Shape":43}],46:[function(_dereq_,module,exports){ +module.exports = GSSolver; + +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Solver = _dereq_('./Solver'); + +/** + * Constraint equation Gauss-Seidel solver. + * @class GSSolver + * @constructor + * @todo The spook parameters should be specified for each constraint, not globally. + * @author schteppe / https://github.com/schteppe + * @see https://www8.cs.umu.se/kurser/5DV058/VT09/lectures/spooknotes.pdf + * @extends Solver + */ +function GSSolver(){ + Solver.call(this); + + /** + * The number of solver iterations determines quality of the constraints in the world. The more iterations, the more correct simulation. More iterations need more computations though. If you have a large gravity force in your world, you will need more iterations. + * @property iterations + * @type {Number} + * @todo write more about solver and iterations in the wiki + */ + this.iterations = 10; + + /** + * When tolerance is reached, the system is assumed to be converged. + * @property tolerance + * @type {Number} + */ + this.tolerance = 1e-7; +} +GSSolver.prototype = new Solver(); + +var GSSolver_solve_lambda = []; // Just temporary number holders that we want to reuse each solve. +var GSSolver_solve_invCs = []; +var GSSolver_solve_Bs = []; +GSSolver.prototype.solve = function(dt,world){ + var iter = 0, + maxIter = this.iterations, + tolSquared = this.tolerance*this.tolerance, + equations = this.equations, + Neq = equations.length, + bodies = world.bodies, + Nbodies = bodies.length, + h = dt, + q, B, invC, deltalambda, deltalambdaTot, GWlambda, lambdaj; + + // Update solve mass + if(Neq !== 0){ + for(var i=0; i!==Nbodies; i++){ + bodies[i].updateSolveMassProperties(); + } + } + + // Things that does not change during iteration can be computed once + var invCs = GSSolver_solve_invCs, + Bs = GSSolver_solve_Bs, + lambda = GSSolver_solve_lambda; + invCs.length = Neq; + Bs.length = Neq; + lambda.length = Neq; + for(var i=0; i!==Neq; i++){ + var c = equations[i]; + lambda[i] = 0.0; + Bs[i] = c.computeB(h); + invCs[i] = 1.0 / c.computeC(); + } + + if(Neq !== 0){ + + // Reset vlambda + for(var i=0; i!==Nbodies; i++){ + var b=bodies[i], + vlambda=b.vlambda, + wlambda=b.wlambda; + vlambda.set(0,0,0); + if(wlambda){ + wlambda.set(0,0,0); + } + } + + // Iterate over equations + for(iter=0; iter!==maxIter; iter++){ + + // Accumulate the total error for each iteration. + deltalambdaTot = 0.0; + + for(var j=0; j!==Neq; j++){ + + var c = equations[j]; + + // Compute iteration + B = Bs[j]; + invC = invCs[j]; + lambdaj = lambda[j]; + GWlambda = c.computeGWlambda(); + deltalambda = invC * ( B - GWlambda - c.eps * lambdaj ); + + // Clamp if we are not within the min/max interval + if(lambdaj + deltalambda < c.minForce){ + deltalambda = c.minForce - lambdaj; + } else if(lambdaj + deltalambda > c.maxForce){ + deltalambda = c.maxForce - lambdaj; + } + lambda[j] += deltalambda; + + deltalambdaTot += deltalambda > 0.0 ? deltalambda : -deltalambda; // abs(deltalambda) + + c.addToWlambda(deltalambda); + } + + // If the total error is small enough - stop iterate + if(deltalambdaTot*deltalambdaTot < tolSquared){ + break; + } + } + + // Add result to velocity + for(var i=0; i!==Nbodies; i++){ + var b=bodies[i], + v=b.velocity, + w=b.angularVelocity; + v.vadd(b.vlambda, v); + if(w){ + w.vadd(b.wlambda, w); + } + } + } + + return iter; +}; + +},{"../math/Quaternion":28,"../math/Vec3":30,"./Solver":47}],47:[function(_dereq_,module,exports){ +module.exports = Solver; + +/** + * Constraint equation solver base class. + * @class Solver + * @constructor + * @author schteppe / https://github.com/schteppe + */ +function Solver(){ + /** + * All equations to be solved + * @property {Array} equations + */ + this.equations = []; +} + +/** + * Should be implemented in subclasses! + * @method solve + * @param {Number} dt + * @param {World} world + */ +Solver.prototype.solve = function(dt,world){ + // Should return the number of iterations done! + return 0; +}; + +/** + * Add an equation + * @method addEquation + * @param {Equation} eq + */ +Solver.prototype.addEquation = function(eq){ + if (eq.enabled) { + this.equations.push(eq); + } +}; + +/** + * Remove an equation + * @method removeEquation + * @param {Equation} eq + */ +Solver.prototype.removeEquation = function(eq){ + var eqs = this.equations; + var i = eqs.indexOf(eq); + if(i !== -1){ + eqs.splice(i,1); + } +}; + +/** + * Add all equations + * @method removeAllEquations + */ +Solver.prototype.removeAllEquations = function(){ + this.equations.length = 0; +}; + + +},{}],48:[function(_dereq_,module,exports){ +module.exports = SplitSolver; + +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Solver = _dereq_('./Solver'); +var Body = _dereq_('../objects/Body'); + +/** + * Splits the equations into islands and solves them independently. Can improve performance. + * @class SplitSolver + * @constructor + * @extends Solver + * @param {Solver} subsolver + */ +function SplitSolver(subsolver){ + Solver.call(this); + this.iterations = 10; + this.tolerance = 1e-7; + this.subsolver = subsolver; + this.nodes = []; + this.nodePool = []; + + // Create needed nodes, reuse if possible + while(this.nodePool.length < 128){ + this.nodePool.push(this.createNode()); + } +} +SplitSolver.prototype = new Solver(); + +// Returns the number of subsystems +var SplitSolver_solve_nodes = []; // All allocated node objects +var SplitSolver_solve_nodePool = []; // All allocated node objects +var SplitSolver_solve_eqs = []; // Temp array +var SplitSolver_solve_bds = []; // Temp array +var SplitSolver_solve_dummyWorld = {bodies:[]}; // Temp object + +var STATIC = Body.STATIC; +function getUnvisitedNode(nodes){ + var Nnodes = nodes.length; + for(var i=0; i!==Nnodes; i++){ + var node = nodes[i]; + if(!node.visited && !(node.body.type & STATIC)){ + return node; + } + } + return false; +} + +var queue = []; +function bfs(root,visitFunc,bds,eqs){ + queue.push(root); + root.visited = true; + visitFunc(root,bds,eqs); + while(queue.length) { + var node = queue.pop(); + // Loop over unvisited child nodes + var child; + while((child = getUnvisitedNode(node.children))) { + child.visited = true; + visitFunc(child,bds,eqs); + queue.push(child); + } + } +} + +function visitFunc(node,bds,eqs){ + bds.push(node.body); + var Neqs = node.eqs.length; + for(var i=0; i!==Neqs; i++){ + var eq = node.eqs[i]; + if(eqs.indexOf(eq) === -1){ + eqs.push(eq); + } + } +} + +SplitSolver.prototype.createNode = function(){ + return { body:null, children:[], eqs:[], visited:false }; +}; + +/** + * Solve the subsystems + * @method solve + * @param {Number} dt + * @param {World} world + */ +SplitSolver.prototype.solve = function(dt,world){ + var nodes=SplitSolver_solve_nodes, + nodePool=this.nodePool, + bodies=world.bodies, + equations=this.equations, + Neq=equations.length, + Nbodies=bodies.length, + subsolver=this.subsolver; + + // Create needed nodes, reuse if possible + while(nodePool.length < Nbodies){ + nodePool.push(this.createNode()); + } + nodes.length = Nbodies; + for (var i = 0; i < Nbodies; i++) { + nodes[i] = nodePool[i]; + } + + // Reset node values + for(var i=0; i!==Nbodies; i++){ + var node = nodes[i]; + node.body = bodies[i]; + node.children.length = 0; + node.eqs.length = 0; + node.visited = false; + } + for(var k=0; k!==Neq; k++){ + var eq=equations[k], + i=bodies.indexOf(eq.bi), + j=bodies.indexOf(eq.bj), + ni=nodes[i], + nj=nodes[j]; + ni.children.push(nj); + ni.eqs.push(eq); + nj.children.push(ni); + nj.eqs.push(eq); + } + + var child, n=0, eqs=SplitSolver_solve_eqs; + + subsolver.tolerance = this.tolerance; + subsolver.iterations = this.iterations; + + var dummyWorld = SplitSolver_solve_dummyWorld; + while((child = getUnvisitedNode(nodes))){ + eqs.length = 0; + dummyWorld.bodies.length = 0; + bfs(child, visitFunc, dummyWorld.bodies, eqs); + + var Neqs = eqs.length; + + eqs = eqs.sort(sortById); + + for(var i=0; i!==Neqs; i++){ + subsolver.addEquation(eqs[i]); + } + + var iter = subsolver.solve(dt,dummyWorld); + subsolver.removeAllEquations(); + n++; + } + + return n; +}; + +function sortById(a, b){ + return b.id - a.id; +} +},{"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"./Solver":47}],49:[function(_dereq_,module,exports){ +/** + * Base class for objects that dispatches events. + * @class EventTarget + * @constructor + */ +var EventTarget = function () { + +}; + +module.exports = EventTarget; + +EventTarget.prototype = { + constructor: EventTarget, + + /** + * Add an event listener + * @method addEventListener + * @param {String} type + * @param {Function} listener + * @return {EventTarget} The self object, for chainability. + */ + addEventListener: function ( type, listener ) { + if ( this._listeners === undefined ){ this._listeners = {}; } + var listeners = this._listeners; + if ( listeners[ type ] === undefined ) { + listeners[ type ] = []; + } + if ( listeners[ type ].indexOf( listener ) === - 1 ) { + listeners[ type ].push( listener ); + } + return this; + }, + + /** + * Check if an event listener is added + * @method hasEventListener + * @param {String} type + * @param {Function} listener + * @return {Boolean} + */ + hasEventListener: function ( type, listener ) { + if ( this._listeners === undefined ){ return false; } + var listeners = this._listeners; + if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) { + return true; + } + return false; + }, + + /** + * Remove an event listener + * @method removeEventListener + * @param {String} type + * @param {Function} listener + * @return {EventTarget} The self object, for chainability. + */ + removeEventListener: function ( type, listener ) { + if ( this._listeners === undefined ){ return this; } + var listeners = this._listeners; + if ( listeners[type] === undefined ){ return this; } + var index = listeners[ type ].indexOf( listener ); + if ( index !== - 1 ) { + listeners[ type ].splice( index, 1 ); + } + return this; + }, + + /** + * Emit an event. + * @method dispatchEvent + * @param {Object} event + * @param {String} event.type + * @return {EventTarget} The self object, for chainability. + */ + dispatchEvent: function ( event ) { + if ( this._listeners === undefined ){ return this; } + var listeners = this._listeners; + var listenerArray = listeners[ event.type ]; + if ( listenerArray !== undefined ) { + event.target = this; + for ( var i = 0, l = listenerArray.length; i < l; i ++ ) { + listenerArray[ i ].call( this, event ); + } + } + return this; + } +}; + +},{}],50:[function(_dereq_,module,exports){ +var AABB = _dereq_('../collision/AABB'); +var Vec3 = _dereq_('../math/Vec3'); + +module.exports = Octree; + +/** + * @class OctreeNode + * @param {object} [options] + * @param {Octree} [options.root] + * @param {AABB} [options.aabb] + */ +function OctreeNode(options){ + options = options || {}; + + /** + * The root node + * @property {OctreeNode} root + */ + this.root = options.root || null; + + /** + * Boundary of this node + * @property {AABB} aabb + */ + this.aabb = options.aabb ? options.aabb.clone() : new AABB(); + + /** + * Contained data at the current node level. + * @property {Array} data + */ + this.data = []; + + /** + * Children to this node + * @property {Array} children + */ + this.children = []; +} + +/** + * @class Octree + * @param {AABB} aabb The total AABB of the tree + * @param {object} [options] + * @param {number} [options.maxDepth=8] + * @extends OctreeNode + */ +function Octree(aabb, options){ + options = options || {}; + options.root = null; + options.aabb = aabb; + OctreeNode.call(this, options); + + /** + * Maximum subdivision depth + * @property {number} maxDepth + */ + this.maxDepth = typeof(options.maxDepth) !== 'undefined' ? options.maxDepth : 8; +} +Octree.prototype = new OctreeNode(); + +OctreeNode.prototype.reset = function(aabb, options){ + this.children.length = this.data.length = 0; +}; + +/** + * Insert data into this node + * @method insert + * @param {AABB} aabb + * @param {object} elementData + * @return {boolean} True if successful, otherwise false + */ +OctreeNode.prototype.insert = function(aabb, elementData, level){ + var nodeData = this.data; + level = level || 0; + + // Ignore objects that do not belong in this node + if (!this.aabb.contains(aabb)){ + return false; // object cannot be added + } + + var children = this.children; + + if(level < (this.maxDepth || this.root.maxDepth)){ + // Subdivide if there are no children yet + var subdivided = false; + if (!children.length){ + this.subdivide(); + subdivided = true; + } + + // add to whichever node will accept it + for (var i = 0; i !== 8; i++) { + if (children[i].insert(aabb, elementData, level + 1)){ + return true; + } + } + + if(subdivided){ + // No children accepted! Might as well just remove em since they contain none + children.length = 0; + } + } + + // Too deep, or children didnt want it. add it in current node + nodeData.push(elementData); + + return true; +}; + +var halfDiagonal = new Vec3(); + +/** + * Create 8 equally sized children nodes and put them in the .children array. + * @method subdivide + */ +OctreeNode.prototype.subdivide = function() { + var aabb = this.aabb; + var l = aabb.lowerBound; + var u = aabb.upperBound; + + var children = this.children; + + children.push( + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,0,0) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,0,0) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,1,0) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,1,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,1,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,0,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,0,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,1,0) }) }) + ); + + u.vsub(l, halfDiagonal); + halfDiagonal.scale(0.5, halfDiagonal); + + var root = this.root || this; + + for (var i = 0; i !== 8; i++) { + var child = children[i]; + + // Set current node as root + child.root = root; + + // Compute bounds + var lowerBound = child.aabb.lowerBound; + lowerBound.x *= halfDiagonal.x; + lowerBound.y *= halfDiagonal.y; + lowerBound.z *= halfDiagonal.z; + + lowerBound.vadd(l, lowerBound); + + // Upper bound is always lower bound + halfDiagonal + lowerBound.vadd(halfDiagonal, child.aabb.upperBound); + } +}; + +/** + * Get all data, potentially within an AABB + * @method aabbQuery + * @param {AABB} aabb + * @param {array} result + * @return {array} The "result" object + */ +OctreeNode.prototype.aabbQuery = function(aabb, result) { + + var nodeData = this.data; + + // abort if the range does not intersect this node + // if (!this.aabb.overlaps(aabb)){ + // return result; + // } + + // Add objects at this level + // Array.prototype.push.apply(result, nodeData); + + // Add child data + // @todo unwrap recursion into a queue / loop, that's faster in JS + var children = this.children; + + + // for (var i = 0, N = this.children.length; i !== N; i++) { + // children[i].aabbQuery(aabb, result); + // } + + var queue = [this]; + while (queue.length) { + var node = queue.pop(); + if (node.aabb.overlaps(aabb)){ + Array.prototype.push.apply(result, node.data); + } + Array.prototype.push.apply(queue, node.children); + } + + return result; +}; + +var tmpAABB = new AABB(); + +/** + * Get all data, potentially intersected by a ray. + * @method rayQuery + * @param {Ray} ray + * @param {Transform} treeTransform + * @param {array} result + * @return {array} The "result" object + */ +OctreeNode.prototype.rayQuery = function(ray, treeTransform, result) { + + // Use aabb query for now. + // @todo implement real ray query which needs less lookups + ray.getAABB(tmpAABB); + tmpAABB.toLocalFrame(treeTransform, tmpAABB); + this.aabbQuery(tmpAABB, result); + + return result; +}; + +/** + * @method removeEmptyNodes + */ +OctreeNode.prototype.removeEmptyNodes = function() { + var queue = [this]; + while (queue.length) { + var node = queue.pop(); + for (var i = node.children.length - 1; i >= 0; i--) { + if(!node.children[i].data.length){ + node.children.splice(i, 1); + } + } + Array.prototype.push.apply(queue, node.children); + } +}; + +},{"../collision/AABB":3,"../math/Vec3":30}],51:[function(_dereq_,module,exports){ +module.exports = Pool; + +/** + * For pooling objects that can be reused. + * @class Pool + * @constructor + */ +function Pool(){ + /** + * The pooled objects + * @property {Array} objects + */ + this.objects = []; + + /** + * Constructor of the objects + * @property {mixed} type + */ + this.type = Object; +} + +/** + * Release an object after use + * @method release + * @param {Object} obj + */ +Pool.prototype.release = function(){ + var Nargs = arguments.length; + for(var i=0; i!==Nargs; i++){ + this.objects.push(arguments[i]); + } +}; + +/** + * Get an object + * @method get + * @return {mixed} + */ +Pool.prototype.get = function(){ + if(this.objects.length===0){ + return this.constructObject(); + } else { + return this.objects.pop(); + } +}; + +/** + * Construct an object. Should be implmented in each subclass. + * @method constructObject + * @return {mixed} + */ +Pool.prototype.constructObject = function(){ + throw new Error("constructObject() not implemented in this Pool subclass yet!"); +}; + +},{}],52:[function(_dereq_,module,exports){ +module.exports = TupleDictionary; + +/** + * @class TupleDictionary + * @constructor + */ +function TupleDictionary() { + + /** + * The data storage + * @property data + * @type {Object} + */ + this.data = { keys:[] }; +} + +/** + * @method get + * @param {Number} i + * @param {Number} j + * @return {Number} + */ +TupleDictionary.prototype.get = function(i, j) { + if (i > j) { + // swap + var temp = j; + j = i; + i = temp; + } + return this.data[i+'-'+j]; +}; + +/** + * @method set + * @param {Number} i + * @param {Number} j + * @param {Number} value + */ +TupleDictionary.prototype.set = function(i, j, value) { + if (i > j) { + var temp = j; + j = i; + i = temp; + } + var key = i+'-'+j; + + // Check if key already exists + if(!this.get(i,j)){ + this.data.keys.push(key); + } + + this.data[key] = value; +}; + +/** + * @method reset + */ +TupleDictionary.prototype.reset = function() { + var data = this.data, + keys = data.keys; + while(keys.length > 0){ + var key = keys.pop(); + delete data[key]; + } +}; + +},{}],53:[function(_dereq_,module,exports){ +function Utils(){} + +module.exports = Utils; + +/** + * Extend an options object with default values. + * @static + * @method defaults + * @param {object} options The options object. May be falsy: in this case, a new object is created and returned. + * @param {object} defaults An object containing default values. + * @return {object} The modified options object. + */ +Utils.defaults = function(options, defaults){ + options = options || {}; + + for(var key in defaults){ + if(!(key in options)){ + options[key] = defaults[key]; + } + } + + return options; +}; + +},{}],54:[function(_dereq_,module,exports){ +module.exports = Vec3Pool; + +var Vec3 = _dereq_('../math/Vec3'); +var Pool = _dereq_('./Pool'); + +/** + * @class Vec3Pool + * @constructor + * @extends Pool + */ +function Vec3Pool(){ + Pool.call(this); + this.type = Vec3; +} +Vec3Pool.prototype = new Pool(); + +/** + * Construct a vector + * @method constructObject + * @return {Vec3} + */ +Vec3Pool.prototype.constructObject = function(){ + return new Vec3(); +}; + +},{"../math/Vec3":30,"./Pool":51}],55:[function(_dereq_,module,exports){ +module.exports = Narrowphase; + +var AABB = _dereq_('../collision/AABB'); +var Shape = _dereq_('../shapes/Shape'); +var Ray = _dereq_('../collision/Ray'); +var Vec3 = _dereq_('../math/Vec3'); +var Transform = _dereq_('../math/Transform'); +var ConvexPolyhedron = _dereq_('../shapes/ConvexPolyhedron'); +var Quaternion = _dereq_('../math/Quaternion'); +var Solver = _dereq_('../solver/Solver'); +var Vec3Pool = _dereq_('../utils/Vec3Pool'); +var ContactEquation = _dereq_('../equations/ContactEquation'); +var FrictionEquation = _dereq_('../equations/FrictionEquation'); + +/** + * Helper class for the World. Generates ContactEquations. + * @class Narrowphase + * @constructor + * @todo Sphere-ConvexPolyhedron contacts + * @todo Contact reduction + * @todo should move methods to prototype + */ +function Narrowphase(world){ + + /** + * Internal storage of pooled contact points. + * @property {Array} contactPointPool + */ + this.contactPointPool = []; + + this.frictionEquationPool = []; + + this.result = []; + this.frictionResult = []; + + /** + * Pooled vectors. + * @property {Vec3Pool} v3pool + */ + this.v3pool = new Vec3Pool(); + + this.world = world; + this.currentContactMaterial = null; + + /** + * @property {Boolean} enableFrictionReduction + */ + this.enableFrictionReduction = false; +} + +/** + * Make a contact object, by using the internal pool or creating a new one. + * @method createContactEquation + * @return {ContactEquation} + */ +Narrowphase.prototype.createContactEquation = function(bi, bj, si, sj, rsi, rsj){ + var c; + if(this.contactPointPool.length){ + c = this.contactPointPool.pop(); + c.bi = bi; + c.bj = bj; + } else { + c = new ContactEquation(bi, bj); + } + + c.enabled = bi.collisionResponse && bj.collisionResponse && si.collisionResponse && sj.collisionResponse; + + var cm = this.currentContactMaterial; + + c.restitution = cm.restitution; + + c.setSpookParams( + cm.contactEquationStiffness, + cm.contactEquationRelaxation, + this.world.dt + ); + + var matA = si.material || bi.material; + var matB = sj.material || bj.material; + if(matA && matB && matA.restitution >= 0 && matB.restitution >= 0){ + c.restitution = matA.restitution * matB.restitution; + } + + c.si = rsi || si; + c.sj = rsj || sj; + + return c; +}; + +Narrowphase.prototype.createFrictionEquationsFromContact = function(contactEquation, outArray){ + var bodyA = contactEquation.bi; + var bodyB = contactEquation.bj; + var shapeA = contactEquation.si; + var shapeB = contactEquation.sj; + + var world = this.world; + var cm = this.currentContactMaterial; + + // If friction or restitution were specified in the material, use them + var friction = cm.friction; + var matA = shapeA.material || bodyA.material; + var matB = shapeB.material || bodyB.material; + if(matA && matB && matA.friction >= 0 && matB.friction >= 0){ + friction = matA.friction * matB.friction; + } + + if(friction > 0){ + + // Create 2 tangent equations + var mug = friction * world.gravity.length(); + var reducedMass = (bodyA.invMass + bodyB.invMass); + if(reducedMass > 0){ + reducedMass = 1/reducedMass; + } + var pool = this.frictionEquationPool; + var c1 = pool.length ? pool.pop() : new FrictionEquation(bodyA,bodyB,mug*reducedMass); + var c2 = pool.length ? pool.pop() : new FrictionEquation(bodyA,bodyB,mug*reducedMass); + + c1.bi = c2.bi = bodyA; + c1.bj = c2.bj = bodyB; + c1.minForce = c2.minForce = -mug*reducedMass; + c1.maxForce = c2.maxForce = mug*reducedMass; + + // Copy over the relative vectors + c1.ri.copy(contactEquation.ri); + c1.rj.copy(contactEquation.rj); + c2.ri.copy(contactEquation.ri); + c2.rj.copy(contactEquation.rj); + + // Construct tangents + contactEquation.ni.tangents(c1.t, c2.t); + + // Set spook params + c1.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt); + c2.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt); + + c1.enabled = c2.enabled = contactEquation.enabled; + + outArray.push(c1, c2); + + return true; + } + + return false; +}; + +var averageNormal = new Vec3(); +var averageContactPointA = new Vec3(); +var averageContactPointB = new Vec3(); + +// Take the average N latest contact point on the plane. +Narrowphase.prototype.createFrictionFromAverage = function(numContacts){ + // The last contactEquation + var c = this.result[this.result.length - 1]; + + // Create the result: two "average" friction equations + if (!this.createFrictionEquationsFromContact(c, this.frictionResult) || numContacts === 1) { + return; + } + + var f1 = this.frictionResult[this.frictionResult.length - 2]; + var f2 = this.frictionResult[this.frictionResult.length - 1]; + + averageNormal.setZero(); + averageContactPointA.setZero(); + averageContactPointB.setZero(); + + var bodyA = c.bi; + var bodyB = c.bj; + for(var i=0; i!==numContacts; i++){ + c = this.result[this.result.length - 1 - i]; + if(c.bodyA !== bodyA){ + averageNormal.vadd(c.ni, averageNormal); // vec2.add(eq.t, eq.t, c.normalA); + averageContactPointA.vadd(c.ri, averageContactPointA); // vec2.add(eq.contactPointA, eq.contactPointA, c.contactPointA); + averageContactPointB.vadd(c.rj, averageContactPointB); + } else { + averageNormal.vsub(c.ni, averageNormal); // vec2.sub(eq.t, eq.t, c.normalA); + averageContactPointA.vadd(c.rj, averageContactPointA); // vec2.add(eq.contactPointA, eq.contactPointA, c.contactPointA); + averageContactPointB.vadd(c.ri, averageContactPointB); + } + } + + var invNumContacts = 1 / numContacts; + averageContactPointA.scale(invNumContacts, f1.ri); // vec2.scale(eq.contactPointA, eq.contactPointA, invNumContacts); + averageContactPointB.scale(invNumContacts, f1.rj); // vec2.scale(eq.contactPointB, eq.contactPointB, invNumContacts); + f2.ri.copy(f1.ri); // Should be the same + f2.rj.copy(f1.rj); + averageNormal.normalize(); + averageNormal.tangents(f1.t, f2.t); + // return eq; +}; + + +var tmpVec1 = new Vec3(); +var tmpVec2 = new Vec3(); +var tmpQuat1 = new Quaternion(); +var tmpQuat2 = new Quaternion(); + +/** + * Generate all contacts between a list of body pairs + * @method getContacts + * @param {array} p1 Array of body indices + * @param {array} p2 Array of body indices + * @param {World} world + * @param {array} result Array to store generated contacts + * @param {array} oldcontacts Optional. Array of reusable contact objects + */ +Narrowphase.prototype.getContacts = function(p1, p2, world, result, oldcontacts, frictionResult, frictionPool){ + // Save old contact objects + this.contactPointPool = oldcontacts; + this.frictionEquationPool = frictionPool; + this.result = result; + this.frictionResult = frictionResult; + + var qi = tmpQuat1; + var qj = tmpQuat2; + var xi = tmpVec1; + var xj = tmpVec2; + + for(var k=0, N=p1.length; k!==N; k++){ + + // Get current collision bodies + var bi = p1[k], + bj = p2[k]; + + // Get contact material + var bodyContactMaterial = null; + if(bi.material && bj.material){ + bodyContactMaterial = world.getContactMaterial(bi.material,bj.material) || null; + } + + for (var i = 0; i < bi.shapes.length; i++) { + bi.quaternion.mult(bi.shapeOrientations[i], qi); + bi.quaternion.vmult(bi.shapeOffsets[i], xi); + xi.vadd(bi.position, xi); + var si = bi.shapes[i]; + + for (var j = 0; j < bj.shapes.length; j++) { + + // Compute world transform of shapes + bj.quaternion.mult(bj.shapeOrientations[j], qj); + bj.quaternion.vmult(bj.shapeOffsets[j], xj); + xj.vadd(bj.position, xj); + var sj = bj.shapes[j]; + + if(xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius){ + continue; + } + + // Get collision material + var shapeContactMaterial = null; + if(si.material && sj.material){ + shapeContactMaterial = world.getContactMaterial(si.material,sj.material) || null; + } + + this.currentContactMaterial = shapeContactMaterial || bodyContactMaterial || world.defaultContactMaterial; + + // Get contacts + var resolver = this[si.type | sj.type]; + if(resolver){ + if (si.type < sj.type) { + resolver.call(this, si, sj, xi, xj, qi, qj, bi, bj, si, sj); + } else { + resolver.call(this, sj, si, xj, xi, qj, qi, bj, bi, si, sj); + } + } + } + } + } +}; + +var numWarnings = 0; +var maxWarnings = 10; + +function warn(msg){ + if(numWarnings > maxWarnings){ + return; + } + + numWarnings++; + + console.warn(msg); +} + +Narrowphase.prototype[Shape.types.BOX | Shape.types.BOX] = +Narrowphase.prototype.boxBox = function(si,sj,xi,xj,qi,qj,bi,bj){ + si.convexPolyhedronRepresentation.material = si.material; + sj.convexPolyhedronRepresentation.material = sj.material; + si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; + sj.convexPolyhedronRepresentation.collisionResponse = sj.collisionResponse; + this.convexConvex(si.convexPolyhedronRepresentation,sj.convexPolyhedronRepresentation,xi,xj,qi,qj,bi,bj,si,sj); +}; + +Narrowphase.prototype[Shape.types.BOX | Shape.types.CONVEXPOLYHEDRON] = +Narrowphase.prototype.boxConvex = function(si,sj,xi,xj,qi,qj,bi,bj){ + si.convexPolyhedronRepresentation.material = si.material; + si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; + this.convexConvex(si.convexPolyhedronRepresentation,sj,xi,xj,qi,qj,bi,bj,si,sj); +}; + +Narrowphase.prototype[Shape.types.BOX | Shape.types.PARTICLE] = +Narrowphase.prototype.boxParticle = function(si,sj,xi,xj,qi,qj,bi,bj){ + si.convexPolyhedronRepresentation.material = si.material; + si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; + this.convexParticle(si.convexPolyhedronRepresentation,sj,xi,xj,qi,qj,bi,bj,si,sj); +}; + +/** + * @method sphereSphere + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.SPHERE] = +Narrowphase.prototype.sphereSphere = function(si,sj,xi,xj,qi,qj,bi,bj){ + // We will have only one contact in this case + var r = this.createContactEquation(bi,bj,si,sj); + + // Contact normal + xj.vsub(xi, r.ni); + r.ni.normalize(); + + // Contact point locations + r.ri.copy(r.ni); + r.rj.copy(r.ni); + r.ri.mult(si.radius, r.ri); + r.rj.mult(-sj.radius, r.rj); + + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + + this.createFrictionEquationsFromContact(r, this.frictionResult); +}; + +/** + * @method planeTrimesh + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +var planeTrimesh_normal = new Vec3(); +var planeTrimesh_relpos = new Vec3(); +var planeTrimesh_projected = new Vec3(); +Narrowphase.prototype[Shape.types.PLANE | Shape.types.TRIMESH] = +Narrowphase.prototype.planeTrimesh = function( + planeShape, + trimeshShape, + planePos, + trimeshPos, + planeQuat, + trimeshQuat, + planeBody, + trimeshBody +){ + // Make contacts! + var v = new Vec3(); + + var normal = planeTrimesh_normal; + normal.set(0,0,1); + planeQuat.vmult(normal,normal); // Turn normal according to plane + + for(var i=0; i 0 && positionAlongEdgeB < 0){ + + // Now check the orthogonal distance from edge to sphere center + localSpherePos.vsub(edgeVertexA, tmp); + + edgeVectorUnit.copy(edgeVector); + edgeVectorUnit.normalize(); + positionAlongEdgeA = tmp.dot(edgeVectorUnit); + + edgeVectorUnit.scale(positionAlongEdgeA, tmp); + tmp.vadd(edgeVertexA, tmp); + + // tmp is now the sphere center position projected to the edge, defined locally in the trimesh frame + var dist = tmp.distanceTo(localSpherePos); + if(dist < sphereShape.radius){ + var r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape); + + tmp.vsub(localSpherePos, r.ni); + r.ni.normalize(); + r.ni.scale(sphereShape.radius, r.ri); + + Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp, tmp); + tmp.vsub(trimeshBody.position, r.rj); + + Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni); + Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + } + } + + // Triangle faces + var va = sphereTrimesh_va; + var vb = sphereTrimesh_vb; + var vc = sphereTrimesh_vc; + var normal = sphereTrimesh_normal; + for(var i=0, N = triangles.length; i !== N; i++){ + trimeshShape.getTriangleVertices(triangles[i], va, vb, vc); + trimeshShape.getNormal(triangles[i], normal); + localSpherePos.vsub(va, tmp); + var dist = tmp.dot(normal); + normal.scale(dist, tmp); + localSpherePos.vsub(tmp, tmp); + + // tmp is now the sphere position projected to the triangle plane + dist = tmp.distanceTo(localSpherePos); + if(Ray.pointInTriangle(tmp, va, vb, vc) && dist < sphereShape.radius){ + var r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape); + + tmp.vsub(localSpherePos, r.ni); + r.ni.normalize(); + r.ni.scale(sphereShape.radius, r.ri); + + Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp, tmp); + tmp.vsub(trimeshBody.position, r.rj); + + Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni); + Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + + triangles.length = 0; +}; + +var point_on_plane_to_sphere = new Vec3(); +var plane_to_sphere_ortho = new Vec3(); + +/** + * @method spherePlane + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.SPHERE | Shape.types.PLANE] = +Narrowphase.prototype.spherePlane = function(si,sj,xi,xj,qi,qj,bi,bj){ + // We will have one contact in this case + var r = this.createContactEquation(bi,bj,si,sj); + + // Contact normal + r.ni.set(0,0,1); + qj.vmult(r.ni, r.ni); + r.ni.negate(r.ni); // body i is the sphere, flip normal + r.ni.normalize(); // Needed? + + // Vector from sphere center to contact point + r.ni.mult(si.radius, r.ri); + + // Project down sphere on plane + xi.vsub(xj, point_on_plane_to_sphere); + r.ni.mult(r.ni.dot(point_on_plane_to_sphere), plane_to_sphere_ortho); + point_on_plane_to_sphere.vsub(plane_to_sphere_ortho,r.rj); // The sphere position projected to plane + + if(-point_on_plane_to_sphere.dot(r.ni) <= si.radius){ + + // Make it relative to the body + var ri = r.ri; + var rj = r.rj; + ri.vadd(xi, ri); + ri.vsub(bi.position, ri); + rj.vadd(xj, rj); + rj.vsub(bj.position, rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } +}; + +// See http://bulletphysics.com/Bullet/BulletFull/SphereTriangleDetector_8cpp_source.html +var pointInPolygon_edge = new Vec3(); +var pointInPolygon_edge_x_normal = new Vec3(); +var pointInPolygon_vtp = new Vec3(); +function pointInPolygon(verts, normal, p){ + var positiveResult = null; + var N = verts.length; + for(var i=0; i!==N; i++){ + var v = verts[i]; + + // Get edge to the next vertex + var edge = pointInPolygon_edge; + verts[(i+1) % (N)].vsub(v,edge); + + // Get cross product between polygon normal and the edge + var edge_x_normal = pointInPolygon_edge_x_normal; + //var edge_x_normal = new Vec3(); + edge.cross(normal,edge_x_normal); + + // Get vector between point and current vertex + var vertex_to_p = pointInPolygon_vtp; + p.vsub(v,vertex_to_p); + + // This dot product determines which side of the edge the point is + var r = edge_x_normal.dot(vertex_to_p); + + // If all such dot products have same sign, we are inside the polygon. + if(positiveResult===null || (r>0 && positiveResult===true) || (r<=0 && positiveResult===false)){ + if(positiveResult===null){ + positiveResult = r>0; + } + continue; + } else { + return false; // Encountered some other sign. Exit. + } + } + + // If we got here, all dot products were of the same sign. + return true; +} + +var box_to_sphere = new Vec3(); +var sphereBox_ns = new Vec3(); +var sphereBox_ns1 = new Vec3(); +var sphereBox_ns2 = new Vec3(); +var sphereBox_sides = [new Vec3(),new Vec3(),new Vec3(),new Vec3(),new Vec3(),new Vec3()]; +var sphereBox_sphere_to_corner = new Vec3(); +var sphereBox_side_ns = new Vec3(); +var sphereBox_side_ns1 = new Vec3(); +var sphereBox_side_ns2 = new Vec3(); + +/** + * @method sphereBox + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.SPHERE | Shape.types.BOX] = +Narrowphase.prototype.sphereBox = function(si,sj,xi,xj,qi,qj,bi,bj){ + var v3pool = this.v3pool; + + // we refer to the box as body j + var sides = sphereBox_sides; + xi.vsub(xj,box_to_sphere); + sj.getSideNormals(sides,qj); + var R = si.radius; + var penetrating_sides = []; + + // Check side (plane) intersections + var found = false; + + // Store the resulting side penetration info + var side_ns = sphereBox_side_ns; + var side_ns1 = sphereBox_side_ns1; + var side_ns2 = sphereBox_side_ns2; + var side_h = null; + var side_penetrations = 0; + var side_dot1 = 0; + var side_dot2 = 0; + var side_distance = null; + for(var idx=0,nsides=sides.length; idx!==nsides && found===false; idx++){ + // Get the plane side normal (ns) + var ns = sphereBox_ns; + ns.copy(sides[idx]); + + var h = ns.norm(); + ns.normalize(); + + // The normal/distance dot product tells which side of the plane we are + var dot = box_to_sphere.dot(ns); + + if(dot0){ + // Intersects plane. Now check the other two dimensions + var ns1 = sphereBox_ns1; + var ns2 = sphereBox_ns2; + ns1.copy(sides[(idx+1)%3]); + ns2.copy(sides[(idx+2)%3]); + var h1 = ns1.norm(); + var h2 = ns2.norm(); + ns1.normalize(); + ns2.normalize(); + var dot1 = box_to_sphere.dot(ns1); + var dot2 = box_to_sphere.dot(ns2); + if(dot1

        -h1 && dot2

        -h2){ + var dist = Math.abs(dot-h-R); + if(side_distance===null || dist < side_distance){ + side_distance = dist; + side_dot1 = dot1; + side_dot2 = dot2; + side_h = h; + side_ns.copy(ns); + side_ns1.copy(ns1); + side_ns2.copy(ns2); + side_penetrations++; + } + } + } + } + if(side_penetrations){ + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + side_ns.mult(-R,r.ri); // Sphere r + r.ni.copy(side_ns); + r.ni.negate(r.ni); // Normal should be out of sphere + side_ns.mult(side_h,side_ns); + side_ns1.mult(side_dot1,side_ns1); + side_ns.vadd(side_ns1,side_ns); + side_ns2.mult(side_dot2,side_ns2); + side_ns.vadd(side_ns2,r.rj); + + // Make relative to bodies + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + + // Check corners + var rj = v3pool.get(); + var sphere_to_corner = sphereBox_sphere_to_corner; + for(var j=0; j!==2 && !found; j++){ + for(var k=0; k!==2 && !found; k++){ + for(var l=0; l!==2 && !found; l++){ + rj.set(0,0,0); + if(j){ + rj.vadd(sides[0],rj); + } else { + rj.vsub(sides[0],rj); + } + if(k){ + rj.vadd(sides[1],rj); + } else { + rj.vsub(sides[1],rj); + } + if(l){ + rj.vadd(sides[2],rj); + } else { + rj.vsub(sides[2],rj); + } + + // World position of corner + xj.vadd(rj,sphere_to_corner); + sphere_to_corner.vsub(xi,sphere_to_corner); + + if(sphere_to_corner.norm2() < R*R){ + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + r.ri.copy(sphere_to_corner); + r.ri.normalize(); + r.ni.copy(r.ri); + r.ri.mult(R,r.ri); + r.rj.copy(rj); + + // Make relative to bodies + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + } + } + v3pool.release(rj); + rj = null; + + // Check edges + var edgeTangent = v3pool.get(); + var edgeCenter = v3pool.get(); + var r = v3pool.get(); // r = edge center to sphere center + var orthogonal = v3pool.get(); + var dist = v3pool.get(); + var Nsides = sides.length; + for(var j=0; j!==Nsides && !found; j++){ + for(var k=0; k!==Nsides && !found; k++){ + if(j%3 !== k%3){ + // Get edge tangent + sides[k].cross(sides[j],edgeTangent); + edgeTangent.normalize(); + sides[j].vadd(sides[k], edgeCenter); + r.copy(xi); + r.vsub(edgeCenter,r); + r.vsub(xj,r); + var orthonorm = r.dot(edgeTangent); // distance from edge center to sphere center in the tangent direction + edgeTangent.mult(orthonorm,orthogonal); // Vector from edge center to sphere center in the tangent direction + + // Find the third side orthogonal to this one + var l = 0; + while(l===j%3 || l===k%3){ + l++; + } + + // vec from edge center to sphere projected to the plane orthogonal to the edge tangent + dist.copy(xi); + dist.vsub(orthogonal,dist); + dist.vsub(edgeCenter,dist); + dist.vsub(xj,dist); + + // Distances in tangent direction and distance in the plane orthogonal to it + var tdist = Math.abs(orthonorm); + var ndist = dist.norm(); + + if(tdist < sides[l].norm() && ndist si.boundingSphereRadius + sj.boundingSphereRadius){ + // return; + // } + + // Check corners + for(var i=0; i!==verts.length; i++){ + var v = verts[i]; + + // World position of corner + var worldCorner = sphereConvex_worldCorner; + qj.vmult(v,worldCorner); + xj.vadd(worldCorner,worldCorner); + var sphere_to_corner = sphereConvex_sphereToCorner; + worldCorner.vsub(xi, sphere_to_corner); + if(sphere_to_corner.norm2() < R * R){ + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + r.ri.copy(sphere_to_corner); + r.ri.normalize(); + r.ni.copy(r.ri); + r.ri.mult(R,r.ri); + worldCorner.vsub(xj,r.rj); + + // Should be relative to the body. + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + + // Should be relative to the body. + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + return; + } + } + + // Check side (plane) intersections + var found = false; + for(var i=0, nfaces=faces.length; i!==nfaces && found===false; i++){ + var normal = normals[i]; + var face = faces[i]; + + // Get world-transformed normal of the face + var worldNormal = sphereConvex_worldNormal; + qj.vmult(normal,worldNormal); + + // Get a world vertex from the face + var worldPoint = sphereConvex_worldPoint; + qj.vmult(verts[face[0]],worldPoint); + worldPoint.vadd(xj,worldPoint); + + // Get a point on the sphere, closest to the face normal + var worldSpherePointClosestToPlane = sphereConvex_worldSpherePointClosestToPlane; + worldNormal.mult(-R, worldSpherePointClosestToPlane); + xi.vadd(worldSpherePointClosestToPlane, worldSpherePointClosestToPlane); + + // Vector from a face point to the closest point on the sphere + var penetrationVec = sphereConvex_penetrationVec; + worldSpherePointClosestToPlane.vsub(worldPoint,penetrationVec); + + // The penetration. Negative value means overlap. + var penetration = penetrationVec.dot(worldNormal); + + var worldPointToSphere = sphereConvex_sphereToWorldPoint; + xi.vsub(worldPoint, worldPointToSphere); + + if(penetration < 0 && worldPointToSphere.dot(worldNormal)>0){ + // Intersects plane. Now check if the sphere is inside the face polygon + var faceVerts = []; // Face vertices, in world coords + for(var j=0, Nverts=face.length; j!==Nverts; j++){ + var worldVertex = v3pool.get(); + qj.vmult(verts[face[j]], worldVertex); + xj.vadd(worldVertex,worldVertex); + faceVerts.push(worldVertex); + } + + if(pointInPolygon(faceVerts,worldNormal,xi)){ // Is the sphere center in the face polygon? + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + + worldNormal.mult(-R, r.ri); // Contact offset, from sphere center to contact + worldNormal.negate(r.ni); // Normal pointing out of sphere + + var penetrationVec2 = v3pool.get(); + worldNormal.mult(-penetration, penetrationVec2); + var penetrationSpherePoint = v3pool.get(); + worldNormal.mult(-R, penetrationSpherePoint); + + //xi.vsub(xj).vadd(penetrationSpherePoint).vadd(penetrationVec2 , r.rj); + xi.vsub(xj,r.rj); + r.rj.vadd(penetrationSpherePoint,r.rj); + r.rj.vadd(penetrationVec2 , r.rj); + + // Should be relative to the body. + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + // Should be relative to the body. + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + + v3pool.release(penetrationVec2); + v3pool.release(penetrationSpherePoint); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + + // Release world vertices + for(var j=0, Nfaceverts=faceVerts.length; j!==Nfaceverts; j++){ + v3pool.release(faceVerts[j]); + } + + return; // We only expect *one* face contact + } else { + // Edge? + for(var j=0; j!==face.length; j++){ + + // Get two world transformed vertices + var v1 = v3pool.get(); + var v2 = v3pool.get(); + qj.vmult(verts[face[(j+1)%face.length]], v1); + qj.vmult(verts[face[(j+2)%face.length]], v2); + xj.vadd(v1, v1); + xj.vadd(v2, v2); + + // Construct edge vector + var edge = sphereConvex_edge; + v2.vsub(v1,edge); + + // Construct the same vector, but normalized + var edgeUnit = sphereConvex_edgeUnit; + edge.unit(edgeUnit); + + // p is xi projected onto the edge + var p = v3pool.get(); + var v1_to_xi = v3pool.get(); + xi.vsub(v1, v1_to_xi); + var dot = v1_to_xi.dot(edgeUnit); + edgeUnit.mult(dot, p); + p.vadd(v1, p); + + // Compute a vector from p to the center of the sphere + var xi_to_p = v3pool.get(); + p.vsub(xi, xi_to_p); + + // Collision if the edge-sphere distance is less than the radius + // AND if p is in between v1 and v2 + if(dot > 0 && dot*dot si.boundingSphereRadius + sj.boundingSphereRadius){ + return; + } + + if(si.findSeparatingAxis(sj,xi,qi,xj,qj,sepAxis,faceListA,faceListB)){ + var res = []; + var q = convexConvex_q; + si.clipAgainstHull(xi,qi,sj,xj,qj,sepAxis,-100,100,res); + var numContacts = 0; + for(var j = 0; j !== res.length; j++){ + var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj), + ri = r.ri, + rj = r.rj; + sepAxis.negate(r.ni); + res[j].normal.negate(q); + q.mult(res[j].depth, q); + res[j].point.vadd(q, ri); + rj.copy(res[j].point); + + // Contact points are in world coordinates. Transform back to relative + ri.vsub(xi,ri); + rj.vsub(xj,rj); + + // Make relative to bodies + ri.vadd(xi, ri); + ri.vsub(bi.position, ri); + rj.vadd(xj, rj); + rj.vsub(bj.position, rj); + + this.result.push(r); + numContacts++; + if(!this.enableFrictionReduction){ + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + if(this.enableFrictionReduction && numContacts){ + this.createFrictionFromAverage(numContacts); + } + } +}; + + +/** + * @method convexTrimesh + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +// Narrowphase.prototype[Shape.types.CONVEXPOLYHEDRON | Shape.types.TRIMESH] = +// Narrowphase.prototype.convexTrimesh = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,faceListA,faceListB){ +// var sepAxis = convexConvex_sepAxis; + +// if(xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius){ +// return; +// } + +// // Construct a temp hull for each triangle +// var hullB = new ConvexPolyhedron(); + +// hullB.faces = [[0,1,2]]; +// var va = new Vec3(); +// var vb = new Vec3(); +// var vc = new Vec3(); +// hullB.vertices = [ +// va, +// vb, +// vc +// ]; + +// for (var i = 0; i < sj.indices.length / 3; i++) { + +// var triangleNormal = new Vec3(); +// sj.getNormal(i, triangleNormal); +// hullB.faceNormals = [triangleNormal]; + +// sj.getTriangleVertices(i, va, vb, vc); + +// var d = si.testSepAxis(triangleNormal, hullB, xi, qi, xj, qj); +// if(!d){ +// triangleNormal.scale(-1, triangleNormal); +// d = si.testSepAxis(triangleNormal, hullB, xi, qi, xj, qj); + +// if(!d){ +// continue; +// } +// } + +// var res = []; +// var q = convexConvex_q; +// si.clipAgainstHull(xi,qi,hullB,xj,qj,triangleNormal,-100,100,res); +// for(var j = 0; j !== res.length; j++){ +// var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj), +// ri = r.ri, +// rj = r.rj; +// r.ni.copy(triangleNormal); +// r.ni.negate(r.ni); +// res[j].normal.negate(q); +// q.mult(res[j].depth, q); +// res[j].point.vadd(q, ri); +// rj.copy(res[j].point); + +// // Contact points are in world coordinates. Transform back to relative +// ri.vsub(xi,ri); +// rj.vsub(xj,rj); + +// // Make relative to bodies +// ri.vadd(xi, ri); +// ri.vsub(bi.position, ri); +// rj.vadd(xj, rj); +// rj.vsub(bj.position, rj); + +// result.push(r); +// } +// } +// }; + +var particlePlane_normal = new Vec3(); +var particlePlane_relpos = new Vec3(); +var particlePlane_projected = new Vec3(); + +/** + * @method particlePlane + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.PLANE | Shape.types.PARTICLE] = +Narrowphase.prototype.planeParticle = function(sj,si,xj,xi,qj,qi,bj,bi){ + var normal = particlePlane_normal; + normal.set(0,0,1); + bj.quaternion.vmult(normal,normal); // Turn normal according to plane orientation + var relpos = particlePlane_relpos; + xi.vsub(bj.position,relpos); + var dot = normal.dot(relpos); + if(dot <= 0.0){ + var r = this.createContactEquation(bi,bj,si,sj); + r.ni.copy(normal); // Contact normal is the plane normal + r.ni.negate(r.ni); + r.ri.set(0,0,0); // Center of particle + + // Get particle position projected on plane + var projected = particlePlane_projected; + normal.mult(normal.dot(xi),projected); + xi.vsub(projected,projected); + //projected.vadd(bj.position,projected); + + // rj is now the projected world position minus plane position + r.rj.copy(projected); + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } +}; + +var particleSphere_normal = new Vec3(); + +/** + * @method particleSphere + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.PARTICLE | Shape.types.SPHERE] = +Narrowphase.prototype.sphereParticle = function(sj,si,xj,xi,qj,qi,bj,bi){ + // The normal is the unit vector from sphere center to particle center + var normal = particleSphere_normal; + normal.set(0,0,1); + xi.vsub(xj,normal); + var lengthSquared = normal.norm2(); + + if(lengthSquared <= sj.radius * sj.radius){ + var r = this.createContactEquation(bi,bj,si,sj); + normal.normalize(); + r.rj.copy(normal); + r.rj.mult(sj.radius,r.rj); + r.ni.copy(normal); // Contact normal + r.ni.negate(r.ni); + r.ri.set(0,0,0); // Center of particle + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } +}; + +// WIP +var cqj = new Quaternion(); +var convexParticle_local = new Vec3(); +var convexParticle_normal = new Vec3(); +var convexParticle_penetratedFaceNormal = new Vec3(); +var convexParticle_vertexToParticle = new Vec3(); +var convexParticle_worldPenetrationVec = new Vec3(); + +/** + * @method convexParticle + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.PARTICLE | Shape.types.CONVEXPOLYHEDRON] = +Narrowphase.prototype.convexParticle = function(sj,si,xj,xi,qj,qi,bj,bi){ + var penetratedFaceIndex = -1; + var penetratedFaceNormal = convexParticle_penetratedFaceNormal; + var worldPenetrationVec = convexParticle_worldPenetrationVec; + var minPenetration = null; + var numDetectedFaces = 0; + + // Convert particle position xi to local coords in the convex + var local = convexParticle_local; + local.copy(xi); + local.vsub(xj,local); // Convert position to relative the convex origin + qj.conjugate(cqj); + cqj.vmult(local,local); + + if(sj.pointIsInside(local)){ + + if(sj.worldVerticesNeedsUpdate){ + sj.computeWorldVertices(xj,qj); + } + if(sj.worldFaceNormalsNeedsUpdate){ + sj.computeWorldFaceNormals(qj); + } + + // For each world polygon in the polyhedra + for(var i=0,nfaces=sj.faces.length; i!==nfaces; i++){ + + // Construct world face vertices + var verts = [ sj.worldVertices[ sj.faces[i][0] ] ]; + var normal = sj.worldFaceNormals[i]; + + // Check how much the particle penetrates the polygon plane. + xi.vsub(verts[0],convexParticle_vertexToParticle); + var penetration = -normal.dot(convexParticle_vertexToParticle); + if(minPenetration===null || Math.abs(penetration) data.length || iMinY > data[0].length){ + return; + } + + // Clamp index to edges + if(iMinX < 0){ iMinX = 0; } + if(iMaxX < 0){ iMaxX = 0; } + if(iMinY < 0){ iMinY = 0; } + if(iMaxY < 0){ iMaxY = 0; } + if(iMinX >= data.length){ iMinX = data.length - 1; } + if(iMaxX >= data.length){ iMaxX = data.length - 1; } + if(iMaxY >= data[0].length){ iMaxY = data[0].length - 1; } + if(iMinY >= data[0].length){ iMinY = data[0].length - 1; } + + var minMax = []; + hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); + var min = minMax[0]; + var max = minMax[1]; + + // Bail out if we're cant touch the bounding height box + if(localConvexPos.z - radius > max || localConvexPos.z + radius < min){ + return; + } + + for(var i = iMinX; i < iMaxX; i++){ + for(var j = iMinY; j < iMaxY; j++){ + + // Lower triangle + hfShape.getConvexTrianglePillar(i, j, false); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (convexPos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) { + this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset, convexQuat, hfQuat, convexBody, hfBody, null, null, faceList, null); + } + + // Upper triangle + hfShape.getConvexTrianglePillar(i, j, true); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (convexPos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) { + this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset, convexQuat, hfQuat, convexBody, hfBody, null, null, faceList, null); + } + } + } +}; + +var sphereHeightfield_tmp1 = new Vec3(); +var sphereHeightfield_tmp2 = new Vec3(); + +/** + * @method sphereHeightfield + */ +Narrowphase.prototype[Shape.types.SPHERE | Shape.types.HEIGHTFIELD] = +Narrowphase.prototype.sphereHeightfield = function ( + sphereShape, + hfShape, + spherePos, + hfPos, + sphereQuat, + hfQuat, + sphereBody, + hfBody +){ + var data = hfShape.data, + radius = sphereShape.radius, + w = hfShape.elementSize, + worldPillarOffset = sphereHeightfield_tmp2; + + // Get sphere position to heightfield local! + var localSpherePos = sphereHeightfield_tmp1; + Transform.pointToLocalFrame(hfPos, hfQuat, spherePos, localSpherePos); + + // Get the index of the data points to test against + var iMinX = Math.floor((localSpherePos.x - radius) / w) - 1, + iMaxX = Math.ceil((localSpherePos.x + radius) / w) + 1, + iMinY = Math.floor((localSpherePos.y - radius) / w) - 1, + iMaxY = Math.ceil((localSpherePos.y + radius) / w) + 1; + + // Bail out if we are out of the terrain + if(iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMaxY > data[0].length){ + return; + } + + // Clamp index to edges + if(iMinX < 0){ iMinX = 0; } + if(iMaxX < 0){ iMaxX = 0; } + if(iMinY < 0){ iMinY = 0; } + if(iMaxY < 0){ iMaxY = 0; } + if(iMinX >= data.length){ iMinX = data.length - 1; } + if(iMaxX >= data.length){ iMaxX = data.length - 1; } + if(iMaxY >= data[0].length){ iMaxY = data[0].length - 1; } + if(iMinY >= data[0].length){ iMinY = data[0].length - 1; } + + var minMax = []; + hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); + var min = minMax[0]; + var max = minMax[1]; + + // Bail out if we're cant touch the bounding height box + if(localSpherePos.z - radius > max || localSpherePos.z + radius < min){ + return; + } + + var result = this.result; + for(var i = iMinX; i < iMaxX; i++){ + for(var j = iMinY; j < iMaxY; j++){ + + var numContactsBefore = result.length; + + // Lower triangle + hfShape.getConvexTrianglePillar(i, j, false); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (spherePos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) { + this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset, sphereQuat, hfQuat, sphereBody, hfBody); + } + + // Upper triangle + hfShape.getConvexTrianglePillar(i, j, true); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (spherePos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) { + this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset, sphereQuat, hfQuat, sphereBody, hfBody); + } + + var numContacts = result.length - numContactsBefore; + + if(numContacts > 2){ + return; + } + /* + // Skip all but 1 + for (var k = 0; k < numContacts - 1; k++) { + result.pop(); + } + */ + } + } +}; + +},{"../collision/AABB":3,"../collision/Ray":9,"../equations/ContactEquation":19,"../equations/FrictionEquation":21,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../shapes/ConvexPolyhedron":38,"../shapes/Shape":43,"../solver/Solver":47,"../utils/Vec3Pool":54}],56:[function(_dereq_,module,exports){ +/* global performance */ + +module.exports = World; + +var Shape = _dereq_('../shapes/Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var GSSolver = _dereq_('../solver/GSSolver'); +var Vec3Pool = _dereq_('../utils/Vec3Pool'); +var ContactEquation = _dereq_('../equations/ContactEquation'); +var FrictionEquation = _dereq_('../equations/FrictionEquation'); +var Narrowphase = _dereq_('./Narrowphase'); +var EventTarget = _dereq_('../utils/EventTarget'); +var ArrayCollisionMatrix = _dereq_('../collision/ArrayCollisionMatrix'); +var Material = _dereq_('../material/Material'); +var ContactMaterial = _dereq_('../material/ContactMaterial'); +var Body = _dereq_('../objects/Body'); +var TupleDictionary = _dereq_('../utils/TupleDictionary'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var AABB = _dereq_('../collision/AABB'); +var Ray = _dereq_('../collision/Ray'); +var NaiveBroadphase = _dereq_('../collision/NaiveBroadphase'); + +/** + * The physics world + * @class World + * @constructor + * @extends EventTarget + */ +function World(){ + EventTarget.apply(this); + + /** + * Currently / last used timestep. Is set to -1 if not available. This value is updated before each internal step, which means that it is "fresh" inside event callbacks. + * @property {Number} dt + */ + this.dt = -1; + + /** + * Makes bodies go to sleep when they've been inactive + * @property allowSleep + * @type {Boolean} + */ + this.allowSleep = false; + + /** + * All the current contacts (instances of ContactEquation) in the world. + * @property contacts + * @type {Array} + */ + this.contacts = []; + this.frictionEquations = []; + + /** + * How often to normalize quaternions. Set to 0 for every step, 1 for every second etc.. A larger value increases performance. If bodies tend to explode, set to a smaller value (zero to be sure nothing can go wrong). + * @property quatNormalizeSkip + * @type {Number} + */ + this.quatNormalizeSkip = 0; + + /** + * Set to true to use fast quaternion normalization. It is often enough accurate to use. If bodies tend to explode, set to false. + * @property quatNormalizeFast + * @type {Boolean} + * @see Quaternion.normalizeFast + * @see Quaternion.normalize + */ + this.quatNormalizeFast = false; + + /** + * The wall-clock time since simulation start + * @property time + * @type {Number} + */ + this.time = 0.0; + + /** + * Number of timesteps taken since start + * @property stepnumber + * @type {Number} + */ + this.stepnumber = 0; + + /// Default and last timestep sizes + this.default_dt = 1/60; + + this.nextId = 0; + /** + * @property gravity + * @type {Vec3} + */ + this.gravity = new Vec3(); + + /** + * @property broadphase + * @type {Broadphase} + */ + this.broadphase = new NaiveBroadphase(); + + /** + * @property bodies + * @type {Array} + */ + this.bodies = []; + + /** + * @property solver + * @type {Solver} + */ + this.solver = new GSSolver(); + + /** + * @property constraints + * @type {Array} + */ + this.constraints = []; + + /** + * @property narrowphase + * @type {Narrowphase} + */ + this.narrowphase = new Narrowphase(this); + + /** + * @property {ArrayCollisionMatrix} collisionMatrix + * @type {ArrayCollisionMatrix} + */ + this.collisionMatrix = new ArrayCollisionMatrix(); + + /** + * CollisionMatrix from the previous step. + * @property {ArrayCollisionMatrix} collisionMatrixPrevious + * @type {ArrayCollisionMatrix} + */ + this.collisionMatrixPrevious = new ArrayCollisionMatrix(); + + /** + * All added materials + * @property materials + * @type {Array} + */ + this.materials = []; + + /** + * @property contactmaterials + * @type {Array} + */ + this.contactmaterials = []; + + /** + * Used to look up a ContactMaterial given two instances of Material. + * @property {TupleDictionary} contactMaterialTable + */ + this.contactMaterialTable = new TupleDictionary(); + + this.defaultMaterial = new Material("default"); + + /** + * This contact material is used if no suitable contactmaterial is found for a contact. + * @property defaultContactMaterial + * @type {ContactMaterial} + */ + this.defaultContactMaterial = new ContactMaterial(this.defaultMaterial, this.defaultMaterial, { friction: 0.3, restitution: 0.0 }); + + /** + * @property doProfiling + * @type {Boolean} + */ + this.doProfiling = false; + + /** + * @property profile + * @type {Object} + */ + this.profile = { + solve:0, + makeContactConstraints:0, + broadphase:0, + integrate:0, + narrowphase:0, + }; + + /** + * @property subsystems + * @type {Array} + */ + this.subsystems = []; + + this.addBodyEvent = { + type:"addBody", + body : null, + }; + + this.removeBodyEvent = { + type:"removeBody", + body : null, + }; +} +World.prototype = new EventTarget(); + +// Temp stuff +var tmpAABB1 = new AABB(); +var tmpArray1 = []; +var tmpRay = new Ray(); + +/** + * Get the contact material between materials m1 and m2 + * @method getContactMaterial + * @param {Material} m1 + * @param {Material} m2 + * @return {ContactMaterial} The contact material if it was found. + */ +World.prototype.getContactMaterial = function(m1,m2){ + return this.contactMaterialTable.get(m1.id,m2.id); //this.contactmaterials[this.mats2cmat[i+j*this.materials.length]]; +}; + +/** + * Get number of objects in the world. + * @method numObjects + * @return {Number} + * @deprecated + */ +World.prototype.numObjects = function(){ + return this.bodies.length; +}; + +/** + * Store old collision state info + * @method collisionMatrixTick + */ +World.prototype.collisionMatrixTick = function(){ + var temp = this.collisionMatrixPrevious; + this.collisionMatrixPrevious = this.collisionMatrix; + this.collisionMatrix = temp; + this.collisionMatrix.reset(); +}; + +/** + * Add a rigid body to the simulation. + * @method add + * @param {Body} body + * @todo If the simulation has not yet started, why recrete and copy arrays for each body? Accumulate in dynamic arrays in this case. + * @todo Adding an array of bodies should be possible. This would save some loops too + * @deprecated Use .addBody instead + */ +World.prototype.add = World.prototype.addBody = function(body){ + if(this.bodies.indexOf(body) !== -1){ + return; + } + body.index = this.bodies.length; + this.bodies.push(body); + body.world = this; + body.initPosition.copy(body.position); + body.initVelocity.copy(body.velocity); + body.timeLastSleepy = this.time; + if(body instanceof Body){ + body.initAngularVelocity.copy(body.angularVelocity); + body.initQuaternion.copy(body.quaternion); + } + this.collisionMatrix.setNumObjects(this.bodies.length); + this.addBodyEvent.body = body; + this.dispatchEvent(this.addBodyEvent); +}; + +/** + * Add a constraint to the simulation. + * @method addConstraint + * @param {Constraint} c + */ +World.prototype.addConstraint = function(c){ + this.constraints.push(c); +}; + +/** + * Removes a constraint + * @method removeConstraint + * @param {Constraint} c + */ +World.prototype.removeConstraint = function(c){ + var idx = this.constraints.indexOf(c); + if(idx!==-1){ + this.constraints.splice(idx,1); + } +}; + +/** + * Raycast test + * @method rayTest + * @param {Vec3} from + * @param {Vec3} to + * @param {Function|RaycastResult} result + * @deprecated Use .raycastAll, .raycastClosest or .raycastAny instead. + */ +World.prototype.rayTest = function(from, to, result){ + if(result instanceof RaycastResult){ + // Do raycastclosest + this.raycastClosest(from, to, { + skipBackfaces: true + }, result); + } else { + // Do raycastAll + this.raycastAll(from, to, { + skipBackfaces: true + }, result); + } +}; + +/** + * Ray cast against all bodies. The provided callback will be executed for each hit with a RaycastResult as single argument. + * @method raycastAll + * @param {Vec3} from + * @param {Vec3} to + * @param {Object} options + * @param {number} [options.collisionFilterMask=-1] + * @param {number} [options.collisionFilterGroup=-1] + * @param {boolean} [options.skipBackfaces=false] + * @param {boolean} [options.checkCollisionResponse=true] + * @param {Function} callback + * @return {boolean} True if any body was hit. + */ +World.prototype.raycastAll = function(from, to, options, callback){ + options.mode = Ray.ALL; + options.from = from; + options.to = to; + options.callback = callback; + return tmpRay.intersectWorld(this, options); +}; + +/** + * Ray cast, and stop at the first result. Note that the order is random - but the method is fast. + * @method raycastAny + * @param {Vec3} from + * @param {Vec3} to + * @param {Object} options + * @param {number} [options.collisionFilterMask=-1] + * @param {number} [options.collisionFilterGroup=-1] + * @param {boolean} [options.skipBackfaces=false] + * @param {boolean} [options.checkCollisionResponse=true] + * @param {RaycastResult} result + * @return {boolean} True if any body was hit. + */ +World.prototype.raycastAny = function(from, to, options, result){ + options.mode = Ray.ANY; + options.from = from; + options.to = to; + options.result = result; + return tmpRay.intersectWorld(this, options); +}; + +/** + * Ray cast, and return information of the closest hit. + * @method raycastClosest + * @param {Vec3} from + * @param {Vec3} to + * @param {Object} options + * @param {number} [options.collisionFilterMask=-1] + * @param {number} [options.collisionFilterGroup=-1] + * @param {boolean} [options.skipBackfaces=false] + * @param {boolean} [options.checkCollisionResponse=true] + * @param {RaycastResult} result + * @return {boolean} True if any body was hit. + */ +World.prototype.raycastClosest = function(from, to, options, result){ + options.mode = Ray.CLOSEST; + options.from = from; + options.to = to; + options.result = result; + return tmpRay.intersectWorld(this, options); +}; + +/** + * Remove a rigid body from the simulation. + * @method remove + * @param {Body} body + * @deprecated Use .removeBody instead + */ +World.prototype.remove = function(body){ + body.world = null; + var n = this.bodies.length-1, + bodies = this.bodies, + idx = bodies.indexOf(body); + if(idx !== -1){ + bodies.splice(idx, 1); // Todo: should use a garbage free method + + // Recompute index + for(var i=0; i!==bodies.length; i++){ + bodies[i].index = i; + } + + this.collisionMatrix.setNumObjects(n); + this.removeBodyEvent.body = body; + this.dispatchEvent(this.removeBodyEvent); + } +}; + +/** + * Remove a rigid body from the simulation. + * @method removeBody + * @param {Body} body + */ +World.prototype.removeBody = World.prototype.remove; + +/** + * Adds a material to the World. + * @method addMaterial + * @param {Material} m + * @todo Necessary? + */ +World.prototype.addMaterial = function(m){ + this.materials.push(m); +}; + +/** + * Adds a contact material to the World + * @method addContactMaterial + * @param {ContactMaterial} cmat + */ +World.prototype.addContactMaterial = function(cmat) { + + // Add contact material + this.contactmaterials.push(cmat); + + // Add current contact material to the material table + this.contactMaterialTable.set(cmat.materials[0].id,cmat.materials[1].id,cmat); +}; + +// performance.now() +if(typeof performance === 'undefined'){ + performance = {}; +} +if(!performance.now){ + var nowOffset = Date.now(); + if (performance.timing && performance.timing.navigationStart){ + nowOffset = performance.timing.navigationStart; + } + performance.now = function(){ + return Date.now() - nowOffset; + }; +} + +var step_tmp1 = new Vec3(); + +/** + * Step the physics world forward in time. + * + * There are two modes. The simple mode is fixed timestepping without interpolation. In this case you only use the first argument. The second case uses interpolation. In that you also provide the time since the function was last used, as well as the maximum fixed timesteps to take. + * + * @method step + * @param {Number} dt The fixed time step size to use. + * @param {Number} [timeSinceLastCalled] The time elapsed since the function was last called. + * @param {Number} [maxSubSteps=10] Maximum number of fixed steps to take per function call. + * + * @example + * // fixed timestepping without interpolation + * world.step(1/60); + * + * @see http://bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World + */ +World.prototype.step = function(dt, timeSinceLastCalled, maxSubSteps){ + maxSubSteps = maxSubSteps || 10; + timeSinceLastCalled = timeSinceLastCalled || 0; + + if(timeSinceLastCalled === 0){ // Fixed, simple stepping + + this.internalStep(dt); + + // Increment time + this.time += dt; + + } else { + + // Compute the number of fixed steps we should have taken since the last step + var internalSteps = Math.floor((this.time + timeSinceLastCalled) / dt) - Math.floor(this.time / dt); + internalSteps = Math.min(internalSteps,maxSubSteps); + + // Do some fixed steps to catch up + var t0 = performance.now(); + for(var i=0; i!==internalSteps; i++){ + this.internalStep(dt); + if(performance.now() - t0 > dt * 1000){ + // We are slower than real-time. Better bail out. + break; + } + } + + // Increment internal clock + this.time += timeSinceLastCalled; + + // Compute "Left over" time step + var h = this.time % dt; + var h_div_dt = h / dt; + var interpvelo = step_tmp1; + var bodies = this.bodies; + + for(var j=0; j !== bodies.length; j++){ + var b = bodies[j]; + if(b.type !== Body.STATIC && b.sleepState !== Body.SLEEPING){ + + // Interpolate + b.position.vsub(b.previousPosition, interpvelo); + interpvelo.scale(h_div_dt, interpvelo); + b.position.vadd(interpvelo, b.interpolatedPosition); + + // TODO: interpolate quaternion + // b.interpolatedAngle = b.angle + (b.angle - b.previousAngle) * h_div_dt; + + } else { + + // For static bodies, just copy. Who else will do it? + b.interpolatedPosition.copy(b.position); + b.interpolatedQuaternion.copy(b.quaternion); + } + } + } +}; + +/** + * Step the simulation + * @method step + * @param {Number} dt + */ +var World_step_postStepEvent = {type:"postStep"}, // Reusable event objects to save memory + World_step_preStepEvent = {type:"preStep"}, + World_step_collideEvent = {type:"collide", body:null, contact:null }, + World_step_oldContacts = [], // Pools for unused objects + World_step_frictionEquationPool = [], + World_step_p1 = [], // Reusable arrays for collision pairs + World_step_p2 = [], + World_step_gvec = new Vec3(), // Temporary vectors and quats + World_step_vi = new Vec3(), + World_step_vj = new Vec3(), + World_step_wi = new Vec3(), + World_step_wj = new Vec3(), + World_step_t1 = new Vec3(), + World_step_t2 = new Vec3(), + World_step_rixn = new Vec3(), + World_step_rjxn = new Vec3(), + World_step_step_q = new Quaternion(), + World_step_step_w = new Quaternion(), + World_step_step_wq = new Quaternion(), + invI_tau_dt = new Vec3(); +World.prototype.internalStep = function(dt){ + this.dt = dt; + + var world = this, + that = this, + contacts = this.contacts, + p1 = World_step_p1, + p2 = World_step_p2, + N = this.numObjects(), + bodies = this.bodies, + solver = this.solver, + gravity = this.gravity, + doProfiling = this.doProfiling, + profile = this.profile, + DYNAMIC = Body.DYNAMIC, + profilingStart, + constraints = this.constraints, + frictionEquationPool = World_step_frictionEquationPool, + gnorm = gravity.norm(), + gx = gravity.x, + gy = gravity.y, + gz = gravity.z, + i=0; + + if(doProfiling){ + profilingStart = performance.now(); + } + + // Add gravity to all objects + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi.type & DYNAMIC){ // Only for dynamic bodies + var f = bi.force, m = bi.mass; + f.x += m*gx; + f.y += m*gy; + f.z += m*gz; + } + } + + // Update subsystems + for(var i=0, Nsubsystems=this.subsystems.length; i!==Nsubsystems; i++){ + this.subsystems[i].update(); + } + + // Collision detection + if(doProfiling){ profilingStart = performance.now(); } + p1.length = 0; // Clean up pair arrays from last step + p2.length = 0; + this.broadphase.collisionPairs(this,p1,p2); + if(doProfiling){ profile.broadphase = performance.now() - profilingStart; } + + // Remove constrained pairs with collideConnected == false + var Nconstraints = constraints.length; + for(i=0; i!==Nconstraints; i++){ + var c = constraints[i]; + if(!c.collideConnected){ + for(var j = p1.length-1; j>=0; j-=1){ + if( (c.bodyA === p1[j] && c.bodyB === p2[j]) || + (c.bodyB === p1[j] && c.bodyA === p2[j])){ + p1.splice(j, 1); + p2.splice(j, 1); + } + } + } + } + + this.collisionMatrixTick(); + + // Generate contacts + if(doProfiling){ profilingStart = performance.now(); } + var oldcontacts = World_step_oldContacts; + var NoldContacts = contacts.length; + + for(i=0; i!==NoldContacts; i++){ + oldcontacts.push(contacts[i]); + } + contacts.length = 0; + + // Transfer FrictionEquation from current list to the pool for reuse + var NoldFrictionEquations = this.frictionEquations.length; + for(i=0; i!==NoldFrictionEquations; i++){ + frictionEquationPool.push(this.frictionEquations[i]); + } + this.frictionEquations.length = 0; + + this.narrowphase.getContacts( + p1, + p2, + this, + contacts, + oldcontacts, // To be reused + this.frictionEquations, + frictionEquationPool + ); + + if(doProfiling){ + profile.narrowphase = performance.now() - profilingStart; + } + + // Loop over all collisions + if(doProfiling){ + profilingStart = performance.now(); + } + + // Add all friction eqs + for (var i = 0; i < this.frictionEquations.length; i++) { + solver.addEquation(this.frictionEquations[i]); + } + + var ncontacts = contacts.length; + for(var k=0; k!==ncontacts; k++){ + + // Current contact + var c = contacts[k]; + + // Get current collision indeces + var bi = c.bi, + bj = c.bj, + si = c.si, + sj = c.sj; + + // Get collision properties + var cm; + if(bi.material && bj.material){ + cm = this.getContactMaterial(bi.material,bj.material) || this.defaultContactMaterial; + } else { + cm = this.defaultContactMaterial; + } + + // c.enabled = bi.collisionResponse && bj.collisionResponse && si.collisionResponse && sj.collisionResponse; + + var mu = cm.friction; + // c.restitution = cm.restitution; + + // If friction or restitution were specified in the material, use them + if(bi.material && bj.material){ + if(bi.material.friction >= 0 && bj.material.friction >= 0){ + mu = bi.material.friction * bj.material.friction; + } + + if(bi.material.restitution >= 0 && bj.material.restitution >= 0){ + c.restitution = bi.material.restitution * bj.material.restitution; + } + } + + // c.setSpookParams( + // cm.contactEquationStiffness, + // cm.contactEquationRelaxation, + // dt + // ); + + solver.addEquation(c); + + // // Add friction constraint equation + // if(mu > 0){ + + // // Create 2 tangent equations + // var mug = mu * gnorm; + // var reducedMass = (bi.invMass + bj.invMass); + // if(reducedMass > 0){ + // reducedMass = 1/reducedMass; + // } + // var pool = frictionEquationPool; + // var c1 = pool.length ? pool.pop() : new FrictionEquation(bi,bj,mug*reducedMass); + // var c2 = pool.length ? pool.pop() : new FrictionEquation(bi,bj,mug*reducedMass); + // this.frictionEquations.push(c1, c2); + + // c1.bi = c2.bi = bi; + // c1.bj = c2.bj = bj; + // c1.minForce = c2.minForce = -mug*reducedMass; + // c1.maxForce = c2.maxForce = mug*reducedMass; + + // // Copy over the relative vectors + // c1.ri.copy(c.ri); + // c1.rj.copy(c.rj); + // c2.ri.copy(c.ri); + // c2.rj.copy(c.rj); + + // // Construct tangents + // c.ni.tangents(c1.t, c2.t); + + // // Set spook params + // c1.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, dt); + // c2.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, dt); + + // c1.enabled = c2.enabled = c.enabled; + + // // Add equations to solver + // solver.addEquation(c1); + // solver.addEquation(c2); + // } + + if( bi.allowSleep && + bi.type === Body.DYNAMIC && + bi.sleepState === Body.SLEEPING && + bj.sleepState === Body.AWAKE && + bj.type !== Body.STATIC + ){ + var speedSquaredB = bj.velocity.norm2() + bj.angularVelocity.norm2(); + var speedLimitSquaredB = Math.pow(bj.sleepSpeedLimit,2); + if(speedSquaredB >= speedLimitSquaredB*2){ + bi._wakeUpAfterNarrowphase = true; + } + } + + if( bj.allowSleep && + bj.type === Body.DYNAMIC && + bj.sleepState === Body.SLEEPING && + bi.sleepState === Body.AWAKE && + bi.type !== Body.STATIC + ){ + var speedSquaredA = bi.velocity.norm2() + bi.angularVelocity.norm2(); + var speedLimitSquaredA = Math.pow(bi.sleepSpeedLimit,2); + if(speedSquaredA >= speedLimitSquaredA*2){ + bj._wakeUpAfterNarrowphase = true; + } + } + + // Now we know that i and j are in contact. Set collision matrix state + this.collisionMatrix.set(bi, bj, true); + + if (!this.collisionMatrixPrevious.get(bi, bj)) { + // First contact! + // We reuse the collideEvent object, otherwise we will end up creating new objects for each new contact, even if there's no event listener attached. + World_step_collideEvent.body = bj; + World_step_collideEvent.contact = c; + bi.dispatchEvent(World_step_collideEvent); + + World_step_collideEvent.body = bi; + bj.dispatchEvent(World_step_collideEvent); + } + } + if(doProfiling){ + profile.makeContactConstraints = performance.now() - profilingStart; + profilingStart = performance.now(); + } + + // Wake up bodies + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi._wakeUpAfterNarrowphase){ + bi.wakeUp(); + bi._wakeUpAfterNarrowphase = false; + } + } + + // Add user-added constraints + var Nconstraints = constraints.length; + for(i=0; i!==Nconstraints; i++){ + var c = constraints[i]; + c.update(); + for(var j=0, Neq=c.equations.length; j!==Neq; j++){ + var eq = c.equations[j]; + solver.addEquation(eq); + } + } + + // Solve the constrained system + solver.solve(dt,this); + + if(doProfiling){ + profile.solve = performance.now() - profilingStart; + } + + // Remove all contacts from solver + solver.removeAllEquations(); + + // Apply damping, see http://code.google.com/p/bullet/issues/detail?id=74 for details + var pow = Math.pow; + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi.type & DYNAMIC){ // Only for dynamic bodies + var ld = pow(1.0 - bi.linearDamping,dt); + var v = bi.velocity; + v.mult(ld,v); + var av = bi.angularVelocity; + if(av){ + var ad = pow(1.0 - bi.angularDamping,dt); + av.mult(ad,av); + } + } + } + + this.dispatchEvent(World_step_preStepEvent); + + // Invoke pre-step callbacks + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi.preStep){ + bi.preStep.call(bi); + } + } + + // Leap frog + // vnew = v + h*f/m + // xnew = x + h*vnew + if(doProfiling){ + profilingStart = performance.now(); + } + var q = World_step_step_q; + var w = World_step_step_w; + var wq = World_step_step_wq; + var stepnumber = this.stepnumber; + var DYNAMIC_OR_KINEMATIC = Body.DYNAMIC | Body.KINEMATIC; + var quatNormalize = stepnumber % (this.quatNormalizeSkip+1) === 0; + var quatNormalizeFast = this.quatNormalizeFast; + var half_dt = dt * 0.5; + var PLANE = Shape.types.PLANE, + CONVEX = Shape.types.CONVEXPOLYHEDRON; + + for(i=0; i!==N; i++){ + var b = bodies[i], + force = b.force, + tau = b.torque; + if((b.type & DYNAMIC_OR_KINEMATIC) && b.sleepState !== Body.SLEEPING){ // Only for dynamic + var velo = b.velocity, + angularVelo = b.angularVelocity, + pos = b.position, + quat = b.quaternion, + invMass = b.invMass, + invInertia = b.invInertiaWorld; + + velo.x += force.x * invMass * dt; + velo.y += force.y * invMass * dt; + velo.z += force.z * invMass * dt; + + if(b.angularVelocity){ + invInertia.vmult(tau,invI_tau_dt); + invI_tau_dt.mult(dt,invI_tau_dt); + invI_tau_dt.vadd(angularVelo,angularVelo); + } + + // Use new velocity - leap frog + pos.x += velo.x * dt; + pos.y += velo.y * dt; + pos.z += velo.z * dt; + + if(b.angularVelocity){ + w.set(angularVelo.x, angularVelo.y, angularVelo.z, 0); + w.mult(quat,wq); + quat.x += half_dt * wq.x; + quat.y += half_dt * wq.y; + quat.z += half_dt * wq.z; + quat.w += half_dt * wq.w; + if(quatNormalize){ + if(quatNormalizeFast){ + quat.normalizeFast(); + } else { + quat.normalize(); + } + } + } + + if(b.aabb){ + b.aabbNeedsUpdate = true; + } + + // Update world inertia + if(b.updateInertiaWorld){ + b.updateInertiaWorld(); + } + } + } + this.clearForces(); + + this.broadphase.dirty = true; + + if(doProfiling){ + profile.integrate = performance.now() - profilingStart; + } + + // Update world time + this.time += dt; + this.stepnumber += 1; + + this.dispatchEvent(World_step_postStepEvent); + + // Invoke post-step callbacks + for(i=0; i!==N; i++){ + var bi = bodies[i]; + var postStep = bi.postStep; + if(postStep){ + postStep.call(bi); + } + } + + // Sleeping update + if(this.allowSleep){ + for(i=0; i!==N; i++){ + bodies[i].sleepTick(this.time); + } + } +}; + +/** + * Sets all body forces in the world to zero. + * @method clearForces + */ +World.prototype.clearForces = function(){ + var bodies = this.bodies; + var N = bodies.length; + for(var i=0; i !== N; i++){ + var b = bodies[i], + force = b.force, + tau = b.torque; + + b.force.set(0,0,0); + b.torque.set(0,0,0); + } +}; + +},{"../collision/AABB":3,"../collision/ArrayCollisionMatrix":4,"../collision/NaiveBroadphase":7,"../collision/Ray":9,"../collision/RaycastResult":10,"../equations/ContactEquation":19,"../equations/FrictionEquation":21,"../material/ContactMaterial":24,"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Shape":43,"../solver/GSSolver":46,"../utils/EventTarget":49,"../utils/TupleDictionary":52,"../utils/Vec3Pool":54,"./Narrowphase":55}]},{},[2]) +(2) +}); \ No newline at end of file diff --git a/examples/js/libs/draco/README.md b/examples/js/libs/draco/README.md index 830a7f251ce8fc..6dfa1d3a9b603f 100644 --- a/examples/js/libs/draco/README.md +++ b/examples/js/libs/draco/README.md @@ -20,9 +20,9 @@ Each file is provided in two variations: Either variation may be used with `THREE.DRACOLoader`: ```js -THREE.DRACOLoader.setDecoderPath('path/to/decoders/'); -THREE.DRACOLoader.setDecoderConfig({type: 'js'}); // (Optional) Override detection of WASM support. var dracoLoader = new THREE.DRACOLoader(); +dracoLoader.setDecoderPath('path/to/decoders/'); +dracoLoader.setDecoderConfig({type: 'js'}); // (Optional) Override detection of WASM support. ``` Further [documentation on GitHub](https://github.com/google/draco/tree/master/javascript/example#static-loading-javascript-decoder). diff --git a/examples/js/lights/LightProbeGenerator.js b/examples/js/lights/LightProbeGenerator.js index b958cde7d107c8..8601a29bec6341 100644 --- a/examples/js/lights/LightProbeGenerator.js +++ b/examples/js/lights/LightProbeGenerator.js @@ -50,7 +50,7 @@ THREE.LightProbeGenerator = { color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); // convert to linear color space - color.copySRGBToLinear( color ); + convertColorToLinear( color, cubeTexture.encoding ); // pixel coordinate on unit cube @@ -116,6 +116,128 @@ THREE.LightProbeGenerator = { return new THREE.LightProbe( sh ); + }, + + fromCubeRenderTarget: function ( renderer, cubeRenderTarget ) { + + // The renderTarget must be set to RGBA in order to make readRenderTargetPixels works + var norm, lengthSq, weight, totalWeight = 0; + + var coord = new THREE.Vector3(); + + var dir = new THREE.Vector3(); + + var color = new THREE.Color(); + + var shBasis = [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + + var sh = new THREE.SphericalHarmonics3(); + var shCoefficients = sh.coefficients; + + for ( var faceIndex = 0; faceIndex < 6; faceIndex ++ ) { + + var imageWidth = cubeRenderTarget.width; // assumed to be square + var data = new Uint8Array( imageWidth * imageWidth * 4 ); + renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex ); + + var pixelSize = 2 / imageWidth; + + for ( var i = 0, il = data.length; i < il; i += 4 ) { // RGBA assumed + + // pixel color + color.setRGB( data[ i ] / 255, data[ i + 1 ] / 255, data[ i + 2 ] / 255 ); + + // convert to linear color space + convertColorToLinear( color, cubeRenderTarget.texture.encoding ); + + // pixel coordinate on unit cube + + var pixelIndex = i / 4; + + var col = - 1 + ( pixelIndex % imageWidth + 0.5 ) * pixelSize; + + var row = 1 - ( Math.floor( pixelIndex / imageWidth ) + 0.5 ) * pixelSize; + + switch ( faceIndex ) { + + case 0: coord.set( 1, row, - col ); break; + + case 1: coord.set( - 1, row, col ); break; + + case 2: coord.set( col, 1, - row ); break; + + case 3: coord.set( col, - 1, row ); break; + + case 4: coord.set( col, row, 1 ); break; + + case 5: coord.set( - col, row, - 1 ); break; + + } + + // weight assigned to this pixel + + lengthSq = coord.lengthSq(); + + weight = 4 / ( Math.sqrt( lengthSq ) * lengthSq ); + + totalWeight += weight; + + // direction vector to this pixel + dir.copy( coord ).normalize(); + + // evaluate SH basis functions in direction dir + THREE.SphericalHarmonics3.getBasisAt( dir, shBasis ); + + // accummuulate + for ( var j = 0; j < 9; j ++ ) { + + shCoefficients[ j ].x += shBasis[ j ] * color.r * weight; + shCoefficients[ j ].y += shBasis[ j ] * color.g * weight; + shCoefficients[ j ].z += shBasis[ j ] * color.b * weight; + + } + + } + + } + + // normalize + norm = ( 4 * Math.PI ) / totalWeight; + + for ( var j = 0; j < 9; j ++ ) { + + shCoefficients[ j ].x *= norm; + shCoefficients[ j ].y *= norm; + shCoefficients[ j ].z *= norm; + + } + + return new THREE.LightProbe( sh ); + + } + +}; + +var convertColorToLinear = function ( color, encoding ) { + + switch ( encoding ) { + + case THREE.sRGBEncoding: + + color.convertSRGBToLinear(); + break; + + case THREE.LinearEncoding: + + break; + + default: + + console.warn( 'WARNING: LightProbeGenerator convertColorToLinear() encountered an unsupported encoding.' ); + break; + } + return color; + }; diff --git a/examples/js/lights/RectAreaLightUniformsLib.js b/examples/js/lights/RectAreaLightUniformsLib.js index a7ac5ff3fb6210..d29f48e3a600f4 100644 --- a/examples/js/lights/RectAreaLightUniformsLib.js +++ b/examples/js/lights/RectAreaLightUniformsLib.js @@ -30,12 +30,8 @@ THREE.RectAreaLightUniformsLib = { // data textures var ltc_1 = new THREE.DataTexture( new Float32Array( LTC_MAT_1 ), 64, 64, THREE.RGBAFormat, THREE.FloatType, THREE.UVMapping, THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping, THREE.LinearFilter, THREE.NearestFilter, 1 ); - var ltc_2 = new THREE.DataTexture( new Float32Array( LTC_MAT_2 ), 64, 64, THREE.RGBAFormat, THREE.FloatType, THREE.UVMapping, THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping, THREE.LinearFilter, THREE.NearestFilter, 1 ); - ltc_1.needsUpdate = true; - ltc_2.needsUpdate = true; - THREE.UniformsLib.LTC_1 = ltc_1; THREE.UniformsLib.LTC_2 = ltc_2; diff --git a/examples/js/lines/Line2.js b/examples/js/lines/Line2.js index 222ded4f35a360..28e0445264af82 100644 --- a/examples/js/lines/Line2.js +++ b/examples/js/lines/Line2.js @@ -18,14 +18,6 @@ THREE.Line2.prototype = Object.assign( Object.create( THREE.LineSegments2.protot constructor: THREE.Line2, - isLine2: true, - - copy: function ( /* source */ ) { - - // todo - - return this; - - } + isLine2: true } ); diff --git a/examples/js/lines/LineMaterial.js b/examples/js/lines/LineMaterial.js index 2e0fb2bcb160e1..add875a09c54b9 100644 --- a/examples/js/lines/LineMaterial.js +++ b/examples/js/lines/LineMaterial.js @@ -228,10 +228,10 @@ THREE.ShaderLib[ 'line' ] = { gl_FragColor = vec4( diffuseColor.rgb, diffuseColor.a ); - #include #include #include #include + #include } ` @@ -246,7 +246,9 @@ THREE.LineMaterial = function ( parameters ) { uniforms: THREE.UniformsUtils.clone( THREE.ShaderLib[ 'line' ].uniforms ), vertexShader: THREE.ShaderLib[ 'line' ].vertexShader, - fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader + fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader, + + clipping: true // required for clipping support } ); @@ -373,19 +375,3 @@ THREE.LineMaterial.prototype.constructor = THREE.LineMaterial; THREE.LineMaterial.prototype.isLineMaterial = true; -THREE.LineMaterial.prototype.copy = function ( source ) { - - THREE.ShaderMaterial.prototype.copy.call( this, source ); - - this.color.copy( source.color ); - - this.linewidth = source.linewidth; - - this.resolution = source.resolution; - - // todo - - return this; - -}; - diff --git a/examples/js/lines/LineSegments2.js b/examples/js/lines/LineSegments2.js index 179746f3d1941e..47a0407a9eb9e7 100644 --- a/examples/js/lines/LineSegments2.js +++ b/examples/js/lines/LineSegments2.js @@ -45,8 +45,8 @@ THREE.LineSegments2.prototype = Object.assign( Object.create( THREE.Mesh.prototy var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1 - geometry.addAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0 - geometry.addAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1 + geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0 + geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1 return this; @@ -54,12 +54,144 @@ THREE.LineSegments2.prototype = Object.assign( Object.create( THREE.Mesh.prototy }() ), - copy: function ( /* source */ ) { + raycast: ( function () { - // todo + var start = new THREE.Vector4(); + var end = new THREE.Vector4(); - return this; + var ssOrigin = new THREE.Vector4(); + var ssOrigin3 = new THREE.Vector3(); + var mvMatrix = new THREE.Matrix4(); + var line = new THREE.Line3(); + var closestPoint = new THREE.Vector3(); - } + return function raycast( raycaster, intersects ) { + + if ( raycaster.camera === null ) { + + console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2.' ); + + } + + var ray = raycaster.ray; + var camera = raycaster.camera; + var projectionMatrix = camera.projectionMatrix; + + var geometry = this.geometry; + var material = this.material; + var resolution = material.resolution; + var lineWidth = material.linewidth; + + var instanceStart = geometry.attributes.instanceStart; + var instanceEnd = geometry.attributes.instanceEnd; + + // pick a point 1 unit out along the ray to avoid the ray origin + // sitting at the camera origin which will cause "w" to be 0 when + // applying the projection matrix. + ray.at( 1, ssOrigin ); + + // ndc space [ - 1.0, 1.0 ] + ssOrigin.w = 1; + ssOrigin.applyMatrix4( camera.matrixWorldInverse ); + ssOrigin.applyMatrix4( projectionMatrix ); + ssOrigin.multiplyScalar( 1 / ssOrigin.w ); + + // screen space + ssOrigin.x *= resolution.x / 2; + ssOrigin.y *= resolution.y / 2; + ssOrigin.z = 0; + + ssOrigin3.copy( ssOrigin ); + + var matrixWorld = this.matrixWorld; + mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld ); + + for ( var i = 0, l = instanceStart.count; i < l; i ++ ) { + + start.fromBufferAttribute( instanceStart, i ); + end.fromBufferAttribute( instanceEnd, i ); + + start.w = 1; + end.w = 1; + + // camera space + start.applyMatrix4( mvMatrix ); + end.applyMatrix4( mvMatrix ); + + // clip space + start.applyMatrix4( projectionMatrix ); + end.applyMatrix4( projectionMatrix ); + + // ndc space [ - 1.0, 1.0 ] + start.multiplyScalar( 1 / start.w ); + end.multiplyScalar( 1 / end.w ); + + // skip the segment if it's outside the camera near and far planes + var isBehindCameraNear = start.z < - 1 && end.z < - 1; + var isPastCameraFar = start.z > 1 && end.z > 1; + if ( isBehindCameraNear || isPastCameraFar ) { + + continue; + + } + + // screen space + start.x *= resolution.x / 2; + start.y *= resolution.y / 2; + + end.x *= resolution.x / 2; + end.y *= resolution.y / 2; + + // create 2d segment + line.start.copy( start ); + line.start.z = 0; + + line.end.copy( end ); + line.end.z = 0; + + // get closest point on ray to segment + var param = line.closestPointToPointParameter( ssOrigin3, true ); + line.at( param, closestPoint ); + + // check if the intersection point is within clip space + var zPos = THREE.MathUtils.lerp( start.z, end.z, param ); + var isInClipSpace = zPos >= - 1 && zPos <= 1; + + var isInside = ssOrigin3.distanceTo( closestPoint ) < lineWidth * 0.5; + + if ( isInClipSpace && isInside ) { + + line.start.fromBufferAttribute( instanceStart, i ); + line.end.fromBufferAttribute( instanceEnd, i ); + + line.start.applyMatrix4( matrixWorld ); + line.end.applyMatrix4( matrixWorld ); + + var pointOnLine = new THREE.Vector3(); + var point = new THREE.Vector3(); + + ray.distanceSqToSegment( line.start, line.end, point, pointOnLine ); + + intersects.push( { + + point: point, + pointOnLine: pointOnLine, + distance: ray.origin.distanceTo( point ), + + object: this, + face: null, + faceIndex: i, + uv: null, + uv2: null, + + } ); + + } + + } + + }; + + }() ) } ); diff --git a/examples/js/lines/LineSegmentsGeometry.js b/examples/js/lines/LineSegmentsGeometry.js index b9b05156d29ce0..122fdb3a704f31 100644 --- a/examples/js/lines/LineSegmentsGeometry.js +++ b/examples/js/lines/LineSegmentsGeometry.js @@ -14,8 +14,8 @@ THREE.LineSegmentsGeometry = function () { var index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ]; this.setIndex( index ); - this.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); - this.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + this.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); + this.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); }; @@ -25,16 +25,16 @@ THREE.LineSegmentsGeometry.prototype = Object.assign( Object.create( THREE.Insta isLineSegmentsGeometry: true, - applyMatrix: function ( matrix ) { + applyMatrix4: function ( matrix ) { var start = this.attributes.instanceStart; var end = this.attributes.instanceEnd; if ( start !== undefined ) { - matrix.applyToBufferAttribute( start ); + start.applyMatrix4( matrix ); - matrix.applyToBufferAttribute( end ); + end.applyMatrix4( matrix ); start.data.needsUpdate = true; @@ -72,8 +72,8 @@ THREE.LineSegmentsGeometry.prototype = Object.assign( Object.create( THREE.Insta var instanceBuffer = new THREE.InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz - this.addAttribute( 'instanceStart', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz - this.addAttribute( 'instanceEnd', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz + this.setAttribute( 'instanceStart', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz + this.setAttribute( 'instanceEnd', new THREE.InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz // @@ -100,8 +100,8 @@ THREE.LineSegmentsGeometry.prototype = Object.assign( Object.create( THREE.Insta var instanceColorBuffer = new THREE.InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb - this.addAttribute( 'instanceColorStart', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb - this.addAttribute( 'instanceColorEnd', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb + this.setAttribute( 'instanceColorStart', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb + this.setAttribute( 'instanceColorEnd', new THREE.InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb return this; @@ -241,17 +241,11 @@ THREE.LineSegmentsGeometry.prototype = Object.assign( Object.create( THREE.Insta }, - clone: function () { - - // todo - - }, - - copy: function ( /* source */ ) { + applyMatrix: function ( matrix ) { - // todo + console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' ); - return this; + return this.applyMatrix4( matrix ); } diff --git a/examples/js/lines/Wireframe.js b/examples/js/lines/Wireframe.js index 338757f21d4caa..9661f1d89dd85c 100644 --- a/examples/js/lines/Wireframe.js +++ b/examples/js/lines/Wireframe.js @@ -45,21 +45,13 @@ THREE.Wireframe.prototype = Object.assign( Object.create( THREE.Mesh.prototype ) var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1 - geometry.addAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0 - geometry.addAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1 + geometry.setAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0 + geometry.setAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1 return this; }; - }() ), - - copy: function ( /* source */ ) { - - // todo - - return this; - - } + }() ) } ); diff --git a/examples/js/lines/WireframeGeometry2.js b/examples/js/lines/WireframeGeometry2.js index 8ef7fb17417fd7..cafbb6c665c8ac 100644 --- a/examples/js/lines/WireframeGeometry2.js +++ b/examples/js/lines/WireframeGeometry2.js @@ -19,14 +19,6 @@ THREE.WireframeGeometry2.prototype = Object.assign( Object.create( THREE.LineSeg constructor: THREE.WireframeGeometry2, - isWireframeGeometry2: true, - - copy: function ( /* source */ ) { - - // todo - - return this; - - } + isWireframeGeometry2: true } ); diff --git a/examples/js/loaders/3MFLoader.js b/examples/js/loaders/3MFLoader.js index 7d9caeb4eefe13..d46efc8beacf2f 100644 --- a/examples/js/loaders/3MFLoader.js +++ b/examples/js/loaders/3MFLoader.js @@ -10,18 +10,23 @@ * - Object Resources (Meshes and Components) * - Material Resources (Base Materials) * - * 3MF Materials and Properties Extension (e.g. textures) are not yet supported. + * 3MF Materials and Properties Extension are only partially supported. * + * - Texture 2D + * - Texture 2D Groups + * - Color Groups (Vertex Colors) + * - Metallic Display Properties (PBR) */ THREE.ThreeMFLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + this.availableExtensions = []; }; -THREE.ThreeMFLoader.prototype = { +THREE.ThreeMFLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.ThreeMFLoader, @@ -39,16 +44,10 @@ THREE.ThreeMFLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( data ) { var scope = this; + var textureLoader = new THREE.TextureLoader( this.manager ); function loadDocument( data ) { @@ -56,12 +55,14 @@ THREE.ThreeMFLoader.prototype = { var file = null; var relsName; + var modelRelsName; var modelPartNames = []; var printTicketPartNames = []; var texturesPartNames = []; var otherPartNames = []; var rels; + var modelRels; var modelParts = {}; var printTicketParts = {}; var texturesParts = {}; @@ -88,6 +89,10 @@ THREE.ThreeMFLoader.prototype = { relsName = file; + } else if ( file.match( /3D\/_rels\/.*\.model\.rels$/ ) ) { + + modelRelsName = file; + } else if ( file.match( /^3D\/.*\.model$/ ) ) { modelPartNames.push( file ); @@ -96,7 +101,7 @@ THREE.ThreeMFLoader.prototype = { printTicketPartNames.push( file ); - } else if ( file.match( /^3D\/Textures\/.*/ ) ) { + } else if ( file.match( /^3D\/Textures?\/.*/ ) ) { texturesPartNames.push( file ); @@ -108,10 +113,24 @@ THREE.ThreeMFLoader.prototype = { } + // + var relsView = new Uint8Array( zip.file( relsName ).asArrayBuffer() ); var relsFileText = THREE.LoaderUtils.decodeText( relsView ); rels = parseRelsXml( relsFileText ); + // + + if ( modelRelsName ) { + + var relsView = new Uint8Array( zip.file( modelRelsName ).asArrayBuffer() ); + var relsFileText = THREE.LoaderUtils.decodeText( relsView ); + modelRels = parseRelsXml( relsFileText ); + + } + + // + for ( var i = 0; i < modelPartNames.length; i ++ ) { var modelPart = modelPartNames[ i ]; @@ -153,15 +172,18 @@ THREE.ThreeMFLoader.prototype = { } + // + for ( var i = 0; i < texturesPartNames.length; i ++ ) { var texturesPartName = texturesPartNames[ i ]; - texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asBinary(); + texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asArrayBuffer(); } return { rels: rels, + modelRels: modelRels, model: modelParts, printTicket: printTicketParts, texture: texturesParts, @@ -172,17 +194,27 @@ THREE.ThreeMFLoader.prototype = { function parseRelsXml( relsFileText ) { + var relationships = []; + var relsXmlData = new DOMParser().parseFromString( relsFileText, 'application/xml' ); - var relsNode = relsXmlData.querySelector( 'Relationship' ); - var target = relsNode.getAttribute( 'Target' ); - var id = relsNode.getAttribute( 'Id' ); - var type = relsNode.getAttribute( 'Type' ); - return { - target: target, - id: id, - type: type - }; + var relsNodes = relsXmlData.querySelectorAll( 'Relationship' ); + + for ( var i = 0; i < relsNodes.length; i ++ ) { + + var relsNode = relsNodes[ i ]; + + var relationship = { + target: relsNode.getAttribute( 'Target' ), //required + id: relsNode.getAttribute( 'Id' ), //required + type: relsNode.getAttribute( 'Type' ) //required + }; + + relationships.push( relationship ); + + } + + return relationships; } @@ -230,6 +262,7 @@ THREE.ThreeMFLoader.prototype = { var basematerialNode = basematerialNodes[ i ]; var basematerialData = parseBasematerialNode( basematerialNode ); + basematerialData.index = i; // the order and count of the material nodes form an implicit 0-based index basematerialsData.basematerials.push( basematerialData ); } @@ -238,12 +271,114 @@ THREE.ThreeMFLoader.prototype = { } + function parseTexture2DNode( texture2DNode ) { + + var texture2dData = { + id: texture2DNode.getAttribute( 'id' ), // required + path: texture2DNode.getAttribute( 'path' ), // required + contenttype: texture2DNode.getAttribute( 'contenttype' ), // required + tilestyleu: texture2DNode.getAttribute( 'tilestyleu' ), + tilestylev: texture2DNode.getAttribute( 'tilestylev' ), + filter: texture2DNode.getAttribute( 'filter' ), + }; + + return texture2dData; + + } + + function parseTextures2DGroupNode( texture2DGroupNode ) { + + var texture2DGroupData = { + id: texture2DGroupNode.getAttribute( 'id' ), // required + texid: texture2DGroupNode.getAttribute( 'texid' ), // required + displaypropertiesid: texture2DGroupNode.getAttribute( 'displaypropertiesid' ) + }; + + var tex2coordNodes = texture2DGroupNode.querySelectorAll( 'tex2coord' ); + + var uvs = []; + + for ( var i = 0; i < tex2coordNodes.length; i ++ ) { + + var tex2coordNode = tex2coordNodes[ i ]; + var u = tex2coordNode.getAttribute( 'u' ); + var v = tex2coordNode.getAttribute( 'v' ); + + uvs.push( parseFloat( u ), parseFloat( v ) ); + + } + + texture2DGroupData[ 'uvs' ] = new Float32Array( uvs ); + + return texture2DGroupData; + + } + + function parseColorGroupNode( colorGroupNode ) { + + var colorGroupData = { + id: colorGroupNode.getAttribute( 'id' ), // required + displaypropertiesid: colorGroupNode.getAttribute( 'displaypropertiesid' ) + }; + + var colorNodes = colorGroupNode.querySelectorAll( 'color' ); + + var colors = []; + var colorObject = new THREE.Color(); + + for ( var i = 0; i < colorNodes.length; i ++ ) { + + var colorNode = colorNodes[ i ]; + var color = colorNode.getAttribute( 'color' ); + + colorObject.setStyle( color.substring( 0, 7 ) ); + colorObject.convertSRGBToLinear(); // color is in sRGB + + colors.push( colorObject.r, colorObject.g, colorObject.b ); + + } + + colorGroupData[ 'colors' ] = new Float32Array( colors ); + + return colorGroupData; + + } + + function parseMetallicDisplaypropertiesNode( metallicDisplaypropetiesNode ) { + + var metallicDisplaypropertiesData = { + id: metallicDisplaypropetiesNode.getAttribute( 'id' ) // required + }; + + var metallicNodes = metallicDisplaypropetiesNode.querySelectorAll( 'pbmetallic' ); + + var metallicData = []; + + for ( var i = 0; i < metallicNodes.length; i ++ ) { + + var metallicNode = metallicNodes[ i ]; + + metallicData.push( { + name: metallicNode.getAttribute( 'name' ), // required + metallicness: parseFloat( metallicNode.getAttribute( 'metallicness' ) ), // required + roughness: parseFloat( metallicNode.getAttribute( 'roughness' ) ) // required + } ); + + } + + metallicDisplaypropertiesData.data = metallicData; + + return metallicDisplaypropertiesData; + + } + function parseBasematerialNode( basematerialNode ) { var basematerialData = {}; basematerialData[ 'name' ] = basematerialNode.getAttribute( 'name' ); // required basematerialData[ 'displaycolor' ] = basematerialNode.getAttribute( 'displaycolor' ); // required + basematerialData[ 'displaypropertiesid' ] = basematerialNode.getAttribute( 'displaypropertiesid' ); return basematerialData; @@ -267,13 +402,7 @@ THREE.ThreeMFLoader.prototype = { } - meshData[ 'vertices' ] = new Float32Array( vertices.length ); - - for ( var i = 0; i < vertices.length; i ++ ) { - - meshData[ 'vertices' ][ i ] = vertices[ i ]; - - } + meshData[ 'vertices' ] = new Float32Array( vertices ); var triangleProperties = []; var triangles = []; @@ -290,10 +419,16 @@ THREE.ThreeMFLoader.prototype = { var p3 = triangleNode.getAttribute( 'p3' ); var pid = triangleNode.getAttribute( 'pid' ); - triangles.push( parseInt( v1, 10 ), parseInt( v2, 10 ), parseInt( v3, 10 ) ); - var triangleProperty = {}; + triangleProperty[ 'v1' ] = parseInt( v1, 10 ); + triangleProperty[ 'v2' ] = parseInt( v2, 10 ); + triangleProperty[ 'v3' ] = parseInt( v3, 10 ); + + triangles.push( triangleProperty[ 'v1' ], triangleProperty[ 'v2' ], triangleProperty[ 'v3' ] ); + + // optional + if ( p1 ) { triangleProperty[ 'p1' ] = parseInt( p1, 10 ); @@ -327,13 +462,7 @@ THREE.ThreeMFLoader.prototype = { } meshData[ 'triangleProperties' ] = triangleProperties; - meshData[ 'triangles' ] = new Uint32Array( triangles.length ); - - for ( var i = 0; i < triangles.length; i ++ ) { - - meshData[ 'triangles' ][ i ] = triangles[ i ]; - - } + meshData[ 'triangles' ] = new Uint32Array( triangles ); return meshData; @@ -473,14 +602,72 @@ THREE.ThreeMFLoader.prototype = { function parseResourcesNode( resourcesNode ) { var resourcesData = {}; - var basematerialsNode = resourcesNode.querySelector( 'basematerials' ); - if ( basematerialsNode ) { + resourcesData[ 'basematerials' ] = {}; + var basematerialsNodes = resourcesNode.querySelectorAll( 'basematerials' ); + + for ( var i = 0; i < basematerialsNodes.length; i ++ ) { + + var basematerialsNode = basematerialsNodes[ i ]; + var basematerialsData = parseBasematerialsNode( basematerialsNode ); + resourcesData[ 'basematerials' ][ basematerialsData[ 'id' ] ] = basematerialsData; + + } + + // + + resourcesData[ 'texture2d' ] = {}; + var textures2DNodes = resourcesNode.querySelectorAll( 'texture2d' ); + + for ( var i = 0; i < textures2DNodes.length; i ++ ) { + + var textures2DNode = textures2DNodes[ i ]; + var texture2DData = parseTexture2DNode( textures2DNode ); + resourcesData[ 'texture2d' ][ texture2DData[ 'id' ] ] = texture2DData; + + } + + // + + resourcesData[ 'colorgroup' ] = {}; + var colorGroupNodes = resourcesNode.querySelectorAll( 'colorgroup' ); + + for ( var i = 0; i < colorGroupNodes.length; i ++ ) { + + var colorGroupNode = colorGroupNodes[ i ]; + var colorGroupData = parseColorGroupNode( colorGroupNode ); + resourcesData[ 'colorgroup' ][ colorGroupData[ 'id' ] ] = colorGroupData; + + } + + // + + resourcesData[ 'pbmetallicdisplayproperties' ] = {}; + var pbmetallicdisplaypropertiesNodes = resourcesNode.querySelectorAll( 'pbmetallicdisplayproperties' ); - resourcesData[ 'basematerials' ] = parseBasematerialsNode( basematerialsNode ); + for ( var i = 0; i < pbmetallicdisplaypropertiesNodes.length; i ++ ) { + + var pbmetallicdisplaypropertiesNode = pbmetallicdisplaypropertiesNodes[ i ]; + var pbmetallicdisplaypropertiesData = parseMetallicDisplaypropertiesNode( pbmetallicdisplaypropertiesNode ); + resourcesData[ 'pbmetallicdisplayproperties' ][ pbmetallicdisplaypropertiesData[ 'id' ] ] = pbmetallicdisplaypropertiesData; } + // + + resourcesData[ 'texture2dgroup' ] = {}; + var textures2DGroupNodes = resourcesNode.querySelectorAll( 'texture2dgroup' ); + + for ( var i = 0; i < textures2DGroupNodes.length; i ++ ) { + + var textures2DGroupNode = textures2DGroupNodes[ i ]; + var textures2DGroupData = parseTextures2DGroupNode( textures2DGroupNode ); + resourcesData[ 'texture2dgroup' ][ textures2DGroupData[ 'id' ] ] = textures2DGroupData; + + } + + // + resourcesData[ 'object' ] = {}; var objectNodes = resourcesNode.querySelectorAll( 'object' ); @@ -554,173 +741,426 @@ THREE.ThreeMFLoader.prototype = { } - function buildMesh( meshData, objects, modelData, objectData ) { + function buildTexture( texture2dgroup, objects, modelData, textureData ) { - // geometry + var texid = texture2dgroup.texid; + var texture2ds = modelData.resources.texture2d; + var texture2d = texture2ds[ texid ]; - var geometry = new THREE.BufferGeometry(); - geometry.setIndex( new THREE.BufferAttribute( meshData[ 'triangles' ], 1 ) ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( meshData[ 'vertices' ], 3 ) ); + if ( texture2d ) { - // groups + var data = textureData[ texture2d.path ]; + var type = texture2d.contenttype; - var basematerialsData = modelData[ 'resources' ][ 'basematerials' ]; - var triangleProperties = meshData[ 'triangleProperties' ]; + var blob = new Blob( [ data ], { type: type } ); + var sourceURI = URL.createObjectURL( blob ); + + var texture = textureLoader.load( sourceURI, function () { + + URL.revokeObjectURL( sourceURI ); + + } ); + + texture.encoding = THREE.sRGBEncoding; + + // texture parameters + + switch ( texture2d.tilestyleu ) { + + case 'wrap': + texture.wrapS = THREE.RepeatWrapping; + break; + + case 'mirror': + texture.wrapS = THREE.MirroredRepeatWrapping; + break; + + case 'none': + case 'clamp': + texture.wrapS = THREE.ClampToEdgeWrapping; + break; + + default: + texture.wrapS = THREE.RepeatWrapping; + + } + + switch ( texture2d.tilestylev ) { + + case 'wrap': + texture.wrapT = THREE.RepeatWrapping; + break; + + case 'mirror': + texture.wrapT = THREE.MirroredRepeatWrapping; + break; + + case 'none': + case 'clamp': + texture.wrapT = THREE.ClampToEdgeWrapping; + break; + + default: + texture.wrapT = THREE.RepeatWrapping; + + } - var start = 0; - var count = 0; - var currentMaterialIndex = - 1; + switch ( texture2d.filter ) { + + case 'auto': + texture.magFilter = THREE.LinearFilter; + texture.minFilter = THREE.LinearMipmapLinearFilter; + break; + + case 'linear': + texture.magFilter = THREE.LinearFilter; + texture.minFilter = THREE.LinearFilter; + break; + + case 'nearest': + texture.magFilter = THREE.NearestFilter; + texture.minFilter = THREE.NearestFilter; + break; + + default: + texture.magFilter = THREE.LinearFilter; + texture.minFilter = THREE.LinearMipmapLinearFilter; + + } + + return texture; + + } else { + + return null; + + } + + } + + function buildBasematerialsMeshes( basematerials, triangleProperties, modelData, meshData, textureData, objectData ) { + + var objectPindex = objectData.pindex; + + var materialMap = {}; for ( var i = 0, l = triangleProperties.length; i < l; i ++ ) { var triangleProperty = triangleProperties[ i ]; - var pid = triangleProperty.pid; + var pindex = ( triangleProperty.p1 !== undefined ) ? triangleProperty.p1 : objectPindex; - // only proceed if the triangle refers to a basematerials definition + if ( materialMap[ pindex ] === undefined ) materialMap[ pindex ] = []; - if ( basematerialsData && ( basematerialsData.id === pid ) ) { + materialMap[ pindex ].push( triangleProperty ); - if ( currentMaterialIndex === - 1 ) currentMaterialIndex = triangleProperty.p1; + } - if ( currentMaterialIndex === triangleProperty.p1 ) { + // - count += 3; // primitves per triangle + var keys = Object.keys( materialMap ); + var meshes = []; - } else { + for ( var i = 0, l = keys.length; i < l; i ++ ) { - geometry.addGroup( start, count, currentMaterialIndex ); + var materialIndex = keys[ i ]; + var trianglePropertiesProps = materialMap[ materialIndex ]; + var basematerialData = basematerials.basematerials[ materialIndex ]; + var material = getBuild( basematerialData, objects, modelData, textureData, objectData, buildBasematerial ); - start += count; - count = 3; - currentMaterialIndex = triangleProperty.p1; + // + + var geometry = new THREE.BufferGeometry(); + + var positionData = []; + + var vertices = meshData.vertices; + + for ( var j = 0, jl = trianglePropertiesProps.length; j < jl; j ++ ) { + + var triangleProperty = trianglePropertiesProps[ j ]; + + positionData.push( vertices[ ( triangleProperty.v1 * 3 ) + 0 ] ); + positionData.push( vertices[ ( triangleProperty.v1 * 3 ) + 1 ] ); + positionData.push( vertices[ ( triangleProperty.v1 * 3 ) + 2 ] ); + + positionData.push( vertices[ ( triangleProperty.v2 * 3 ) + 0 ] ); + positionData.push( vertices[ ( triangleProperty.v2 * 3 ) + 1 ] ); + positionData.push( vertices[ ( triangleProperty.v2 * 3 ) + 2 ] ); + + positionData.push( vertices[ ( triangleProperty.v3 * 3 ) + 0 ] ); + positionData.push( vertices[ ( triangleProperty.v3 * 3 ) + 1 ] ); + positionData.push( vertices[ ( triangleProperty.v3 * 3 ) + 2 ] ); - } } + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); + + // + + var mesh = new THREE.Mesh( geometry, material ); + meshes.push( mesh ); + } - if ( geometry.groups.length > 0 ) mergeGroups( geometry ); + return meshes; - geometry.computeBoundingSphere(); + } - // material + function buildTexturedMesh( texture2dgroup, triangleProperties, modelData, meshData, textureData, objectData ) { - var material; + // geometry - // add material if an object-level definition is present + var geometry = new THREE.BufferGeometry(); + + var positionData = []; + var uvData = []; + + var vertices = meshData.vertices; + var uvs = texture2dgroup.uvs; + + for ( var i = 0, l = triangleProperties.length; i < l; i ++ ) { + + var triangleProperty = triangleProperties[ i ]; + + positionData.push( vertices[ ( triangleProperty.v1 * 3 ) + 0 ] ); + positionData.push( vertices[ ( triangleProperty.v1 * 3 ) + 1 ] ); + positionData.push( vertices[ ( triangleProperty.v1 * 3 ) + 2 ] ); + + positionData.push( vertices[ ( triangleProperty.v2 * 3 ) + 0 ] ); + positionData.push( vertices[ ( triangleProperty.v2 * 3 ) + 1 ] ); + positionData.push( vertices[ ( triangleProperty.v2 * 3 ) + 2 ] ); - if ( basematerialsData && ( basematerialsData.id === objectData.pid ) ) { + positionData.push( vertices[ ( triangleProperty.v3 * 3 ) + 0 ] ); + positionData.push( vertices[ ( triangleProperty.v3 * 3 ) + 1 ] ); + positionData.push( vertices[ ( triangleProperty.v3 * 3 ) + 2 ] ); - var materialIndex = objectData.pindex; - var basematerialData = basematerialsData.basematerials[ materialIndex ]; + // - material = getBuild( basematerialData, objects, modelData, objectData, buildBasematerial ); + uvData.push( uvs[ ( triangleProperty.p1 * 2 ) + 0 ] ); + uvData.push( uvs[ ( triangleProperty.p1 * 2 ) + 1 ] ); + + uvData.push( uvs[ ( triangleProperty.p2 * 2 ) + 0 ] ); + uvData.push( uvs[ ( triangleProperty.p2 * 2 ) + 1 ] ); + + uvData.push( uvs[ ( triangleProperty.p3 * 2 ) + 0 ] ); + uvData.push( uvs[ ( triangleProperty.p3 * 2 ) + 1 ] ); } - // add/overwrite material if definitions on triangles are present + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvData, 2 ) ); - if ( geometry.groups.length > 0 ) { + // material - var groups = geometry.groups; - material = []; + var texture = getBuild( texture2dgroup, objects, modelData, textureData, objectData, buildTexture ); - for ( var i = 0, l = groups.length; i < l; i ++ ) { + var material = new THREE.MeshPhongMaterial( { map: texture, flatShading: true } ); - var group = groups[ i ]; - var basematerialData = basematerialsData.basematerials[ group.materialIndex ]; + // mesh - material.push( getBuild( basematerialData, objects, modelData, objectData, buildBasematerial ) ); + var mesh = new THREE.Mesh( geometry, material ); - } + return mesh; + + } + + function buildVertexColorMesh( colorgroup, triangleProperties, modelData, meshData ) { + + // geometry + + var geometry = new THREE.BufferGeometry(); + + var positionData = []; + var colorData = []; + + var vertices = meshData.vertices; + var colors = colorgroup.colors; + + for ( var i = 0, l = triangleProperties.length; i < l; i ++ ) { + + var triangleProperty = triangleProperties[ i ]; + + var v1 = triangleProperty.v1; + var v2 = triangleProperty.v2; + var v3 = triangleProperty.v3; + + positionData.push( vertices[ ( v1 * 3 ) + 0 ] ); + positionData.push( vertices[ ( v1 * 3 ) + 1 ] ); + positionData.push( vertices[ ( v1 * 3 ) + 2 ] ); + + positionData.push( vertices[ ( v2 * 3 ) + 0 ] ); + positionData.push( vertices[ ( v2 * 3 ) + 1 ] ); + positionData.push( vertices[ ( v2 * 3 ) + 2 ] ); + + positionData.push( vertices[ ( v3 * 3 ) + 0 ] ); + positionData.push( vertices[ ( v3 * 3 ) + 1 ] ); + positionData.push( vertices[ ( v3 * 3 ) + 2 ] ); + + // + + var p1 = triangleProperty.p1; + var p2 = triangleProperty.p2; + var p3 = triangleProperty.p3; + + colorData.push( colors[ ( p1 * 3 ) + 0 ] ); + colorData.push( colors[ ( p1 * 3 ) + 1 ] ); + colorData.push( colors[ ( p1 * 3 ) + 2 ] ); + + colorData.push( colors[ ( ( p2 || p1 ) * 3 ) + 0 ] ); + colorData.push( colors[ ( ( p2 || p1 ) * 3 ) + 1 ] ); + colorData.push( colors[ ( ( p2 || p1 ) * 3 ) + 2 ] ); + + colorData.push( colors[ ( ( p3 || p1 ) * 3 ) + 0 ] ); + colorData.push( colors[ ( ( p3 || p1 ) * 3 ) + 1 ] ); + colorData.push( colors[ ( ( p3 || p1 ) * 3 ) + 2 ] ); } - // default material + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positionData, 3 ) ); + geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colorData, 3 ) ); + + // material + + var material = new THREE.MeshPhongMaterial( { vertexColors: true, flatShading: true } ); + + // mesh - if ( material === undefined ) material = new THREE.MeshPhongMaterial( { color: 0xaaaaff, flatShading: true } ); + var mesh = new THREE.Mesh( geometry, material ); - return new THREE.Mesh( geometry, material ); + return mesh; } - function mergeGroups( geometry ) { + function buildDefaultMesh( meshData ) { - // sort by material index + var geometry = new THREE.BufferGeometry(); + geometry.setIndex( new THREE.BufferAttribute( meshData[ 'triangles' ], 1 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( meshData[ 'vertices' ], 3 ) ); - var groups = geometry.groups.sort( function ( a, b ) { + var material = new THREE.MeshPhongMaterial( { color: 0xaaaaff, flatShading: true } ); - if ( a.materialIndex !== b.materialIndex ) return a.materialIndex - b.materialIndex; + var mesh = new THREE.Mesh( geometry, material ); - return a.start - b.start; + return mesh; - } ); + } - // reorganize index buffer + function buildMeshes( resourceMap, modelData, meshData, textureData, objectData ) { - var index = geometry.index; + var keys = Object.keys( resourceMap ); + var meshes = []; - var itemSize = index.itemSize; - var srcArray = index.array; + for ( var i = 0, il = keys.length; i < il; i ++ ) { - var targetOffset = 0; + var resourceId = keys[ i ]; + var triangleProperties = resourceMap[ resourceId ]; + var resourceType = getResourceType( resourceId, modelData ); - var targetArray = new srcArray.constructor( srcArray.length ); + switch ( resourceType ) { - for ( var i = 0; i < groups.length; i ++ ) { + case 'material': + var basematerials = modelData.resources.basematerials[ resourceId ]; + var newMeshes = buildBasematerialsMeshes( basematerials, triangleProperties, modelData, meshData, textureData, objectData ); - var group = groups[ i ]; + for ( var j = 0, jl = newMeshes.length; j < jl; j ++ ) { - var groupLength = group.count * itemSize; - var groupStart = group.start * itemSize; + meshes.push( newMeshes[ j ] ); - var sub = srcArray.subarray( groupStart, groupStart + groupLength ); + } + break; - targetArray.set( sub, targetOffset ); + case 'texture': + var texture2dgroup = modelData.resources.texture2dgroup[ resourceId ]; + meshes.push( buildTexturedMesh( texture2dgroup, triangleProperties, modelData, meshData, textureData, objectData ) ); + break; - targetOffset += groupLength; + case 'vertexColors': + var colorgroup = modelData.resources.colorgroup[ resourceId ]; + meshes.push( buildVertexColorMesh( colorgroup, triangleProperties, modelData, meshData ) ); + break; + + case 'default': + meshes.push( buildDefaultMesh( meshData ) ); + break; + + default: + console.error( 'THREE.3MFLoader: Unsupported resource type.' ); + + } } - srcArray.set( targetArray ); + return meshes; + + } + + function getResourceType( pid, modelData ) { + + if ( modelData.resources.texture2dgroup[ pid ] !== undefined ) { - // update groups + return 'texture'; - var start = 0; + } else if ( modelData.resources.basematerials[ pid ] !== undefined ) { - for ( i = 0; i < groups.length; i ++ ) { + return 'material'; - group = groups[ i ]; + } else if ( modelData.resources.colorgroup[ pid ] !== undefined ) { - group.start = start; - start += group.count; + return 'vertexColors'; + + } else if ( pid === 'default' ) { + + return 'default'; + + } else { + + return undefined; } - // merge groups + } - var lastGroup = groups[ 0 ]; + function analyzeObject( modelData, meshData, objectData ) { - geometry.groups = [ lastGroup ]; + var resourceMap = {}; - for ( i = 1; i < groups.length; i ++ ) { + var triangleProperties = meshData[ 'triangleProperties' ]; - group = groups[ i ]; + var objectPid = objectData.pid; - if ( lastGroup.materialIndex === group.materialIndex ) { + for ( var i = 0, l = triangleProperties.length; i < l; i ++ ) { - lastGroup.count += group.count; + var triangleProperty = triangleProperties[ i ]; + var pid = ( triangleProperty.pid !== undefined ) ? triangleProperty.pid : objectPid; - } else { + if ( pid === undefined ) pid = 'default'; - lastGroup = group; - geometry.groups.push( lastGroup ); + if ( resourceMap[ pid ] === undefined ) resourceMap[ pid ] = []; - } + resourceMap[ pid ].push( triangleProperty ); } + return resourceMap; + + } + + function buildGroup( meshData, objects, modelData, textureData, objectData ) { + + var group = new THREE.Group(); + + var resourceMap = analyzeObject( modelData, meshData, objectData ); + var meshes = buildMeshes( resourceMap, modelData, meshData, textureData, objectData ); + + for ( var i = 0, l = meshes.length; i < l; i ++ ) { + + group.add( meshes[ i ] ); + + } + + return group; + } function applyExtensions( extensions, meshData, modelXml ) { @@ -761,19 +1201,39 @@ THREE.ThreeMFLoader.prototype = { } - function getBuild( data, objects, modelData, objectData, builder ) { + function getBuild( data, objects, modelData, textureData, objectData, builder ) { if ( data.build !== undefined ) return data.build; - data.build = builder( data, objects, modelData, objectData ); + data.build = builder( data, objects, modelData, textureData, objectData ); return data.build; } - function buildBasematerial( materialData ) { + function buildBasematerial( materialData, objects, modelData ) { + + var material; + + var displaypropertiesid = materialData.displaypropertiesid; + var pbmetallicdisplayproperties = modelData.resources.pbmetallicdisplayproperties; - var material = new THREE.MeshPhongMaterial( { flatShading: true } ); + if ( displaypropertiesid !== null && pbmetallicdisplayproperties[ displaypropertiesid ] !== undefined ) { + + // metallic display property, use StandardMaterial + + var pbmetallicdisplayproperty = pbmetallicdisplayproperties[ displaypropertiesid ]; + var metallicData = pbmetallicdisplayproperty.data[ materialData.index ]; + + material = new THREE.MeshStandardMaterial( { flatShading: true, roughness: metallicData.roughness, metalness: metallicData.metallicness } ); + + } else { + + // otherwise use PhongMaterial + + material = new THREE.MeshPhongMaterial( { flatShading: true } ); + + } material.name = materialData.name; @@ -797,7 +1257,7 @@ THREE.ThreeMFLoader.prototype = { } - function buildComposite( compositeData, objects, modelData ) { + function buildComposite( compositeData, objects, modelData, textureData ) { var composite = new THREE.Group(); @@ -808,7 +1268,7 @@ THREE.ThreeMFLoader.prototype = { if ( build === undefined ) { - buildObject( component.objectId, objects, modelData ); + buildObject( component.objectId, objects, modelData, textureData ); build = objects[ component.objectId ]; } @@ -821,7 +1281,7 @@ THREE.ThreeMFLoader.prototype = { if ( transform ) { - object3D.applyMatrix( transform ); + object3D.applyMatrix4( transform ); } @@ -833,7 +1293,7 @@ THREE.ThreeMFLoader.prototype = { } - function buildObject( objectId, objects, modelData ) { + function buildObject( objectId, objects, modelData, textureData ) { var objectData = modelData[ 'resources' ][ 'object' ][ objectId ]; @@ -846,13 +1306,13 @@ THREE.ThreeMFLoader.prototype = { applyExtensions( extensions, meshData, modelXml ); - objects[ objectData.id ] = getBuild( meshData, objects, modelData, objectData, buildMesh ); + objects[ objectData.id ] = getBuild( meshData, objects, modelData, textureData, objectData, buildGroup ); } else { var compositeData = objectData[ 'components' ]; - objects[ objectData.id ] = getBuild( compositeData, objects, modelData, objectData, buildComposite ); + objects[ objectData.id ] = getBuild( compositeData, objects, modelData, textureData, objectData, buildComposite ); } @@ -861,8 +1321,31 @@ THREE.ThreeMFLoader.prototype = { function buildObjects( data3mf ) { var modelsData = data3mf.model; + var modelRels = data3mf.modelRels; var objects = {}; var modelsKeys = Object.keys( modelsData ); + var textureData = {}; + + // evaluate model relationships to textures + + if ( modelRels ) { + + for ( var i = 0, l = modelRels.length; i < l; i ++ ) { + + var modelRel = modelRels[ i ]; + var textureKey = modelRel.target.substring( 1 ); + + if ( data3mf.texture[ textureKey ] ) { + + textureData[ modelRel.target ] = data3mf.texture[ textureKey ]; + + } + + } + + } + + // start build for ( var i = 0; i < modelsKeys.length; i ++ ) { @@ -875,7 +1358,7 @@ THREE.ThreeMFLoader.prototype = { var objectId = objectIds[ j ]; - buildObject( objectId, objects, modelData ); + buildObject( objectId, objects, modelData, textureData ); } @@ -885,10 +1368,12 @@ THREE.ThreeMFLoader.prototype = { } - function build( objects, refs, data3mf ) { + function build( objects, data3mf ) { var group = new THREE.Group(); - var buildData = data3mf.model[ refs[ 'target' ].substring( 1 ) ][ 'build' ]; + + var relationship = data3mf[ 'rels' ][ 0 ]; + var buildData = data3mf.model[ relationship[ 'target' ].substring( 1 ) ][ 'build' ]; for ( var i = 0; i < buildData.length; i ++ ) { @@ -901,7 +1386,7 @@ THREE.ThreeMFLoader.prototype = { if ( transform ) { - object3D.applyMatrix( transform ); + object3D.applyMatrix4( transform ); } @@ -916,7 +1401,7 @@ THREE.ThreeMFLoader.prototype = { var data3mf = loadDocument( data ); var objects = buildObjects( data3mf ); - return build( objects, data3mf[ 'rels' ], data3mf ); + return build( objects, data3mf ); }, @@ -926,4 +1411,4 @@ THREE.ThreeMFLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/AMFLoader.js b/examples/js/loaders/AMFLoader.js index 5ff54107e8222f..49bde2fe8e7d0c 100644 --- a/examples/js/loaders/AMFLoader.js +++ b/examples/js/loaders/AMFLoader.js @@ -20,11 +20,11 @@ THREE.AMFLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.AMFLoader.prototype = { +THREE.AMFLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.AMFLoader, @@ -43,13 +43,6 @@ THREE.AMFLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( data ) { function loadDocument( data ) { @@ -463,11 +456,11 @@ THREE.AMFLoader.prototype = { var material = objDefaultMaterial; newGeometry.setIndex( volume.triangles ); - newGeometry.addAttribute( 'position', vertices.clone() ); + newGeometry.setAttribute( 'position', vertices.clone() ); if ( normals ) { - newGeometry.addAttribute( 'normal', normals.clone() ); + newGeometry.setAttribute( 'normal', normals.clone() ); } @@ -492,4 +485,4 @@ THREE.AMFLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/AWDLoader.js b/examples/js/loaders/AWDLoader.js deleted file mode 100644 index 707491ff5bff15..00000000000000 --- a/examples/js/loaders/AWDLoader.js +++ /dev/null @@ -1,1226 +0,0 @@ -/** - * Author: Pierre Lepers - * Date: 09/12/2013 17:21 - */ - -THREE.AWDLoader = ( function () { - - var //UNCOMPRESSED = 0, - //DEFLATE = 1, - //LZMA = 2, - - AWD_FIELD_INT8 = 1, - AWD_FIELD_INT16 = 2, - AWD_FIELD_INT32 = 3, - AWD_FIELD_UINT8 = 4, - AWD_FIELD_UINT16 = 5, - AWD_FIELD_UINT32 = 6, - AWD_FIELD_FLOAT32 = 7, - AWD_FIELD_FLOAT64 = 8, - AWD_FIELD_BOOL = 21, - //AWD_FIELD_COLOR = 22, - AWD_FIELD_BADDR = 23, - //AWD_FIELD_STRING = 31, - //AWD_FIELD_BYTEARRAY = 32, - AWD_FIELD_VECTOR2x1 = 41, - AWD_FIELD_VECTOR3x1 = 42, - AWD_FIELD_VECTOR4x1 = 43, - AWD_FIELD_MTX3x2 = 44, - AWD_FIELD_MTX3x3 = 45, - AWD_FIELD_MTX4x3 = 46, - AWD_FIELD_MTX4x4 = 47, - - BOOL = 21, - //COLOR = 22, - BADDR = 23, - - //INT8 = 1, - //INT16 = 2, - //INT32 = 3, - UINT8 = 4, - UINT16 = 5, - //UINT32 = 6, - FLOAT32 = 7, - FLOAT64 = 8; - - var littleEndian = true; - - function Block() { - - this.id = 0; - this.data = null; - this.namespace = 0; - this.flags = 0; - - } - - function AWDProperties() {} - - AWDProperties.prototype = { - set: function ( key, value ) { - - this[ key ] = value; - - }, - - get: function ( key, fallback ) { - - if ( this.hasOwnProperty( key ) ) { - - return this[ key ]; - - } else { - - return fallback; - - } - - } - }; - - var AWDLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - - this.trunk = new THREE.Object3D(); - - this.materialFactory = undefined; - - this._url = ''; - this._baseDir = ''; - - this._data = undefined; - this._ptr = 0; - - this._version = []; - this._streaming = false; - this._optimized_for_accuracy = false; - this._compression = 0; - this._bodylen = 0xFFFFFFFF; - - this._blocks = [ new Block() ]; - - this._accuracyMatrix = false; - this._accuracyGeo = false; - this._accuracyProps = false; - - }; - - AWDLoader.prototype = { - - constructor: AWDLoader, - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - this._url = url; - this._baseDir = url.substr( 0, url.lastIndexOf( '/' ) + 1 ); - - var loader = new THREE.FileLoader( this.manager ); - loader.setPath( this.path ); - loader.setResponseType( 'arraybuffer' ); - loader.load( url, function ( text ) { - - onLoad( scope.parse( text ) ); - - }, onProgress, onError ); - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - parse: function ( data ) { - - var blen = data.byteLength; - - this._ptr = 0; - this._data = new DataView( data ); - - this._parseHeader( ); - - if ( this._compression != 0 ) { - - console.error( 'compressed AWD not supported' ); - - } - - if ( ! this._streaming && this._bodylen != data.byteLength - this._ptr ) { - - console.error( 'AWDLoader: body len does not match file length', this._bodylen, blen - this._ptr ); - - } - - while ( this._ptr < blen ) { - - this.parseNextBlock(); - - } - - return this.trunk; - - }, - - parseNextBlock: function () { - - var assetData, - block, - blockId = this.readU32(), - ns = this.readU8(), - type = this.readU8(), - flags = this.readU8(), - len = this.readU32(); - - - switch ( type ) { - - case 1: - assetData = this.parseMeshData(); - break; - - case 22: - assetData = this.parseContainer(); - break; - - case 23: - assetData = this.parseMeshInstance(); - break; - - case 81: - assetData = this.parseMaterial(); - break; - - case 82: - assetData = this.parseTexture(); - break; - - case 101: - assetData = this.parseSkeleton(); - break; - - case 112: - assetData = this.parseMeshPoseAnimation( false ); - break; - - case 113: - assetData = this.parseVertexAnimationSet(); - break; - - case 102: - assetData = this.parseSkeletonPose(); - break; - - case 103: - assetData = this.parseSkeletonAnimation(); - break; - - case 122: - assetData = this.parseAnimatorSet(); - break; - - default: - //debug('Ignoring block!',type, len); - this._ptr += len; - break; - - } - - - // Store block reference for later use - this._blocks[ blockId ] = block = new Block(); - block.data = assetData; - block.id = blockId; - block.namespace = ns; - block.flags = flags; - - - }, - - _parseHeader: function () { - - var version = this._version, - awdmagic = ( this.readU8() << 16 ) | ( this.readU8() << 8 ) | this.readU8(); - - if ( awdmagic != 4282180 ) - throw new Error( "AWDLoader - bad magic" ); - - version[ 0 ] = this.readU8(); - version[ 1 ] = this.readU8(); - - var flags = this.readU16(); - - this._streaming = ( flags & 0x1 ) == 0x1; - - if ( ( version[ 0 ] === 2 ) && ( version[ 1 ] === 1 ) ) { - - this._accuracyMatrix = ( flags & 0x2 ) === 0x2; - this._accuracyGeo = ( flags & 0x4 ) === 0x4; - this._accuracyProps = ( flags & 0x8 ) === 0x8; - - } - - this._geoNrType = this._accuracyGeo ? FLOAT64 : FLOAT32; - this._matrixNrType = this._accuracyMatrix ? FLOAT64 : FLOAT32; - this._propsNrType = this._accuracyProps ? FLOAT64 : FLOAT32; - - this._optimized_for_accuracy = ( flags & 0x2 ) === 0x2; - - this._compression = this.readU8(); - this._bodylen = this.readU32(); - - }, - - parseContainer: function () { - - var parent, - ctr = new THREE.Object3D(), - par_id = this.readU32(), - mtx = this.parseMatrix4(); - - ctr.name = this.readUTF(); - ctr.applyMatrix( mtx ); - - parent = this._blocks[ par_id ].data || this.trunk; - parent.add( ctr ); - - this.parseProperties( { - 1: this._matrixNrType, - 2: this._matrixNrType, - 3: this._matrixNrType, - 4: UINT8 - } ); - - ctr.extra = this.parseUserAttributes(); - - return ctr; - - }, - - parseMeshInstance: function () { - - var name, - mesh, geometries, meshLen, meshes, - par_id, data_id, - mtx, - materials, mat, mat_id, - num_materials, - parent, - i; - - par_id = this.readU32(); - mtx = this.parseMatrix4(); - name = this.readUTF(); - data_id = this.readU32(); - num_materials = this.readU16(); - - geometries = this.getBlock( data_id ); - - materials = []; - - for ( i = 0; i < num_materials; i ++ ) { - - mat_id = this.readU32(); - mat = this.getBlock( mat_id ); - materials.push( mat ); - - } - - meshLen = geometries.length; - meshes = []; - - // TODO : BufferGeometry don't support "geometryGroups" for now. - // so we create sub meshes for each groups - if ( meshLen > 1 ) { - - mesh = new THREE.Object3D(); - for ( i = 0; i < meshLen; i ++ ) { - - var sm = new THREE.Mesh( geometries[ i ] ); - meshes.push( sm ); - mesh.add( sm ); - - } - - } else { - - mesh = new THREE.Mesh( geometries[ 0 ] ); - meshes.push( mesh ); - - } - - mesh.applyMatrix( mtx ); - mesh.name = name; - - - parent = this.getBlock( par_id ) || this.trunk; - parent.add( mesh ); - - - var matLen = materials.length; - var maxLen = Math.max( meshLen, matLen ); - for ( i = 0; i < maxLen; i ++ ) - meshes[ i % meshLen ].material = materials[ i % matLen ]; - - - // Ignore for now - this.parseProperties( null ); - mesh.extra = this.parseUserAttributes(); - - return mesh; - - }, - - parseMaterial: function () { - - var name, - type, - props, - mat, - attributes, - num_methods, - methods_parsed; - - name = this.readUTF(); - type = this.readU8(); - num_methods = this.readU8(); - - //log( "AWDLoader parseMaterial ",name ) - - // Read material numerical properties - // (1=color, 2=bitmap url, 11=alpha_blending, 12=alpha_threshold, 13=repeat) - props = this.parseProperties( { - 1: AWD_FIELD_INT32, - 2: AWD_FIELD_BADDR, - 11: AWD_FIELD_BOOL, - 12: AWD_FIELD_FLOAT32, - 13: AWD_FIELD_BOOL - } ); - - methods_parsed = 0; - - while ( methods_parsed < num_methods ) { - - // read method_type before - this.readU16(); - this.parseProperties( null ); - this.parseUserAttributes(); - - } - - attributes = this.parseUserAttributes(); - - if ( this.materialFactory !== undefined ) { - - mat = this.materialFactory( name ); - if ( mat ) return mat; - - } - - mat = new THREE.MeshPhongMaterial(); - - if ( type === 1 ) { - - // Color material - mat.color.setHex( props.get( 1, 0xcccccc ) ); - - } else if ( type === 2 ) { - - // Bitmap material - var tex_addr = props.get( 2, 0 ); - mat.map = this.getBlock( tex_addr ); - - } - - mat.extra = attributes; - mat.alphaThreshold = props.get( 12, 0.0 ); - mat.repeat = props.get( 13, false ); - - - return mat; - - }, - - parseTexture: function () { - - var name = this.readUTF(), - type = this.readU8(), - asset, - data_len; - - // External - if ( type === 0 ) { - - data_len = this.readU32(); - var url = this.readUTFBytes( data_len ); - console.log( url ); - - asset = this.loadTexture( url ); - asset.userData = {}; - asset.userData.name = name; - - } else { - // embed texture not supported - } - // Ignore for now - this.parseProperties( null ); - - this.parseUserAttributes(); - return asset; - - }, - - loadTexture: function ( url ) { - - var tex = new THREE.Texture(); - - var loader = new THREE.ImageLoader( this.manager ); - - loader.load( this._baseDir + url, function ( image ) { - - tex.image = image; - tex.needsUpdate = true; - - } ); - - return tex; - - }, - - parseSkeleton: function () { - - // Array - // - this.readUTF(); - var num_joints = this.readU16(), - skeleton = [], - joints_parsed = 0; - - this.parseProperties( null ); - - while ( joints_parsed < num_joints ) { - - var joint, ibp; - - // Ignore joint id - this.readU16(); - - joint = new THREE.Bone(); - joint.parent = this.readU16() - 1; // 0=null in AWD - joint.name = this.readUTF(); - - ibp = this.parseMatrix4(); - joint.skinMatrix = ibp; - - // Ignore joint props/attributes for now - this.parseProperties( null ); - this.parseUserAttributes(); - - skeleton.push( joint ); - joints_parsed ++; - - } - - // Discard attributes for now - this.parseUserAttributes(); - - - return skeleton; - - }, - - parseSkeletonPose: function () { - - var name = this.readUTF(); - - var num_joints = this.readU16(); - this.parseProperties( null ); - - // debug( 'parse Skeleton Pose. joints : ' + num_joints); - - var pose = []; - - var joints_parsed = 0; - - while ( joints_parsed < num_joints ) { - - var has_transform; //:uint; - var mtx_data; - - has_transform = this.readU8(); - - if ( has_transform === 1 ) { - - mtx_data = this.parseMatrix4(); - - } else { - - mtx_data = new THREE.Matrix4(); - - } - pose[ joints_parsed ] = mtx_data; - joints_parsed ++; - - } - - // Skip attributes for now - this.parseUserAttributes(); - - return pose; - - }, - - parseSkeletonAnimation: function () { - - var frame_dur; - var pose_addr; - var pose; - - var name = this.readUTF(); - - var clip = []; - - var num_frames = this.readU16(); - this.parseProperties( null ); - - var frames_parsed = 0; - - // debug( 'parse Skeleton Animation. frames : ' + num_frames); - - while ( frames_parsed < num_frames ) { - - pose_addr = this.readU32(); - frame_dur = this.readU16(); - - pose = this._blocks[ pose_addr ].data; - // debug( 'pose address ',pose[2].elements[12],pose[2].elements[13],pose[2].elements[14] ); - clip.push( { - pose: pose, - duration: frame_dur - } ); - - frames_parsed ++; - - } - - if ( clip.length === 0 ) { - - // debug("Could not this SkeletonClipNode, because no Frames where set."); - return; - - } - // Ignore attributes for now - this.parseUserAttributes(); - return clip; - - }, - - parseVertexAnimationSet: function () { - - var poseBlockAdress, - name = this.readUTF(), - num_frames = this.readU16(), - props = this.parseProperties( { 1: UINT16 } ), - frames_parsed = 0, - skeletonFrames = []; - - while ( frames_parsed < num_frames ) { - - poseBlockAdress = this.readU32(); - skeletonFrames.push( this._blocks[ poseBlockAdress ].data ); - frames_parsed ++; - - } - - this.parseUserAttributes(); - - - return skeletonFrames; - - }, - - parseAnimatorSet: function () { - - var animSetBlockAdress; //:int - - var targetAnimationSet; //:AnimationSetBase; - var name = this.readUTF(); - var type = this.readU16(); - - var props = this.parseProperties( { 1: BADDR } ); - - animSetBlockAdress = this.readU32(); - var targetMeshLength = this.readU16(); - - var meshAdresses = []; //:Vector. = new Vector.; - - for ( var i = 0; i < targetMeshLength; i ++ ) - meshAdresses.push( this.readU32() ); - - var activeState = this.readU16(); - var autoplay = Boolean( this.readU8() ); - this.parseUserAttributes(); - this.parseUserAttributes(); - - var targetMeshes = []; //:Vector. = new Vector.; - - for ( i = 0; i < meshAdresses.length; i ++ ) { - - // returnedArray = getAssetByID(meshAdresses[i], [AssetType.MESH]); - // if (returnedArray[0]) - targetMeshes.push( this._blocks[ meshAdresses[ i ] ].data ); - - } - - targetAnimationSet = this._blocks[ animSetBlockAdress ].data; - var thisAnimator; - - if ( type == 1 ) { - - - thisAnimator = { - animationSet: targetAnimationSet, - skeleton: this._blocks[ props.get( 1, 0 ) ].data - }; - - } else if ( type == 2 ) { - // debug( "vertex Anim???"); - } - - - for ( i = 0; i < targetMeshes.length; i ++ ) { - - targetMeshes[ i ].animator = thisAnimator; - - } - // debug("Parsed a Animator: Name = " + name); - - return thisAnimator; - - }, - - parseMeshData: function () { - - var name = this.readUTF(), - num_subs = this.readU16(), - geom, - subs_parsed = 0, - buffer, - geometries = []; - - // Ignore for now - this.parseProperties( { 1: this._geoNrType, 2: this._geoNrType } ); - - // Loop through sub meshes - while ( subs_parsed < num_subs ) { - - var sm_len, sm_end, attrib; - - geom = new THREE.BufferGeometry(); - geom.name = name; - geometries.push( geom ); - - - sm_len = this.readU32(); - sm_end = this._ptr + sm_len; - - - // Ignore for now - this.parseProperties( { 1: this._geoNrType, 2: this._geoNrType } ); - - // Loop through data streams - while ( this._ptr < sm_end ) { - - var idx = 0, - str_type = this.readU8(), - str_ftype = this.readU8(), - str_len = this.readU32(), - str_end = str_len + this._ptr; - - if ( str_type === 1 ) { - - // VERTICES - - buffer = new Float32Array( ( str_len / 12 ) * 3 ); - attrib = new THREE.BufferAttribute( buffer, 3 ); - - geom.addAttribute( 'position', attrib ); - idx = 0; - - while ( this._ptr < str_end ) { - - buffer[ idx ] = - this.readF32(); - buffer[ idx + 1 ] = this.readF32(); - buffer[ idx + 2 ] = this.readF32(); - idx += 3; - - } - - } else if ( str_type === 2 ) { - - // INDICES - - buffer = new Uint16Array( str_len / 2 ); - attrib = new THREE.BufferAttribute( buffer, 1 ); - geom.setIndex( attrib ); - - idx = 0; - - while ( this._ptr < str_end ) { - - buffer[ idx + 1 ] = this.readU16(); - buffer[ idx ] = this.readU16(); - buffer[ idx + 2 ] = this.readU16(); - idx += 3; - - } - - } else if ( str_type === 3 ) { - - // UVS - - buffer = new Float32Array( ( str_len / 8 ) * 2 ); - attrib = new THREE.BufferAttribute( buffer, 2 ); - - geom.addAttribute( 'uv', attrib ); - idx = 0; - - while ( this._ptr < str_end ) { - - buffer[ idx ] = this.readF32(); - buffer[ idx + 1 ] = 1.0 - this.readF32(); - idx += 2; - - } - - } else if ( str_type === 4 ) { - - // NORMALS - - buffer = new Float32Array( ( str_len / 12 ) * 3 ); - attrib = new THREE.BufferAttribute( buffer, 3 ); - geom.addAttribute( 'normal', attrib ); - idx = 0; - - while ( this._ptr < str_end ) { - - buffer[ idx ] = - this.readF32(); - buffer[ idx + 1 ] = this.readF32(); - buffer[ idx + 2 ] = this.readF32(); - idx += 3; - - } - - } else { - - this._ptr = str_end; - - } - - } - - this.parseUserAttributes(); - - geom.computeBoundingSphere(); - subs_parsed ++; - - } - - //geom.computeFaceNormals(); - - this.parseUserAttributes(); - //finalizeAsset(geom, name); - - return geometries; - - }, - - parseMeshPoseAnimation: function ( poseOnly ) { - - var num_frames = 1, - num_submeshes, - frames_parsed, - subMeshParsed, - - str_len, - str_end, - geom, - idx = 0, - clip = {}, - num_Streams, - streamsParsed, - streamtypes = [], - - props, - name = this.readUTF(), - geoAdress = this.readU32(); - - var mesh = this.getBlock( geoAdress ); - - if ( mesh === null ) { - - console.log( "parseMeshPoseAnimation target mesh not found at:", geoAdress ); - return; - - } - - geom = mesh.geometry; - geom.morphTargets = []; - - if ( ! poseOnly ) - num_frames = this.readU16(); - - num_submeshes = this.readU16(); - num_Streams = this.readU16(); - - // debug("VA num_frames : ", num_frames ); - // debug("VA num_submeshes : ", num_submeshes ); - // debug("VA numstreams : ", num_Streams ); - - streamsParsed = 0; - while ( streamsParsed < num_Streams ) { - - streamtypes.push( this.readU16() ); - streamsParsed ++; - - } - props = this.parseProperties( { 1: BOOL, 2: BOOL } ); - - clip.looping = props.get( 1, true ); - clip.stitchFinalFrame = props.get( 2, false ); - - frames_parsed = 0; - - while ( frames_parsed < num_frames ) { - - this.readU16(); - subMeshParsed = 0; - - while ( subMeshParsed < num_submeshes ) { - - streamsParsed = 0; - str_len = this.readU32(); - str_end = this._ptr + str_len; - - while ( streamsParsed < num_Streams ) { - - if ( streamtypes[ streamsParsed ] === 1 ) { - - //geom.addAttribute( 'morphTarget'+frames_parsed, Float32Array, str_len/12, 3 ); - var buffer = new Float32Array( str_len / 4 ); - geom.morphTargets.push( { - array: buffer - } ); - - //buffer = geom.attributes['morphTarget'+frames_parsed].array - idx = 0; - - while ( this._ptr < str_end ) { - - buffer[ idx ] = this.readF32(); - buffer[ idx + 1 ] = this.readF32(); - buffer[ idx + 2 ] = this.readF32(); - idx += 3; - - } - - - subMeshParsed ++; - - } else - this._ptr = str_end; - streamsParsed ++; - - } - - } - - - frames_parsed ++; - - } - - this.parseUserAttributes(); - - return null; - - }, - - getBlock: function ( id ) { - - return this._blocks[ id ].data; - - }, - - parseMatrix4: function () { - - var mtx = new THREE.Matrix4(); - var e = mtx.elements; - - e[ 0 ] = this.readF32(); - e[ 1 ] = this.readF32(); - e[ 2 ] = this.readF32(); - e[ 3 ] = 0.0; - //e[3] = 0.0; - - e[ 4 ] = this.readF32(); - e[ 5 ] = this.readF32(); - e[ 6 ] = this.readF32(); - //e[7] = this.readF32(); - e[ 7 ] = 0.0; - - e[ 8 ] = this.readF32(); - e[ 9 ] = this.readF32(); - e[ 10 ] = this.readF32(); - //e[11] = this.readF32(); - e[ 11 ] = 0.0; - - e[ 12 ] = - this.readF32(); - e[ 13 ] = this.readF32(); - e[ 14 ] = this.readF32(); - //e[15] = this.readF32(); - e[ 15 ] = 1.0; - return mtx; - - }, - - parseProperties: function ( expected ) { - - var list_len = this.readU32(); - var list_end = this._ptr + list_len; - - var props = new AWDProperties(); - - if ( expected ) { - - while ( this._ptr < list_end ) { - - var key = this.readU16(); - var len = this.readU32(); - var type; - - if ( expected.hasOwnProperty( key ) ) { - - type = expected[ key ]; - props.set( key, this.parseAttrValue( type, len ) ); - - } else { - - this._ptr += len; - - } - - } - - } - - return props; - - }, - - parseUserAttributes: function () { - - // skip for now - this._ptr = this.readU32() + this._ptr; - return null; - - }, - - parseAttrValue: function ( type, len ) { - - var elem_len; - var read_func; - - switch ( type ) { - - case AWD_FIELD_INT8: - elem_len = 1; - read_func = this.readI8; - break; - - case AWD_FIELD_INT16: - elem_len = 2; - read_func = this.readI16; - break; - - case AWD_FIELD_INT32: - elem_len = 4; - read_func = this.readI32; - break; - - case AWD_FIELD_BOOL: - case AWD_FIELD_UINT8: - elem_len = 1; - read_func = this.readU8; - break; - - case AWD_FIELD_UINT16: - elem_len = 2; - read_func = this.readU16; - break; - - case AWD_FIELD_UINT32: - case AWD_FIELD_BADDR: - elem_len = 4; - read_func = this.readU32; - break; - - case AWD_FIELD_FLOAT32: - elem_len = 4; - read_func = this.readF32; - break; - - case AWD_FIELD_FLOAT64: - elem_len = 8; - read_func = this.readF64; - break; - - case AWD_FIELD_VECTOR2x1: - case AWD_FIELD_VECTOR3x1: - case AWD_FIELD_VECTOR4x1: - case AWD_FIELD_MTX3x2: - case AWD_FIELD_MTX3x3: - case AWD_FIELD_MTX4x3: - case AWD_FIELD_MTX4x4: - elem_len = 8; - read_func = this.readF64; - break; - - } - - if ( elem_len < len ) { - - var list; - var num_read; - var num_elems; - - list = []; - num_read = 0; - num_elems = len / elem_len; - - while ( num_read < num_elems ) { - - list.push( read_func.call( this ) ); - num_read ++; - - } - - return list; - - } else { - - return read_func.call( this ); - - } - - }, - - readU8: function () { - - return this._data.getUint8( this._ptr ++ ); - - }, - readI8: function () { - - return this._data.getInt8( this._ptr ++ ); - - }, - readU16: function () { - - var a = this._data.getUint16( this._ptr, littleEndian ); - this._ptr += 2; - return a; - - }, - readI16: function () { - - var a = this._data.getInt16( this._ptr, littleEndian ); - this._ptr += 2; - return a; - - }, - readU32: function () { - - var a = this._data.getUint32( this._ptr, littleEndian ); - this._ptr += 4; - return a; - - }, - readI32: function () { - - var a = this._data.getInt32( this._ptr, littleEndian ); - this._ptr += 4; - return a; - - }, - readF32: function () { - - var a = this._data.getFloat32( this._ptr, littleEndian ); - this._ptr += 4; - return a; - - }, - readF64: function () { - - var a = this._data.getFloat64( this._ptr, littleEndian ); - this._ptr += 8; - return a; - - }, - - /** - * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode. - * @param {Array.} bytes UTF-8 byte array. - * @return {string} 16-bit Unicode string. - */ - readUTF: function () { - - var len = this.readU16(); - return this.readUTFBytes( len ); - - }, - - /** - * Converts a UTF-8 byte array to JavaScript's 16-bit Unicode. - * @param {Array.} bytes UTF-8 byte array. - * @return {string} 16-bit Unicode string. - */ - readUTFBytes: function ( len ) { - - // TODO(user): Use native implementations if/when available - var out = [], c = 0; - - while ( out.length < len ) { - - var c1 = this._data.getUint8( this._ptr ++, littleEndian ); - if ( c1 < 128 ) { - - out[ c ++ ] = String.fromCharCode( c1 ); - - } else if ( c1 > 191 && c1 < 224 ) { - - var c2 = this._data.getUint8( this._ptr ++, littleEndian ); - out[ c ++ ] = String.fromCharCode( ( c1 & 31 ) << 6 | c2 & 63 ); - - } else { - - var c2 = this._data.getUint8( this._ptr ++, littleEndian ); - var c3 = this._data.getUint8( this._ptr ++, littleEndian ); - out[ c ++ ] = String.fromCharCode( ( c1 & 15 ) << 12 | ( c2 & 63 ) << 6 | c3 & 63 ); - - } - - } - return out.join( '' ); - - } - - }; - - return AWDLoader; - -} )(); diff --git a/examples/js/loaders/AssimpJSONLoader.js b/examples/js/loaders/AssimpJSONLoader.js deleted file mode 100644 index 7cfb78293b3e34..00000000000000 --- a/examples/js/loaders/AssimpJSONLoader.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * @author Alexander Gessler / http://www.greentoken.de/ - * https://github.com/acgessler - * - * Loader for models imported with Open Asset Import Library (http://assimp.sf.net) - * through assimp2json (https://github.com/acgessler/assimp2json). - * - * Supports any input format that assimp supports, including 3ds, obj, dae, blend, - * fbx, x, ms3d, lwo (and many more). - * - * See webgl_loader_assimp2json example. - */ - -THREE.AssimpJSONLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.AssimpJSONLoader.prototype = { - - constructor: THREE.AssimpJSONLoader, - - crossOrigin: 'anonymous', - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var path = ( scope.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; - - var loader = new THREE.FileLoader( this.manager ); - loader.setPath( scope.path ); - loader.load( url, function ( text ) { - - var json = JSON.parse( text ); - var metadata = json.__metadata__; - - // check if __metadata__ meta header is present - // this header is used to disambiguate between different JSON-based file formats - - if ( typeof metadata !== 'undefined' ) { - - // check if assimp2json at all - - if ( metadata.format !== 'assimp2json' ) { - - onError( 'THREE.AssimpJSONLoader: Not an assimp2json scene.' ); - return; - - // check major format version - - } else if ( metadata.version < 100 && metadata.version >= 200 ) { - - onError( 'THREE.AssimpJSONLoader: Unsupported assimp2json file format version.' ); - return; - - } - - } - - onLoad( scope.parse( json, path ) ); - - }, onProgress, onError ); - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - parse: function ( json, path ) { - - function parseList( json, handler ) { - - var meshes = new Array( json.length ); - - for ( var i = 0; i < json.length; ++ i ) { - - meshes[ i ] = handler.call( this, json[ i ] ); - - } - - return meshes; - - } - - function parseMesh( json ) { - - var geometry = new THREE.BufferGeometry(); - - var i, l, face; - - var indices = []; - - var vertices = json.vertices || []; - var normals = json.normals || []; - var uvs = json.texturecoords || []; - var colors = json.colors || []; - - uvs = uvs[ 0 ] || []; // only support for a single set of uvs - - for ( i = 0, l = json.faces.length; i < l; i ++ ) { - - face = json.faces[ i ]; - indices.push( face[ 0 ], face[ 1 ], face[ 2 ] ); - - } - - geometry.setIndex( indices ); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - - if ( normals.length > 0 ) { - - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - - } - - if ( uvs.length > 0 ) { - - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); - - } - - if ( colors.length > 0 ) { - - geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); - - } - - geometry.computeBoundingSphere(); - - return geometry; - - } - - function parseMaterial( json ) { - - var material = new THREE.MeshPhongMaterial(); - - for ( var i in json.properties ) { - - var property = json.properties[ i ]; - var key = property.key; - var value = property.value; - - switch ( key ) { - - case '$tex.file': { - - var semantic = property.semantic; - - // prop.semantic gives the type of the texture - // 1: diffuse - // 2: specular map - // 4: emissive map - // 5: height map (bumps) - // 6: normal map - // more values (i.e. environment, etc) are known by assimp and may be relevant - - if ( semantic === 1 || semantic === 2 || semantic === 4 || semantic === 5 || semantic === 6 ) { - - var keyname; - - switch ( semantic ) { - - case 1: - keyname = 'map'; - break; - case 2: - keyname = 'specularMap'; - break; - case 4: - keyname = 'emissiveMap'; - break; - case 5: - keyname = 'bumpMap'; - break; - case 6: - keyname = 'normalMap'; - break; - - } - - var texture = textureLoader.load( value ); - - // TODO: read texture settings from assimp. - // Wrapping is the default, though. - - texture.wrapS = texture.wrapT = THREE.RepeatWrapping; - - material[ keyname ] = texture; - - } - - break; - - } - - case '?mat.name': - material.name = value; - break; - - case '$clr.diffuse': - material.color.fromArray( value ); - break; - - case '$clr.specular': - material.specular.fromArray( value ); - break; - - case '$clr.emissive': - material.emissive.fromArray( value ); - break; - - case '$mat.shininess': - material.shininess = value; - break; - - case '$mat.shadingm': - // aiShadingMode_Flat - material.flatShading = ( value === 1 ) ? true : false; - break; - - case '$mat.opacity': - if ( value < 1 ) { - - material.opacity = value; - material.transparent = true; - - } - break; - - } - - } - - return material; - - } - - function parseObject( json, node, meshes, materials ) { - - var obj = new THREE.Object3D(), i, idx; - - obj.name = node.name || ''; - obj.matrix = new THREE.Matrix4().fromArray( node.transformation ).transpose(); - obj.matrix.decompose( obj.position, obj.quaternion, obj.scale ); - - for ( i = 0; node.meshes && i < node.meshes.length; i ++ ) { - - idx = node.meshes[ i ]; - obj.add( new THREE.Mesh( meshes[ idx ], materials[ json.meshes[ idx ].materialindex ] ) ); - - } - - for ( i = 0; node.children && i < node.children.length; i ++ ) { - - obj.add( parseObject( json, node.children[ i ], meshes, materials ) ); - - } - - return obj; - - } - - var textureLoader = new THREE.TextureLoader( this.manager ); - textureLoader.setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); - - var meshes = parseList( json.meshes, parseMesh ); - var materials = parseList( json.materials, parseMaterial ); - return parseObject( json, json.rootnode, meshes, materials ); - - } - -}; diff --git a/examples/js/loaders/AssimpLoader.js b/examples/js/loaders/AssimpLoader.js index 4fef99b1ab4bbe..f131725230d935 100644 --- a/examples/js/loaders/AssimpLoader.js +++ b/examples/js/loaders/AssimpLoader.js @@ -4,21 +4,19 @@ THREE.AssimpLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.AssimpLoader.prototype = { +THREE.AssimpLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.AssimpLoader, - crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { var scope = this; - var path = ( scope.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; + var path = ( scope.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; var loader = new THREE.FileLoader( this.manager ); loader.setPath( scope.path ); @@ -32,27 +30,6 @@ THREE.AssimpLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - parse: function ( buffer, path ) { var textureLoader = new THREE.TextureLoader( this.manager ); @@ -695,19 +672,19 @@ THREE.AssimpLoader.prototype = { else mat = new THREE.MeshLambertMaterial(); geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( this.mIndexArray ), 1 ) ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( this.mVertexBuffer, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( this.mVertexBuffer, 3 ) ); if ( this.mNormalBuffer && this.mNormalBuffer.length > 0 ) - geometry.addAttribute( 'normal', new THREE.BufferAttribute( this.mNormalBuffer, 3 ) ); + geometry.setAttribute( 'normal', new THREE.BufferAttribute( this.mNormalBuffer, 3 ) ); if ( this.mColorBuffer && this.mColorBuffer.length > 0 ) - geometry.addAttribute( 'color', new THREE.BufferAttribute( this.mColorBuffer, 4 ) ); + geometry.setAttribute( 'color', new THREE.BufferAttribute( this.mColorBuffer, 4 ) ); if ( this.mTexCoordsBuffers[ 0 ] && this.mTexCoordsBuffers[ 0 ].length > 0 ) - geometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( this.mTexCoordsBuffers[ 0 ] ), 2 ) ); + geometry.setAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( this.mTexCoordsBuffers[ 0 ] ), 2 ) ); if ( this.mTexCoordsBuffers[ 1 ] && this.mTexCoordsBuffers[ 1 ].length > 0 ) - geometry.addAttribute( 'uv1', new THREE.BufferAttribute( new Float32Array( this.mTexCoordsBuffers[ 1 ] ), 2 ) ); + geometry.setAttribute( 'uv1', new THREE.BufferAttribute( new Float32Array( this.mTexCoordsBuffers[ 1 ] ), 2 ) ); if ( this.mTangentBuffer && this.mTangentBuffer.length > 0 ) - geometry.addAttribute( 'tangents', new THREE.BufferAttribute( this.mTangentBuffer, 3 ) ); + geometry.setAttribute( 'tangents', new THREE.BufferAttribute( this.mTangentBuffer, 3 ) ); if ( this.mBitangentBuffer && this.mBitangentBuffer.length > 0 ) - geometry.addAttribute( 'bitangents', new THREE.BufferAttribute( this.mBitangentBuffer, 3 ) ); + geometry.setAttribute( 'bitangents', new THREE.BufferAttribute( this.mBitangentBuffer, 3 ) ); if ( this.mBones.length > 0 ) { var weights = []; @@ -760,8 +737,8 @@ THREE.AssimpLoader.prototype = { } - geometry.addAttribute( 'skinWeight', new THREE.BufferAttribute( new Float32Array( _weights ), BONESPERVERT ) ); - geometry.addAttribute( 'skinIndex', new THREE.BufferAttribute( new Float32Array( _bones ), BONESPERVERT ) ); + geometry.setAttribute( 'skinWeight', new THREE.BufferAttribute( new Float32Array( _weights ), BONESPERVERT ) ); + geometry.setAttribute( 'skinIndex', new THREE.BufferAttribute( new Float32Array( _bones ), BONESPERVERT ) ); } @@ -2274,4 +2251,4 @@ THREE.AssimpLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/BVHLoader.js b/examples/js/loaders/BVHLoader.js index a0461e2ae04d6d..cc803c5362161a 100644 --- a/examples/js/loaders/BVHLoader.js +++ b/examples/js/loaders/BVHLoader.js @@ -10,14 +10,14 @@ THREE.BVHLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); this.animateBonePositions = true; this.animateBoneRotations = true; }; -THREE.BVHLoader.prototype = { +THREE.BVHLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.BVHLoader, @@ -35,13 +35,6 @@ THREE.BVHLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( text ) { /* @@ -411,4 +404,4 @@ THREE.BVHLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/BabylonLoader.js b/examples/js/loaders/BabylonLoader.js deleted file mode 100644 index 3eee2e88bd88ca..00000000000000 --- a/examples/js/loaders/BabylonLoader.js +++ /dev/null @@ -1,255 +0,0 @@ -/** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ - -THREE.BabylonLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.BabylonLoader.prototype = { - - constructor: THREE.BabylonLoader, - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var loader = new THREE.FileLoader( scope.manager ); - loader.setPath( scope.path ); - loader.load( url, function ( text ) { - - onLoad( scope.parse( JSON.parse( text ) ) ); - - }, onProgress, onError ); - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - parse: function ( json ) { - - function parseMaterials( json ) { - - var materials = {}; - - for ( var i = 0, l = json.materials.length; i < l; i ++ ) { - - var data = json.materials[ i ]; - - var material = new THREE.MeshPhongMaterial(); - material.name = data.name; - material.color.fromArray( data.diffuse ); - material.emissive.fromArray( data.emissive ); - material.specular.fromArray( data.specular ); - material.shininess = data.specularPower; - material.opacity = data.alpha; - - materials[ data.id ] = material; - - } - - if ( json.multiMaterials ) { - - for ( var i = 0, l = json.multiMaterials.length; i < l; i ++ ) { - - var data = json.multiMaterials[ i ]; - - console.warn( 'THREE.BabylonLoader: Multi materials not yet supported.' ); - - materials[ data.id ] = new THREE.MeshPhongMaterial(); - - } - - } - - return materials; - - } - - function parseGeometry( json ) { - - var geometry = new THREE.BufferGeometry(); - - var indices = json.indices; - var positions = json.positions; - var normals = json.normals; - var uvs = json.uvs; - - // indices - - geometry.setIndex( indices ); - - // positions - - for ( var j = 2, jl = positions.length; j < jl; j += 3 ) { - - positions[ j ] = - positions[ j ]; - - } - - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); - - // normals - - if ( normals ) { - - for ( var j = 2, jl = normals.length; j < jl; j += 3 ) { - - normals[ j ] = - normals[ j ]; - - } - - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - - } - - // uvs - - if ( uvs ) { - - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); - - } - - // offsets - - var subMeshes = json.subMeshes; - - if ( subMeshes ) { - - for ( var j = 0, jl = subMeshes.length; j < jl; j ++ ) { - - var subMesh = subMeshes[ j ]; - - geometry.addGroup( subMesh.indexStart, subMesh.indexCount ); - - } - - } - - return geometry; - - } - - function parseObjects( json, materials ) { - - var objects = {}; - var scene = new THREE.Scene(); - - var cameras = json.cameras; - - for ( var i = 0, l = cameras.length; i < l; i ++ ) { - - var data = cameras[ i ]; - - var camera = new THREE.PerspectiveCamera( ( data.fov / Math.PI ) * 180, 1.33, data.minZ, data.maxZ ); - - camera.name = data.name; - camera.position.fromArray( data.position ); - if ( data.rotation ) camera.rotation.fromArray( data.rotation ); - - objects[ data.id ] = camera; - - } - - var lights = json.lights; - - for ( var i = 0, l = lights.length; i < l; i ++ ) { - - var data = lights[ i ]; - - var light; - - switch ( data.type ) { - - case 0: - light = new THREE.PointLight(); - break; - - case 1: - light = new THREE.DirectionalLight(); - break; - - case 2: - light = new THREE.SpotLight(); - break; - - case 3: - light = new THREE.HemisphereLight(); - break; - - } - - light.name = data.name; - if ( data.position ) light.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] ); - light.color.fromArray( data.diffuse ); - if ( data.groundColor ) light.groundColor.fromArray( data.groundColor ); - if ( data.intensity ) light.intensity = data.intensity; - - objects[ data.id ] = light; - - scene.add( light ); - - } - - var meshes = json.meshes; - - for ( var i = 0, l = meshes.length; i < l; i ++ ) { - - var data = meshes[ i ]; - - var object; - - if ( data.indices ) { - - var geometry = parseGeometry( data ); - - object = new THREE.Mesh( geometry, materials[ data.materialId ] ); - - } else { - - object = new THREE.Group(); - - } - - object.name = data.name; - object.position.set( data.position[ 0 ], data.position[ 1 ], - data.position[ 2 ] ); - object.rotation.fromArray( data.rotation ); - if ( data.rotationQuaternion ) object.quaternion.fromArray( data.rotationQuaternion ); - object.scale.fromArray( data.scaling ); - // object.visible = data.isVisible; - - if ( data.parentId ) { - - objects[ data.parentId ].add( object ); - - } else { - - scene.add( object ); - - } - - objects[ data.id ] = object; - - } - - return scene; - - } - - var materials = parseMaterials( json ); - var scene = parseObjects( json, materials ); - - return scene; - - } - -}; diff --git a/examples/js/loaders/BasisTextureLoader.js b/examples/js/loaders/BasisTextureLoader.js index 72b4eb0fcfbc69..41f59f610b37ba 100644 --- a/examples/js/loaders/BasisTextureLoader.js +++ b/examples/js/loaders/BasisTextureLoader.js @@ -4,8 +4,6 @@ * @author Shrek Shao / https://github.com/shrekshao */ -/* global Module, createBasisModule */ - /** * Loader for Basis Universal GPU Texture Codec. * @@ -20,9 +18,7 @@ */ THREE.BasisTextureLoader = function ( manager ) { - this.manager = manager || THREE.DefaultLoadingManager; - - this.crossOrigin = 'anonymous'; + THREE.Loader.call( this, manager ); this.transcoderPath = ''; this.transcoderBinary = null; @@ -34,6 +30,7 @@ THREE.BasisTextureLoader = function ( manager ) { this.workerSourceURL = ''; this.workerConfig = { format: null, + astcSupported: false, etcSupported: false, dxtSupported: false, pvrtcSupported: false, @@ -41,18 +38,10 @@ THREE.BasisTextureLoader = function ( manager ) { }; -THREE.BasisTextureLoader.prototype = { +THREE.BasisTextureLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.BasisTextureLoader, - setCrossOrigin: function ( crossOrigin ) { - - this.crossOrigin = crossOrigin; - - return this; - - }, - setTranscoderPath: function ( path ) { this.transcoderPath = path; @@ -73,22 +62,27 @@ THREE.BasisTextureLoader.prototype = { var config = this.workerConfig; + config.astcSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_astc' ); config.etcSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_etc1' ); config.dxtSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_s3tc' ); config.pvrtcSupported = !! renderer.extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || !! renderer.extensions.get( 'WEBKIT_WEBGL_compressed_texture_pvrtc' ); - if ( config.etcSupported ) { + if ( config.astcSupported ) { - config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFETC1; + config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFASTC_4x4; } else if ( config.dxtSupported ) { - config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFBC1; + config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFBC3; } else if ( config.pvrtcSupported ) { - config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_OPAQUE_ONLY; + config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGBA; + + } else if ( config.etcSupported ) { + + config.format = THREE.BasisTextureLoader.BASIS_FORMAT.cTFETC1; } else { @@ -125,7 +119,9 @@ THREE.BasisTextureLoader.prototype = { var worker; var taskID; - var texturePending = this._getWorker() + var taskCost = buffer.byteLength; + + var texturePending = this._allocateWorker( taskCost ) .then( ( _worker ) => { worker = _worker; @@ -134,8 +130,6 @@ THREE.BasisTextureLoader.prototype = { return new Promise( ( resolve, reject ) => { worker._callbacks[ taskID ] = { resolve, reject }; - worker._taskCosts[ taskID ] = buffer.byteLength; - worker._taskLoad += worker._taskCosts[ taskID ]; worker.postMessage( { type: 'transcode', id: taskID, buffer }, [ buffer ] ); @@ -146,25 +140,30 @@ THREE.BasisTextureLoader.prototype = { var config = this.workerConfig; - var { width, height, mipmaps } = message; + var { width, height, mipmaps, format } = message; var texture; - if ( config.etcSupported ) { - - texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_ETC1_Format ); - - } else if ( config.dxtSupported ) { - - texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.BasisTextureLoader.DXT_FORMAT_MAP[ config.format ], THREE.UnsignedByteType ); - - } else if ( config.pvrtcSupported ) { - - texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_PVRTC_4BPPV1_Format ); - - } else { - - throw new Error( 'THREE.BasisTextureLoader: No supported format available.' ); + switch ( format ) { + + case THREE.BasisTextureLoader.BASIS_FORMAT.cTFASTC_4x4: + texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGBA_ASTC_4x4_Format ); + break; + case THREE.BasisTextureLoader.BASIS_FORMAT.cTFBC1: + case THREE.BasisTextureLoader.BASIS_FORMAT.cTFBC3: + texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.BasisTextureLoader.DXT_FORMAT_MAP[ config.format ], THREE.UnsignedByteType ); + break; + case THREE.BasisTextureLoader.BASIS_FORMAT.cTFETC1: + texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_ETC1_Format ); + break; + case THREE.BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGB: + texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGB_PVRTC_4BPPV1_Format ); + break; + case THREE.BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGBA: + texture = new THREE.CompressedTexture( mipmaps, width, height, THREE.RGBA_PVRTC_4BPPV1_Format ); + break; + default: + throw new Error( 'THREE.BasisTextureLoader: No supported format available.' ); } @@ -182,9 +181,8 @@ THREE.BasisTextureLoader.prototype = { if ( worker && taskID ) { - worker._taskLoad -= worker._taskCosts[ taskID ]; + worker._taskLoad -= taskCost; delete worker._callbacks[ taskID ]; - delete worker._taskCosts[ taskID ]; } @@ -196,7 +194,7 @@ THREE.BasisTextureLoader.prototype = { _initTranscoder: function () { - if ( ! this.transcoderBinary ) { + if ( ! this.transcoderPending ) { // Load transcoder wrapper. var jsLoader = new THREE.FileLoader( this.manager ); @@ -224,12 +222,7 @@ THREE.BasisTextureLoader.prototype = { var body = [ '/* basis_transcoder.js */', - 'var Module;', - 'function createBasisModule () {', - ' ' + jsContent, - ' return Module;', - '}', - '', + jsContent, '/* worker */', fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) ) ].join( '\n' ); @@ -245,7 +238,7 @@ THREE.BasisTextureLoader.prototype = { }, - _getWorker: function () { + _allocateWorker: function ( taskCost ) { return this._initTranscoder().then( () => { @@ -254,7 +247,6 @@ THREE.BasisTextureLoader.prototype = { var worker = new Worker( this.workerSourceURL ); worker._callbacks = {}; - worker._taskCosts = {}; worker._taskLoad = 0; worker.postMessage( { @@ -296,7 +288,11 @@ THREE.BasisTextureLoader.prototype = { } - return this.workerPool[ this.workerPool.length - 1 ]; + var worker = this.workerPool[ this.workerPool.length - 1 ]; + + worker._taskLoad += taskCost; + + return worker; } ); @@ -315,19 +311,29 @@ THREE.BasisTextureLoader.prototype = { return this; } -}; + +} ); /* CONSTANTS */ THREE.BasisTextureLoader.BASIS_FORMAT = { cTFETC1: 0, - cTFBC1: 1, - cTFBC4: 2, - cTFPVRTC1_4_OPAQUE_ONLY: 3, - cTFBC7_M6_OPAQUE_ONLY: 4, - cTFETC2: 5, - cTFBC3: 6, - cTFBC5: 7, + cTFETC2: 1, + cTFBC1: 2, + cTFBC3: 3, + cTFBC4: 4, + cTFBC5: 5, + cTFBC7_M6_OPAQUE_ONLY: 6, + cTFBC7_M5: 7, + cTFPVRTC1_4_RGB: 8, + cTFPVRTC1_4_RGBA: 9, + cTFASTC_4x4: 10, + cTFATC_RGB: 11, + cTFATC_RGBA_INTERPOLATED_ALPHA: 12, + cTFRGBA32: 13, + cTFRGB565: 14, + cTFBGR565: 15, + cTFRGBA4444: 16, }; // DXT formats, from: @@ -368,7 +374,7 @@ THREE.BasisTextureLoader.BasisWorker = function () { try { - var { width, height, mipmaps } = transcode( message.buffer ); + var { width, height, hasAlpha, mipmaps, format } = transcode( message.buffer ); var buffers = []; @@ -378,7 +384,7 @@ THREE.BasisTextureLoader.BasisWorker = function () { } - self.postMessage( { type: 'transcode', id: message.id, width, height, mipmaps }, buffers ); + self.postMessage( { type: 'transcode', id: message.id, width, height, hasAlpha, mipmaps, format }, buffers ); } catch ( error ) { @@ -397,19 +403,15 @@ THREE.BasisTextureLoader.BasisWorker = function () { function init( wasmBinary ) { + var BasisModule; transcoderPending = new Promise( ( resolve ) => { - // The 'Module' global is used by the Basis wrapper, which will check for - // the 'wasmBinary' property before trying to load the file itself. - - // TODO(donmccurdy): This only works with a modified version of the - // emscripten-generated wrapper. The default seems to have a bug making it - // impossible to override the WASM binary. - Module = { wasmBinary, onRuntimeInitialized: resolve }; + BasisModule = { wasmBinary, onRuntimeInitialized: resolve }; + BASIS( BasisModule ); } ).then( () => { - var { BasisFile, initializeBasis } = Module; + var { BasisFile, initializeBasis } = BasisModule; _BasisFile = BasisFile; @@ -417,8 +419,6 @@ THREE.BasisTextureLoader.BasisWorker = function () { } ); - createBasisModule(); - } function transcode( buffer ) { @@ -428,6 +428,7 @@ THREE.BasisTextureLoader.BasisWorker = function () { var width = basisFile.getImageWidth( 0, 0 ); var height = basisFile.getImageHeight( 0, 0 ); var levels = basisFile.getNumLevels( 0 ); + var hasAlpha = basisFile.getHasAlpha(); function cleanup() { @@ -436,6 +437,20 @@ THREE.BasisTextureLoader.BasisWorker = function () { } + if ( ! hasAlpha ) { + + switch ( config.format ) { + + case 9: // Hardcoded: THREE.BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGBA + config.format = 8; // Hardcoded: THREE.BasisTextureLoader.BASIS_FORMAT.cTFPVRTC1_4_RGB; + break; + default: + break; + + } + + } + if ( ! width || ! height || ! levels ) { cleanup(); @@ -450,12 +465,6 @@ THREE.BasisTextureLoader.BasisWorker = function () { } - if ( basisFile.getHasAlpha() ) { - - console.warn( 'THREE.BasisTextureLoader: Alpha not yet implemented.' ); - - } - var mipmaps = []; for ( var mip = 0; mip < levels; mip ++ ) { @@ -469,8 +478,8 @@ THREE.BasisTextureLoader.BasisWorker = function () { 0, mip, config.format, - config.etcSupported ? 0 : ( config.dxtSupported ? 1 : 0 ), - 0 + 0, + hasAlpha ); if ( ! status ) { @@ -486,7 +495,7 @@ THREE.BasisTextureLoader.BasisWorker = function () { cleanup(); - return { width, height, mipmaps }; + return { width, height, hasAlpha, mipmaps, format: config.format }; } diff --git a/examples/js/loaders/ColladaLoader.js b/examples/js/loaders/ColladaLoader.js index f3cb9d442fce36..44d9cdf7415c23 100644 --- a/examples/js/loaders/ColladaLoader.js +++ b/examples/js/loaders/ColladaLoader.js @@ -5,21 +5,19 @@ THREE.ColladaLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.ColladaLoader.prototype = { +THREE.ColladaLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.ColladaLoader, - crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { var scope = this; - var path = ( scope.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; + var path = ( scope.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; var loader = new THREE.FileLoader( scope.manager ); loader.setPath( scope.path ); @@ -31,20 +29,6 @@ THREE.ColladaLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - options: { set convertUpAxis( value ) { @@ -55,13 +39,6 @@ THREE.ColladaLoader.prototype = { }, - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - parse: function ( text, path ) { function getElementsByTagName( xml, name ) { @@ -2409,14 +2386,14 @@ THREE.ColladaLoader.prototype = { // build geometry - if ( position.array.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position.array, position.stride ) ); - if ( normal.array.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) ); - if ( color.array.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color.array, color.stride ) ); - if ( uv.array.length > 0 ) geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv.array, uv.stride ) ); - if ( uv2.array.length > 0 ) geometry.addAttribute( 'uv2', new THREE.Float32BufferAttribute( uv2.array, uv2.stride ) ); + if ( position.array.length > 0 ) geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position.array, position.stride ) ); + if ( normal.array.length > 0 ) geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normal.array, normal.stride ) ); + if ( color.array.length > 0 ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( color.array, color.stride ) ); + if ( uv.array.length > 0 ) geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uv.array, uv.stride ) ); + if ( uv2.array.length > 0 ) geometry.setAttribute( 'uv2', new THREE.Float32BufferAttribute( uv2.array, uv2.stride ) ); - if ( skinIndex.array.length > 0 ) geometry.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( skinIndex.array, skinIndex.stride ) ); - if ( skinWeight.array.length > 0 ) geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeight.array, skinWeight.stride ) ); + if ( skinIndex.array.length > 0 ) geometry.setAttribute( 'skinIndex', new THREE.Float32BufferAttribute( skinIndex.array, skinIndex.stride ) ); + if ( skinWeight.array.length > 0 ) geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeight.array, skinWeight.stride ) ); build.data = geometry; build.type = primitives[ 0 ].type; @@ -2751,7 +2728,7 @@ THREE.ColladaLoader.prototype = { case 'rotate': data.obj = new THREE.Vector3(); data.obj.fromArray( array ); - data.angle = THREE.Math.degToRad( array[ 3 ] ); + data.angle = THREE.MathUtils.degToRad( array[ 3 ] ); break; } @@ -3023,7 +3000,7 @@ THREE.ColladaLoader.prototype = { switch ( joint.type ) { case 'revolute': - matrix.multiply( m0.makeRotationAxis( axis, THREE.Math.degToRad( value ) ) ); + matrix.multiply( m0.makeRotationAxis( axis, THREE.MathUtils.degToRad( value ) ) ); break; case 'prismatic': @@ -3119,7 +3096,7 @@ THREE.ColladaLoader.prototype = { case 'rotate': var array = parseFloats( child.textContent ); var vector = new THREE.Vector3().fromArray( array ); - var angle = THREE.Math.degToRad( array[ 3 ] ); + var angle = THREE.MathUtils.degToRad( array[ 3 ] ); transforms.push( { sid: child.getAttribute( 'sid' ), type: child.nodeName, @@ -3226,7 +3203,7 @@ THREE.ColladaLoader.prototype = { case 'rotate': var array = parseFloats( child.textContent ); - var angle = THREE.Math.degToRad( array[ 3 ] ); + var angle = THREE.MathUtils.degToRad( array[ 3 ] ); data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) ); data.transforms[ child.getAttribute( 'sid' ) ] = child.nodeName; break; @@ -3968,4 +3945,4 @@ THREE.ColladaLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/DDSLoader.js b/examples/js/loaders/DDSLoader.js index 2f60f4b304356f..00f55527539b3f 100644 --- a/examples/js/loaders/DDSLoader.js +++ b/examples/js/loaders/DDSLoader.js @@ -6,267 +6,268 @@ THREE.DDSLoader = function ( manager ) { THREE.CompressedTextureLoader.call( this, manager ); - this._parser = THREE.DDSLoader.parse; - }; -THREE.DDSLoader.prototype = Object.create( THREE.CompressedTextureLoader.prototype ); -THREE.DDSLoader.prototype.constructor = THREE.DDSLoader; +THREE.DDSLoader.prototype = Object.assign( Object.create( THREE.CompressedTextureLoader.prototype ), { -THREE.DDSLoader.parse = function ( buffer, loadMipmaps ) { + constructor: THREE.DDSLoader, - var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 }; + parse: function ( buffer, loadMipmaps ) { - // Adapted from @toji's DDS utils - // https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js + var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 }; - // All values and structures referenced from: - // http://msdn.microsoft.com/en-us/library/bb943991.aspx/ + // Adapted from @toji's DDS utils + // https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js - var DDS_MAGIC = 0x20534444; + // All values and structures referenced from: + // http://msdn.microsoft.com/en-us/library/bb943991.aspx/ - var DDSD_CAPS = 0x1, - DDSD_HEIGHT = 0x2, - DDSD_WIDTH = 0x4, - DDSD_PITCH = 0x8, - DDSD_PIXELFORMAT = 0x1000, - DDSD_MIPMAPCOUNT = 0x20000, - DDSD_LINEARSIZE = 0x80000, - DDSD_DEPTH = 0x800000; + var DDS_MAGIC = 0x20534444; - var DDSCAPS_COMPLEX = 0x8, - DDSCAPS_MIPMAP = 0x400000, - DDSCAPS_TEXTURE = 0x1000; + var DDSD_CAPS = 0x1, + DDSD_HEIGHT = 0x2, + DDSD_WIDTH = 0x4, + DDSD_PITCH = 0x8, + DDSD_PIXELFORMAT = 0x1000, + DDSD_MIPMAPCOUNT = 0x20000, + DDSD_LINEARSIZE = 0x80000, + DDSD_DEPTH = 0x800000; - var DDSCAPS2_CUBEMAP = 0x200, - DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, - DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, - DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, - DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, - DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, - DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, - DDSCAPS2_VOLUME = 0x200000; + var DDSCAPS_COMPLEX = 0x8, + DDSCAPS_MIPMAP = 0x400000, + DDSCAPS_TEXTURE = 0x1000; - var DDPF_ALPHAPIXELS = 0x1, - DDPF_ALPHA = 0x2, - DDPF_FOURCC = 0x4, - DDPF_RGB = 0x40, - DDPF_YUV = 0x200, - DDPF_LUMINANCE = 0x20000; + var DDSCAPS2_CUBEMAP = 0x200, + DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, + DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, + DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, + DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, + DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, + DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, + DDSCAPS2_VOLUME = 0x200000; - function fourCCToInt32( value ) { + var DDPF_ALPHAPIXELS = 0x1, + DDPF_ALPHA = 0x2, + DDPF_FOURCC = 0x4, + DDPF_RGB = 0x40, + DDPF_YUV = 0x200, + DDPF_LUMINANCE = 0x20000; - return value.charCodeAt( 0 ) + - ( value.charCodeAt( 1 ) << 8 ) + - ( value.charCodeAt( 2 ) << 16 ) + - ( value.charCodeAt( 3 ) << 24 ); + function fourCCToInt32( value ) { - } + return value.charCodeAt( 0 ) + + ( value.charCodeAt( 1 ) << 8 ) + + ( value.charCodeAt( 2 ) << 16 ) + + ( value.charCodeAt( 3 ) << 24 ); - function int32ToFourCC( value ) { + } - return String.fromCharCode( - value & 0xff, - ( value >> 8 ) & 0xff, - ( value >> 16 ) & 0xff, - ( value >> 24 ) & 0xff - ); + function int32ToFourCC( value ) { - } + return String.fromCharCode( + value & 0xff, + ( value >> 8 ) & 0xff, + ( value >> 16 ) & 0xff, + ( value >> 24 ) & 0xff + ); - function loadARGBMip( buffer, dataOffset, width, height ) { + } + + function loadARGBMip( buffer, dataOffset, width, height ) { - var dataLength = width * height * 4; - var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength ); - var byteArray = new Uint8Array( dataLength ); - var dst = 0; - var src = 0; - for ( var y = 0; y < height; y ++ ) { + var dataLength = width * height * 4; + var srcBuffer = new Uint8Array( buffer, dataOffset, dataLength ); + var byteArray = new Uint8Array( dataLength ); + var dst = 0; + var src = 0; + for ( var y = 0; y < height; y ++ ) { - for ( var x = 0; x < width; x ++ ) { + for ( var x = 0; x < width; x ++ ) { - var b = srcBuffer[ src ]; src ++; - var g = srcBuffer[ src ]; src ++; - var r = srcBuffer[ src ]; src ++; - var a = srcBuffer[ src ]; src ++; - byteArray[ dst ] = r; dst ++; //r - byteArray[ dst ] = g; dst ++; //g - byteArray[ dst ] = b; dst ++; //b - byteArray[ dst ] = a; dst ++; //a + var b = srcBuffer[ src ]; src ++; + var g = srcBuffer[ src ]; src ++; + var r = srcBuffer[ src ]; src ++; + var a = srcBuffer[ src ]; src ++; + byteArray[ dst ] = r; dst ++; //r + byteArray[ dst ] = g; dst ++; //g + byteArray[ dst ] = b; dst ++; //b + byteArray[ dst ] = a; dst ++; //a + + } } + return byteArray; } - return byteArray; - } + var FOURCC_DXT1 = fourCCToInt32( "DXT1" ); + var FOURCC_DXT3 = fourCCToInt32( "DXT3" ); + var FOURCC_DXT5 = fourCCToInt32( "DXT5" ); + var FOURCC_ETC1 = fourCCToInt32( "ETC1" ); - var FOURCC_DXT1 = fourCCToInt32( "DXT1" ); - var FOURCC_DXT3 = fourCCToInt32( "DXT3" ); - var FOURCC_DXT5 = fourCCToInt32( "DXT5" ); - var FOURCC_ETC1 = fourCCToInt32( "ETC1" ); + var headerLengthInt = 31; // The header length in 32 bit ints - var headerLengthInt = 31; // The header length in 32 bit ints + // Offsets into the header array - // Offsets into the header array + var off_magic = 0; - var off_magic = 0; + var off_size = 1; + var off_flags = 2; + var off_height = 3; + var off_width = 4; - var off_size = 1; - var off_flags = 2; - var off_height = 3; - var off_width = 4; + var off_mipmapCount = 7; - var off_mipmapCount = 7; + var off_pfFlags = 20; + var off_pfFourCC = 21; + var off_RGBBitCount = 22; + var off_RBitMask = 23; + var off_GBitMask = 24; + var off_BBitMask = 25; + var off_ABitMask = 26; - var off_pfFlags = 20; - var off_pfFourCC = 21; - var off_RGBBitCount = 22; - var off_RBitMask = 23; - var off_GBitMask = 24; - var off_BBitMask = 25; - var off_ABitMask = 26; + var off_caps = 27; + var off_caps2 = 28; + var off_caps3 = 29; + var off_caps4 = 30; - var off_caps = 27; - var off_caps2 = 28; - var off_caps3 = 29; - var off_caps4 = 30; + // Parse header - // Parse header + var header = new Int32Array( buffer, 0, headerLengthInt ); - var header = new Int32Array( buffer, 0, headerLengthInt ); + if ( header[ off_magic ] !== DDS_MAGIC ) { - if ( header[ off_magic ] !== DDS_MAGIC ) { + console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' ); + return dds; - console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' ); - return dds; + } - } + if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) { - if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) { + console.error( 'THREE.DDSLoader.parse: Unsupported format, must contain a FourCC code.' ); + return dds; - console.error( 'THREE.DDSLoader.parse: Unsupported format, must contain a FourCC code.' ); - return dds; + } - } + var blockBytes; - var blockBytes; + var fourCC = header[ off_pfFourCC ]; - var fourCC = header[ off_pfFourCC ]; + var isRGBAUncompressed = false; - var isRGBAUncompressed = false; + switch ( fourCC ) { - switch ( fourCC ) { + case FOURCC_DXT1: - case FOURCC_DXT1: + blockBytes = 8; + dds.format = THREE.RGB_S3TC_DXT1_Format; + break; - blockBytes = 8; - dds.format = THREE.RGB_S3TC_DXT1_Format; - break; + case FOURCC_DXT3: - case FOURCC_DXT3: + blockBytes = 16; + dds.format = THREE.RGBA_S3TC_DXT3_Format; + break; - blockBytes = 16; - dds.format = THREE.RGBA_S3TC_DXT3_Format; - break; + case FOURCC_DXT5: - case FOURCC_DXT5: + blockBytes = 16; + dds.format = THREE.RGBA_S3TC_DXT5_Format; + break; - blockBytes = 16; - dds.format = THREE.RGBA_S3TC_DXT5_Format; - break; + case FOURCC_ETC1: - case FOURCC_ETC1: + blockBytes = 8; + dds.format = THREE.RGB_ETC1_Format; + break; - blockBytes = 8; - dds.format = THREE.RGB_ETC1_Format; - break; + default: - default: + if ( header[ off_RGBBitCount ] === 32 + && header[ off_RBitMask ] & 0xff0000 + && header[ off_GBitMask ] & 0xff00 + && header[ off_BBitMask ] & 0xff + && header[ off_ABitMask ] & 0xff000000 ) { - if ( header[ off_RGBBitCount ] === 32 - && header[ off_RBitMask ] & 0xff0000 - && header[ off_GBitMask ] & 0xff00 - && header[ off_BBitMask ] & 0xff - && header[ off_ABitMask ] & 0xff000000 ) { + isRGBAUncompressed = true; + blockBytes = 64; + dds.format = THREE.RGBAFormat; - isRGBAUncompressed = true; - blockBytes = 64; - dds.format = THREE.RGBAFormat; + } else { - } else { + console.error( 'THREE.DDSLoader.parse: Unsupported FourCC code ', int32ToFourCC( fourCC ) ); + return dds; - console.error( 'THREE.DDSLoader.parse: Unsupported FourCC code ', int32ToFourCC( fourCC ) ); - return dds; + } - } + } - } + dds.mipmapCount = 1; - dds.mipmapCount = 1; + if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) { - if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) { + dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] ); - dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] ); + } - } + var caps2 = header[ off_caps2 ]; + dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false; + if ( dds.isCubemap && ( + ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) || + ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) || + ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) || + ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) || + ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) || + ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) + ) ) { - var caps2 = header[ off_caps2 ]; - dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false; - if ( dds.isCubemap && ( - ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) || - ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) || - ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) || - ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) || - ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) || - ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ ) - ) ) { - - console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' ); - return dds; + console.error( 'THREE.DDSLoader.parse: Incomplete cubemap faces' ); + return dds; - } + } - dds.width = header[ off_width ]; - dds.height = header[ off_height ]; + dds.width = header[ off_width ]; + dds.height = header[ off_height ]; - var dataOffset = header[ off_size ] + 4; + var dataOffset = header[ off_size ] + 4; - // Extract mipmaps buffers + // Extract mipmaps buffers - var faces = dds.isCubemap ? 6 : 1; + var faces = dds.isCubemap ? 6 : 1; - for ( var face = 0; face < faces; face ++ ) { + for ( var face = 0; face < faces; face ++ ) { - var width = dds.width; - var height = dds.height; + var width = dds.width; + var height = dds.height; - for ( var i = 0; i < dds.mipmapCount; i ++ ) { + for ( var i = 0; i < dds.mipmapCount; i ++ ) { - if ( isRGBAUncompressed ) { + if ( isRGBAUncompressed ) { - var byteArray = loadARGBMip( buffer, dataOffset, width, height ); - var dataLength = byteArray.length; + var byteArray = loadARGBMip( buffer, dataOffset, width, height ); + var dataLength = byteArray.length; - } else { + } else { - var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes; - var byteArray = new Uint8Array( buffer, dataOffset, dataLength ); + var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes; + var byteArray = new Uint8Array( buffer, dataOffset, dataLength ); - } + } + + var mipmap = { "data": byteArray, "width": width, "height": height }; + dds.mipmaps.push( mipmap ); - var mipmap = { "data": byteArray, "width": width, "height": height }; - dds.mipmaps.push( mipmap ); + dataOffset += dataLength; - dataOffset += dataLength; + width = Math.max( width >> 1, 1 ); + height = Math.max( height >> 1, 1 ); - width = Math.max( width >> 1, 1 ); - height = Math.max( height >> 1, 1 ); + } } - } + return dds; - return dds; + } -}; +} ); diff --git a/examples/js/loaders/DRACOLoader.js b/examples/js/loaders/DRACOLoader.js index 3b6ad5706de9ba..7398ca9f2e878b 100644 --- a/examples/js/loaders/DRACOLoader.js +++ b/examples/js/loaders/DRACOLoader.js @@ -1,723 +1,678 @@ -/** Copyright 2016 The Draco Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /** - * @param {THREE.LoadingManager} manager + * @author Don McCurdy / https://www.donmccurdy.com */ + THREE.DRACOLoader = function ( manager ) { - this.timeLoaded = 0; - this.manager = manager || THREE.DefaultLoadingManager; - this.materials = null; - this.verbosity = 0; - this.attributeOptions = {}; - this.drawMode = THREE.TrianglesDrawMode; - // Native Draco attribute type to Three.JS attribute type. - this.nativeAttributeMap = { - position: "POSITION", - normal: "NORMAL", - color: "COLOR", - uv: "TEX_COORD" + THREE.Loader.call( this, manager ); + + this.decoderPath = ''; + this.decoderConfig = {}; + this.decoderBinary = null; + this.decoderPending = null; + + this.workerLimit = 4; + this.workerPool = []; + this.workerNextTaskID = 1; + this.workerSourceURL = ''; + + this.defaultAttributeIDs = { + position: 'POSITION', + normal: 'NORMAL', + color: 'COLOR', + uv: 'TEX_COORD' + }; + this.defaultAttributeTypes = { + position: 'Float32Array', + normal: 'Float32Array', + color: 'Float32Array', + uv: 'Float32Array' }; }; -THREE.DRACOLoader.prototype = { - constructor: THREE.DRACOLoader, +THREE.DRACOLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { - load: function ( url, onLoad, onProgress, onError ) { + constructor: THREE.DRACOLoader, - var scope = this; - var loader = new THREE.FileLoader( scope.manager ); - loader.setPath( this.path ); - loader.setResponseType( "arraybuffer" ); - loader.load( - url, - function ( blob ) { + setDecoderPath: function ( path ) { - scope.decodeDracoFile( blob, onLoad ); + this.decoderPath = path; - }, - onProgress, - onError - ); + return this; }, - setPath: function ( value ) { + setDecoderConfig: function ( config ) { + + this.decoderConfig = config; - this.path = value; return this; }, - setVerbosity: function ( level ) { + setWorkerLimit: function ( workerLimit ) { + + this.workerLimit = workerLimit; - this.verbosity = level; return this; }, - /** - * Sets desired mode for generated geometry indices. - * Can be either: - * THREE.TrianglesDrawMode - * THREE.TriangleStripDrawMode - */ - setDrawMode: function ( drawMode ) { + /** @deprecated */ + setVerbosity: function () { - this.drawMode = drawMode; - return this; + console.warn( 'THREE.DRACOLoader: The .setVerbosity() method has been removed.' ); }, - /** - * Skips dequantization for a specific attribute. - * |attributeName| is the THREE.js name of the given attribute type. - * The only currently supported |attributeName| is 'position', more may be - * added in future. - */ - setSkipDequantization: function ( attributeName, skip ) { - - var skipDequantization = true; - if ( typeof skip !== "undefined" ) skipDequantization = skip; - this.getAttributeOptions( - attributeName - ).skipDequantization = skipDequantization; - return this; + /** @deprecated */ + setDrawMode: function () { + + console.warn( 'THREE.DRACOLoader: The .setDrawMode() method has been removed.' ); }, - /** - * Decompresses a Draco buffer. Names of attributes (for ID and type maps) - * must be one of the supported three.js types, including: position, color, - * normal, uv, uv2, skinIndex, skinWeight. - * - * @param {ArrayBuffer} rawBuffer - * @param {Function} callback - * @param {Object|undefined} attributeUniqueIdMap Provides a pre-defined ID - * for each attribute in the geometry to be decoded. If given, - * `attributeTypeMap` is required and `nativeAttributeMap` will be - * ignored. - * @param {Object|undefined} attributeTypeMap Provides a predefined data - * type (as a typed array constructor) for each attribute in the - * geometry to be decoded. - */ - decodeDracoFile: function ( - rawBuffer, - callback, - attributeUniqueIdMap, - attributeTypeMap - ) { - - var scope = this; - THREE.DRACOLoader.getDecoderModule().then( function ( module ) { - - scope.decodeDracoFileInternal( - rawBuffer, - module.decoder, - callback, - attributeUniqueIdMap, - attributeTypeMap - ); + /** @deprecated */ + setSkipDequantization: function () { - } ); + console.warn( 'THREE.DRACOLoader: The .setSkipDequantization() method has been removed.' ); }, - decodeDracoFileInternal: function ( - rawBuffer, - dracoDecoder, - callback, - attributeUniqueIdMap, - attributeTypeMap - ) { + load: function ( url, onLoad, onProgress, onError ) { - /* - * Here is how to use Draco Javascript decoder and get the geometry. - */ - var buffer = new dracoDecoder.DecoderBuffer(); - buffer.Init( new Int8Array( rawBuffer ), rawBuffer.byteLength ); - var decoder = new dracoDecoder.Decoder(); + var loader = new THREE.FileLoader( this.manager ); - /* - * Determine what type is this file: mesh or point cloud. - */ - var geometryType = decoder.GetEncodedGeometryType( buffer ); - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { + loader.setPath( this.path ); + loader.setResponseType( 'arraybuffer' ); - if ( this.verbosity > 0 ) { + if ( this.crossOrigin === 'use-credentials' ) { - console.log( "Loaded a mesh." ); + loader.setWithCredentials( true ); - } + } - } else if ( geometryType == dracoDecoder.POINT_CLOUD ) { + loader.load( url, ( buffer ) => { - if ( this.verbosity > 0 ) { + var taskConfig = { + attributeIDs: this.defaultAttributeIDs, + attributeTypes: this.defaultAttributeTypes, + useUniqueIDs: false + }; - console.log( "Loaded a point cloud." ); + this.decodeGeometry( buffer, taskConfig ) + .then( onLoad ) + .catch( onError ); - } + }, onProgress, onError ); - } else { + }, - var errorMsg = "THREE.DRACOLoader: Unknown geometry type."; - console.error( errorMsg ); - throw new Error( errorMsg ); + /** @deprecated Kept for backward-compatibility with previous DRACOLoader versions. */ + decodeDracoFile: function ( buffer, callback, attributeIDs, attributeTypes ) { - } - callback( - this.convertDracoGeometryTo3JS( - dracoDecoder, - decoder, - geometryType, - buffer, - attributeUniqueIdMap, - attributeTypeMap - ) - ); + var taskConfig = { + attributeIDs: attributeIDs || this.defaultAttributeIDs, + attributeTypes: attributeTypes || this.defaultAttributeTypes, + useUniqueIDs: !! attributeIDs + }; + + this.decodeGeometry( buffer, taskConfig ).then( callback ); }, - addAttributeToGeometry: function ( - dracoDecoder, - decoder, - dracoGeometry, - attributeName, - attributeType, - attribute, - geometry, - geometryBuffer - ) { + decodeGeometry: function ( buffer, taskConfig ) { + + // TODO: For backward-compatibility, support 'attributeTypes' objects containing + // references (rather than names) to typed array constructors. These must be + // serialized before sending them to the worker. + for ( var attribute in taskConfig.attributeTypes ) { - if ( attribute.ptr === 0 ) { + var type = taskConfig.attributeTypes[ attribute ]; - var errorMsg = "THREE.DRACOLoader: No attribute " + attributeName; - console.error( errorMsg ); - throw new Error( errorMsg ); + if ( type.BYTES_PER_ELEMENT !== undefined ) { + + taskConfig.attributeTypes[ attribute ] = type.name; + + } } - var numComponents = attribute.num_components(); - var numPoints = dracoGeometry.num_points(); - var numValues = numPoints * numComponents; - var attributeData; - var TypedBufferAttribute; + // - switch ( attributeType ) { + var taskKey = JSON.stringify( taskConfig ); - case Float32Array: - attributeData = new dracoDecoder.DracoFloat32Array(); - decoder.GetAttributeFloatForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Float32Array( numValues ); - TypedBufferAttribute = THREE.Float32BufferAttribute; - break; + // Check for an existing task using this buffer. A transferred buffer cannot be transferred + // again from this thread. + if ( THREE.DRACOLoader.taskCache.has( buffer ) ) { - case Int8Array: - attributeData = new dracoDecoder.DracoInt8Array(); - decoder.GetAttributeInt8ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Int8Array( numValues ); - TypedBufferAttribute = THREE.Int8BufferAttribute; - break; + var cachedTask = THREE.DRACOLoader.taskCache.get( buffer ); - case Int16Array: - attributeData = new dracoDecoder.DracoInt16Array(); - decoder.GetAttributeInt16ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Int16Array( numValues ); - TypedBufferAttribute = THREE.Int16BufferAttribute; - break; + if ( cachedTask.key === taskKey ) { - case Int32Array: - attributeData = new dracoDecoder.DracoInt32Array(); - decoder.GetAttributeInt32ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Int32Array( numValues ); - TypedBufferAttribute = THREE.Int32BufferAttribute; - break; + return cachedTask.promise; - case Uint8Array: - attributeData = new dracoDecoder.DracoUInt8Array(); - decoder.GetAttributeUInt8ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Uint8Array( numValues ); - TypedBufferAttribute = THREE.Uint8BufferAttribute; - break; + } else if ( buffer.byteLength === 0 ) { - case Uint16Array: - attributeData = new dracoDecoder.DracoUInt16Array(); - decoder.GetAttributeUInt16ForAllPoints( - dracoGeometry, - attribute, - attributeData - ); - geometryBuffer[ attributeName ] = new Uint16Array( numValues ); - TypedBufferAttribute = THREE.Uint16BufferAttribute; - break; + // Technically, it would be possible to wait for the previous task to complete, + // transfer the buffer back, and decode again with the second configuration. That + // is complex, and I don't know of any reason to decode a Draco buffer twice in + // different ways, so this is left unimplemented. + throw new Error( + + 'THREE.DRACOLoader: Unable to re-decode a buffer with different ' + + 'settings. Buffer has already been transferred.' - case Uint32Array: - attributeData = new dracoDecoder.DracoUInt32Array(); - decoder.GetAttributeUInt32ForAllPoints( - dracoGeometry, - attribute, - attributeData ); - geometryBuffer[ attributeName ] = new Uint32Array( numValues ); - TypedBufferAttribute = THREE.Uint32BufferAttribute; - break; - default: - var errorMsg = "THREE.DRACOLoader: Unexpected attribute type."; - console.error( errorMsg ); - throw new Error( errorMsg ); + } } - // Copy data from decoder. - for ( var i = 0; i < numValues; i ++ ) { + // - geometryBuffer[ attributeName ][ i ] = attributeData.GetValue( i ); + var worker; + var taskID = this.workerNextTaskID ++; + var taskCost = buffer.byteLength; - } - // Add attribute to THREEJS geometry for rendering. - geometry.addAttribute( - attributeName, - new TypedBufferAttribute( geometryBuffer[ attributeName ], numComponents ) - ); - dracoDecoder.destroy( attributeData ); + // Obtain a worker and assign a task, and construct a geometry instance + // when the task completes. + var geometryPending = this._getWorker( taskID, taskCost ) + .then( ( _worker ) => { + + worker = _worker; + + return new Promise( ( resolve, reject ) => { + + worker._callbacks[ taskID ] = { resolve, reject }; + + worker.postMessage( { type: 'decode', id: taskID, taskConfig, buffer }, [ buffer ] ); + + // this.debug(); + + } ); + + } ) + .then( ( message ) => this._createGeometry( message.geometry ) ); + + // Remove task from the task list. + geometryPending + .finally( () => { + + if ( worker && taskID ) { + + this._releaseTask( worker, taskID ); + + // this.debug(); + + } + + } ); + + // Cache the task result. + THREE.DRACOLoader.taskCache.set( buffer, { + + key: taskKey, + promise: geometryPending + + } ); + + return geometryPending; }, - convertDracoGeometryTo3JS: function ( - dracoDecoder, - decoder, - geometryType, - buffer, - attributeUniqueIdMap, - attributeTypeMap - ) { + _createGeometry: function ( geometryData ) { - // TODO: Should not assume native Draco attribute IDs apply. - if ( this.getAttributeOptions( "position" ).skipDequantization === true ) { + var geometry = new THREE.BufferGeometry(); + + if ( geometryData.index ) { - decoder.SkipAttributeTransform( dracoDecoder.POSITION ); + geometry.setIndex( new THREE.BufferAttribute( geometryData.index.array, 1 ) ); } - var dracoGeometry; - var decodingStatus; - var start_time = performance.now(); - if ( geometryType === dracoDecoder.TRIANGULAR_MESH ) { - dracoGeometry = new dracoDecoder.Mesh(); - decodingStatus = decoder.DecodeBufferToMesh( buffer, dracoGeometry ); + for ( var i = 0; i < geometryData.attributes.length; i ++ ) { - } else { + var attribute = geometryData.attributes[ i ]; + var name = attribute.name; + var array = attribute.array; + var itemSize = attribute.itemSize; - dracoGeometry = new dracoDecoder.PointCloud(); - decodingStatus = decoder.DecodeBufferToPointCloud( buffer, dracoGeometry ); + geometry.setAttribute( name, new THREE.BufferAttribute( array, itemSize ) ); } - if ( ! decodingStatus.ok() || dracoGeometry.ptr == 0 ) { - var errorMsg = "THREE.DRACOLoader: Decoding failed: "; - errorMsg += decodingStatus.error_msg(); - console.error( errorMsg ); - dracoDecoder.destroy( decoder ); - dracoDecoder.destroy( dracoGeometry ); - throw new Error( errorMsg ); + return geometry; - } + }, - var decode_end = performance.now(); - dracoDecoder.destroy( buffer ); - /* - * Example on how to retrieve mesh and attributes. - */ - var numFaces; - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { + _loadLibrary: function ( url, responseType ) { - numFaces = dracoGeometry.num_faces(); - if ( this.verbosity > 0 ) { + var loader = new THREE.FileLoader( this.manager ); + loader.setPath( this.decoderPath ); + loader.setResponseType( responseType ); - console.log( "Number of faces loaded: " + numFaces.toString() ); + return new Promise( ( resolve, reject ) => { - } + loader.load( url, resolve, undefined, reject ); + + } ); + + }, + + preload: function () { + + this._initDecoder(); + + return this; + + }, + + _initDecoder: function () { + + if ( this.decoderPending ) return this.decoderPending; + + var useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js'; + var librariesPending = []; + + if ( useJS ) { + + librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) ); } else { - numFaces = 0; + librariesPending.push( this._loadLibrary( 'draco_wasm_wrapper.js', 'text' ) ); + librariesPending.push( this._loadLibrary( 'draco_decoder.wasm', 'arraybuffer' ) ); } - var numPoints = dracoGeometry.num_points(); - var numAttributes = dracoGeometry.num_attributes(); - if ( this.verbosity > 0 ) { + this.decoderPending = Promise.all( librariesPending ) + .then( ( libraries ) => { - console.log( "Number of points loaded: " + numPoints.toString() ); - console.log( "Number of attributes loaded: " + numAttributes.toString() ); + var jsContent = libraries[ 0 ]; - } + if ( ! useJS ) { - // Verify if there is position attribute. - // TODO: Should not assume native Draco attribute IDs apply. - var posAttId = decoder.GetAttributeId( dracoGeometry, dracoDecoder.POSITION ); - if ( posAttId == - 1 ) { + this.decoderConfig.wasmBinary = libraries[ 1 ]; - var errorMsg = "THREE.DRACOLoader: No position attribute found."; - console.error( errorMsg ); - dracoDecoder.destroy( decoder ); - dracoDecoder.destroy( dracoGeometry ); - throw new Error( errorMsg ); + } - } - var posAttribute = decoder.GetAttribute( dracoGeometry, posAttId ); + var fn = THREE.DRACOLoader.DRACOWorker.toString(); - // Structure for converting to THREEJS geometry later. - var geometryBuffer = {}; - // Import data to Three JS geometry. - var geometry = new THREE.BufferGeometry(); + var body = [ + '/* draco decoder */', + jsContent, + '', + '/* worker */', + fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) ) + ].join( '\n' ); - // Do not use both the native attribute map and a provided (e.g. glTF) map. - if ( attributeUniqueIdMap ) { + this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) ); - // Add attributes of user specified unique id. E.g. GLTF models. - for ( var attributeName in attributeUniqueIdMap ) { + } ); - var attributeType = attributeTypeMap[ attributeName ]; - var attributeId = attributeUniqueIdMap[ attributeName ]; - var attribute = decoder.GetAttributeByUniqueId( - dracoGeometry, - attributeId - ); - this.addAttributeToGeometry( - dracoDecoder, - decoder, - dracoGeometry, - attributeName, - attributeType, - attribute, - geometry, - geometryBuffer - ); + return this.decoderPending; - } + }, - } else { + _getWorker: function ( taskID, taskCost ) { - // Add native Draco attribute type to geometry. - for ( var attributeName in this.nativeAttributeMap ) { + return this._initDecoder().then( () => { - var attId = decoder.GetAttributeId( - dracoGeometry, - dracoDecoder[ this.nativeAttributeMap[ attributeName ] ] - ); - if ( attId !== - 1 ) { + if ( this.workerPool.length < this.workerLimit ) { + + var worker = new Worker( this.workerSourceURL ); + + worker._callbacks = {}; + worker._taskCosts = {}; + worker._taskLoad = 0; + + worker.postMessage( { type: 'init', decoderConfig: this.decoderConfig } ); + + worker.onmessage = function ( e ) { - if ( this.verbosity > 0 ) { + var message = e.data; - console.log( "Loaded " + attributeName + " attribute." ); + switch ( message.type ) { + + case 'decode': + worker._callbacks[ message.id ].resolve( message ); + break; + + case 'error': + worker._callbacks[ message.id ].reject( message ); + break; + + default: + console.error( 'THREE.DRACOLoader: Unexpected message, "' + message.type + '"' ); } - var attribute = decoder.GetAttribute( dracoGeometry, attId ); - this.addAttributeToGeometry( - dracoDecoder, - decoder, - dracoGeometry, - attributeName, - Float32Array, - attribute, - geometry, - geometryBuffer - ); - } + }; + + this.workerPool.push( worker ); + + } else { + + this.workerPool.sort( function ( a, b ) { + + return a._taskLoad > b._taskLoad ? - 1 : 1; + + } ); } + var worker = this.workerPool[ this.workerPool.length - 1 ]; + worker._taskCosts[ taskID ] = taskCost; + worker._taskLoad += taskCost; + return worker; + + } ); + + }, + + _releaseTask: function ( worker, taskID ) { + + worker._taskLoad -= worker._taskCosts[ taskID ]; + delete worker._callbacks[ taskID ]; + delete worker._taskCosts[ taskID ]; + + }, + + debug: function () { + + console.log( 'Task load: ', this.workerPool.map( ( worker ) => worker._taskLoad ) ); + + }, + + dispose: function () { + + for ( var i = 0; i < this.workerPool.length; ++ i ) { + + this.workerPool[ i ].terminate(); + } - // For mesh, we need to generate the faces. - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { + this.workerPool.length = 0; - if ( this.drawMode === THREE.TriangleStripDrawMode ) { + return this; - var stripsArray = new dracoDecoder.DracoInt32Array(); - decoder.GetTriangleStripsFromMesh( - dracoGeometry, - stripsArray - ); - geometryBuffer.indices = new Uint32Array( stripsArray.size() ); - for ( var i = 0; i < stripsArray.size(); ++ i ) { + } - geometryBuffer.indices[ i ] = stripsArray.GetValue( i ); +} ); - } - dracoDecoder.destroy( stripsArray ); +/* WEB WORKER */ - } else { +THREE.DRACOLoader.DRACOWorker = function () { - var numIndices = numFaces * 3; - geometryBuffer.indices = new Uint32Array( numIndices ); - var ia = new dracoDecoder.DracoInt32Array(); - for ( var i = 0; i < numFaces; ++ i ) { + var decoderConfig; + var decoderPending; - decoder.GetFaceFromMesh( dracoGeometry, i, ia ); - var index = i * 3; - geometryBuffer.indices[ index ] = ia.GetValue( 0 ); - geometryBuffer.indices[ index + 1 ] = ia.GetValue( 1 ); - geometryBuffer.indices[ index + 2 ] = ia.GetValue( 2 ); + onmessage = function ( e ) { - } - dracoDecoder.destroy( ia ); + var message = e.data; - } + switch ( message.type ) { + + case 'init': + decoderConfig = message.decoderConfig; + decoderPending = new Promise( function ( resolve/*, reject*/ ) { + + decoderConfig.onModuleLoaded = function ( draco ) { + + // Module is Promise-like. Wrap before resolving to avoid loop. + resolve( { draco: draco } ); + + }; + + DracoDecoderModule( decoderConfig ); + + } ); + break; + + case 'decode': + var buffer = message.buffer; + var taskConfig = message.taskConfig; + decoderPending.then( ( module ) => { + + var draco = module.draco; + var decoder = new draco.Decoder(); + var decoderBuffer = new draco.DecoderBuffer(); + decoderBuffer.Init( new Int8Array( buffer ), buffer.byteLength ); + + try { + + var geometry = decodeGeometry( draco, decoder, decoderBuffer, taskConfig ); + + var buffers = geometry.attributes.map( ( attr ) => attr.array.buffer ); + + if ( geometry.index ) buffers.push( geometry.index.array.buffer ); + + self.postMessage( { type: 'decode', id: message.id, geometry }, buffers ); + + } catch ( error ) { + + console.error( error ); + + self.postMessage( { type: 'error', id: message.id, error: error.message } ); + + } finally { + + draco.destroy( decoderBuffer ); + draco.destroy( decoder ); + + } + + } ); + break; } - geometry.drawMode = this.drawMode; - if ( geometryType == dracoDecoder.TRIANGULAR_MESH ) { + }; + + function decodeGeometry( draco, decoder, decoderBuffer, taskConfig ) { + + var attributeIDs = taskConfig.attributeIDs; + var attributeTypes = taskConfig.attributeTypes; + + var dracoGeometry; + var decodingStatus; + + var geometryType = decoder.GetEncodedGeometryType( decoderBuffer ); + + if ( geometryType === draco.TRIANGULAR_MESH ) { + + dracoGeometry = new draco.Mesh(); + decodingStatus = decoder.DecodeBufferToMesh( decoderBuffer, dracoGeometry ); - geometry.setIndex( - new ( geometryBuffer.indices.length > 65535 - ? THREE.Uint32BufferAttribute - : THREE.Uint16BufferAttribute )( geometryBuffer.indices, 1 ) - ); + } else if ( geometryType === draco.POINT_CLOUD ) { + + dracoGeometry = new draco.PointCloud(); + decodingStatus = decoder.DecodeBufferToPointCloud( decoderBuffer, dracoGeometry ); + + } else { + + throw new Error( 'THREE.DRACOLoader: Unexpected geometry type.' ); } - // TODO: Should not assume native Draco attribute IDs apply. - // TODO: Can other attribute types be quantized? - var posTransform = new dracoDecoder.AttributeQuantizationTransform(); - if ( posTransform.InitFromAttribute( posAttribute ) ) { - - // Quantized attribute. Store the quantization parameters into the - // THREE.js attribute. - geometry.attributes[ "position" ].isQuantized = true; - geometry.attributes[ "position" ].maxRange = posTransform.range(); - geometry.attributes[ - "position" - ].numQuantizationBits = posTransform.quantization_bits(); - geometry.attributes[ "position" ].minValues = new Float32Array( 3 ); - for ( var i = 0; i < 3; ++ i ) { - - geometry.attributes[ "position" ].minValues[ i ] = posTransform.min_value( - i - ); + if ( ! decodingStatus.ok() || dracoGeometry.ptr === 0 ) { - } + throw new Error( 'THREE.DRACOLoader: Decoding failed: ' + decodingStatus.error_msg() ); } - dracoDecoder.destroy( posTransform ); - dracoDecoder.destroy( decoder ); - dracoDecoder.destroy( dracoGeometry ); - this.decode_time = decode_end - start_time; - this.import_time = performance.now() - decode_end; + var geometry = { index: null, attributes: [] }; - if ( this.verbosity > 0 ) { + // Gather all vertex attributes. + for ( var attributeName in attributeIDs ) { - console.log( "Decode time: " + this.decode_time ); - console.log( "Import time: " + this.import_time ); + var attributeType = self[ attributeTypes[ attributeName ] ]; - } - return geometry; + var attribute; + var attributeID; - }, + // A Draco file may be created with default vertex attributes, whose attribute IDs + // are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively, + // a Draco file may contain a custom set of attributes, identified by known unique + // IDs. glTF files always do the latter, and `.drc` files typically do the former. + if ( taskConfig.useUniqueIDs ) { - isVersionSupported: function ( version, callback ) { + attributeID = attributeIDs[ attributeName ]; + attribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeID ); - THREE.DRACOLoader.getDecoderModule().then( function ( module ) { + } else { - callback( module.decoder.isVersionSupported( version ) ); + attributeID = decoder.GetAttributeId( dracoGeometry, draco[ attributeIDs[ attributeName ] ] ); - } ); + if ( attributeID === - 1 ) continue; - }, + attribute = decoder.GetAttribute( dracoGeometry, attributeID ); - getAttributeOptions: function ( attributeName ) { + } - if ( typeof this.attributeOptions[ attributeName ] === "undefined" ) - this.attributeOptions[ attributeName ] = {}; - return this.attributeOptions[ attributeName ]; + geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) ); - } -}; + } -THREE.DRACOLoader.decoderPath = "./"; -THREE.DRACOLoader.decoderConfig = {}; -THREE.DRACOLoader.decoderModulePromise = null; + // Add index. + if ( geometryType === draco.TRIANGULAR_MESH ) { -/** - * Sets the base path for decoder source files. - * @param {string} path - */ -THREE.DRACOLoader.setDecoderPath = function ( path ) { + // Generate mesh faces. + var numFaces = dracoGeometry.num_faces(); + var numIndices = numFaces * 3; + var index = new Uint32Array( numIndices ); + var indexArray = new draco.DracoInt32Array(); - THREE.DRACOLoader.decoderPath = path; + for ( var i = 0; i < numFaces; ++ i ) { -}; + decoder.GetFaceFromMesh( dracoGeometry, i, indexArray ); -/** - * Sets decoder configuration and releases singleton decoder module. Module - * will be recreated with the next decoding call. - * @param {Object} config - */ -THREE.DRACOLoader.setDecoderConfig = function ( config ) { + for ( var j = 0; j < 3; ++ j ) { - var wasmBinary = THREE.DRACOLoader.decoderConfig.wasmBinary; - THREE.DRACOLoader.decoderConfig = config || {}; - THREE.DRACOLoader.releaseDecoderModule(); + index[ i * 3 + j ] = indexArray.GetValue( j ); - // Reuse WASM binary. - if ( wasmBinary ) THREE.DRACOLoader.decoderConfig.wasmBinary = wasmBinary; + } -}; + } -/** - * Releases the singleton DracoDecoderModule instance. Module will be recreated - * with the next decoding call. - */ -THREE.DRACOLoader.releaseDecoderModule = function () { + geometry.index = { array: index, itemSize: 1 }; - THREE.DRACOLoader.decoderModulePromise = null; + draco.destroy( indexArray ); -}; + } -/** - * Gets WebAssembly or asm.js singleton instance of DracoDecoderModule - * after testing for browser support. Returns Promise that resolves when - * module is available. - * @return {Promise<{decoder: DracoDecoderModule}>} - */ -THREE.DRACOLoader.getDecoderModule = function () { + draco.destroy( dracoGeometry ); - var scope = this; - var path = THREE.DRACOLoader.decoderPath; - var config = THREE.DRACOLoader.decoderConfig; - var promise = THREE.DRACOLoader.decoderModulePromise; + return geometry; - if ( promise ) return promise; + } - // Load source files. - if ( typeof DracoDecoderModule !== "undefined" ) { + function decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) { - // Loaded externally. - promise = Promise.resolve(); + var numComponents = attribute.num_components(); + var numPoints = dracoGeometry.num_points(); + var numValues = numPoints * numComponents; + var dracoArray; - } else if ( typeof WebAssembly !== "object" || config.type === "js" ) { + var array; - // Load with asm.js. - promise = THREE.DRACOLoader._loadScript( path + "draco_decoder.js" ); + switch ( attributeType ) { - } else { + case Float32Array: + dracoArray = new draco.DracoFloat32Array(); + decoder.GetAttributeFloatForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Float32Array( numValues ); + break; - // Load with WebAssembly. - config.wasmBinaryFile = path + "draco_decoder.wasm"; - promise = THREE.DRACOLoader._loadScript( path + "draco_wasm_wrapper.js" ) - .then( function () { + case Int8Array: + dracoArray = new draco.DracoInt8Array(); + decoder.GetAttributeInt8ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Int8Array( numValues ); + break; - return THREE.DRACOLoader._loadArrayBuffer( config.wasmBinaryFile ); + case Int16Array: + dracoArray = new draco.DracoInt16Array(); + decoder.GetAttributeInt16ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Int16Array( numValues ); + break; - } ) - .then( function ( wasmBinary ) { + case Int32Array: + dracoArray = new draco.DracoInt32Array(); + decoder.GetAttributeInt32ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Int32Array( numValues ); + break; - config.wasmBinary = wasmBinary; + case Uint8Array: + dracoArray = new draco.DracoUInt8Array(); + decoder.GetAttributeUInt8ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Uint8Array( numValues ); + break; - } ); + case Uint16Array: + dracoArray = new draco.DracoUInt16Array(); + decoder.GetAttributeUInt16ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Uint16Array( numValues ); + break; - } + case Uint32Array: + dracoArray = new draco.DracoUInt32Array(); + decoder.GetAttributeUInt32ForAllPoints( dracoGeometry, attribute, dracoArray ); + array = new Uint32Array( numValues ); + break; - // Wait for source files, then create and return a decoder. - promise = promise.then( function () { + default: + throw new Error( 'THREE.DRACOLoader: Unexpected attribute type.' ); - return new Promise( function ( resolve ) { + } - config.onModuleLoaded = function ( decoder ) { + for ( var i = 0; i < numValues; i ++ ) { - scope.timeLoaded = performance.now(); - // Module is Promise-like. Wrap before resolving to avoid loop. - resolve( { decoder: decoder } ); + array[ i ] = dracoArray.GetValue( i ); - }; - DracoDecoderModule( config ); + } - } ); + draco.destroy( dracoArray ); - } ); + return { + name: attributeName, + array: array, + itemSize: numComponents + }; - THREE.DRACOLoader.decoderModulePromise = promise; - return promise; + } }; -/** - * @param {string} src - * @return {Promise} - */ -THREE.DRACOLoader._loadScript = function ( src ) { +THREE.DRACOLoader.taskCache = new WeakMap(); - var prevScript = document.getElementById( "decoder_script" ); - if ( prevScript !== null ) { +/** Deprecated static methods */ - prevScript.parentNode.removeChild( prevScript ); +/** @deprecated */ +THREE.DRACOLoader.setDecoderPath = function () { - } - var head = document.getElementsByTagName( "head" )[ 0 ]; - var script = document.createElement( "script" ); - script.id = "decoder_script"; - script.type = "text/javascript"; - script.src = src; - return new Promise( function ( resolve ) { + console.warn( 'THREE.DRACOLoader: The .setDecoderPath() method has been removed. Use instance methods.' ); - script.onload = resolve; - head.appendChild( script ); +}; + +/** @deprecated */ +THREE.DRACOLoader.setDecoderConfig = function () { - } ); + console.warn( 'THREE.DRACOLoader: The .setDecoderConfig() method has been removed. Use instance methods.' ); }; -/** - * @param {string} src - * @return {Promise} - */ -THREE.DRACOLoader._loadArrayBuffer = function ( src ) { +/** @deprecated */ +THREE.DRACOLoader.releaseDecoderModule = function () { + + console.warn( 'THREE.DRACOLoader: The .releaseDecoderModule() method has been removed. Use instance methods.' ); - var loader = new THREE.FileLoader(); - loader.setResponseType( "arraybuffer" ); - return new Promise( function ( resolve, reject ) { +}; - loader.load( src, resolve, undefined, reject ); +/** @deprecated */ +THREE.DRACOLoader.getDecoderModule = function () { - } ); + console.warn( 'THREE.DRACOLoader: The .getDecoderModule() method has been removed. Use instance methods.' ); }; diff --git a/examples/js/loaders/EXRLoader.js b/examples/js/loaders/EXRLoader.js index 9172fa35be35f6..10adffe87390a0 100644 --- a/examples/js/loaders/EXRLoader.js +++ b/examples/js/loaders/EXRLoader.js @@ -1,8 +1,9 @@ /** * @author Richard M. / https://github.com/richardmonette + * @author ScieCode / http://github.com/sciecode * - * OpenEXR loader which, currently, supports reading 16 bit half data, in either - * uncompressed or PIZ wavelet compressed form. + * OpenEXR loader which, currently, supports uncompressed, ZIP(S), RLE and PIZ wavelet compression. + * Supports reading 16 and 32 bit data format. * * Referred to the original Industrial Light & Magic OpenEXR implementation and the TinyEXR / Syoyo Fujita * implementation, so I have preserved their copyright notices. @@ -75,544 +76,1335 @@ THREE.EXRLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.DataTextureLoader.call( this, manager ); + this.type = THREE.FloatType; -}; +}; + +THREE.EXRLoader.prototype = Object.assign( Object.create( THREE.DataTextureLoader.prototype ), { + + constructor: THREE.EXRLoader, + + parse: function ( buffer ) { + + const USHORT_RANGE = ( 1 << 16 ); + const BITMAP_SIZE = ( USHORT_RANGE >> 3 ); + + const HUF_ENCBITS = 16; // literal (value) bit length + const HUF_DECBITS = 14; // decoding bit size (>= 8) + + const HUF_ENCSIZE = ( 1 << HUF_ENCBITS ) + 1; // encoding table size + const HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size + const HUF_DECMASK = HUF_DECSIZE - 1; + + const SHORT_ZEROCODE_RUN = 59; + const LONG_ZEROCODE_RUN = 63; + const SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN; + + const ULONG_SIZE = 8; + const FLOAT32_SIZE = 4; + const INT32_SIZE = 4; + const INT16_SIZE = 2; + const INT8_SIZE = 1; + + const STATIC_HUFFMAN = 0; + const DEFLATE = 1; + + const UNKNOWN = 0; + const LOSSY_DCT = 1; + const RLE = 2; + + const logBase = Math.pow( 2.7182818, 2.2 ); + + function reverseLutFromBitmap( bitmap, lut ) { + + var k = 0; + + for ( var i = 0; i < USHORT_RANGE; ++ i ) { + + if ( ( i == 0 ) || ( bitmap[ i >> 3 ] & ( 1 << ( i & 7 ) ) ) ) { + + lut[ k ++ ] = i; + + } + + } + + var n = k - 1; + + while ( k < USHORT_RANGE ) lut[ k ++ ] = 0; + + return n; + + } + + function hufClearDecTable( hdec ) { + + for ( var i = 0; i < HUF_DECSIZE; i ++ ) { + + hdec[ i ] = {}; + hdec[ i ].len = 0; + hdec[ i ].lit = 0; + hdec[ i ].p = null; + + } + + } + + const getBitsReturn = { l: 0, c: 0, lc: 0 }; + + function getBits( nBits, c, lc, uInt8Array, inOffset ) { + + while ( lc < nBits ) { + + c = ( c << 8 ) | parseUint8Array( uInt8Array, inOffset ); + lc += 8; + + } + + lc -= nBits; + + getBitsReturn.l = ( c >> lc ) & ( ( 1 << nBits ) - 1 ); + getBitsReturn.c = c; + getBitsReturn.lc = lc; + + } + + const hufTableBuffer = new Array( 59 ); + + function hufCanonicalCodeTable( hcode ) { + + for ( var i = 0; i <= 58; ++ i ) hufTableBuffer[ i ] = 0; + for ( var i = 0; i < HUF_ENCSIZE; ++ i ) hufTableBuffer[ hcode[ i ] ] += 1; + + var c = 0; + + for ( var i = 58; i > 0; -- i ) { + + var nc = ( ( c + hufTableBuffer[ i ] ) >> 1 ); + hufTableBuffer[ i ] = c; + c = nc; + + } + + for ( var i = 0; i < HUF_ENCSIZE; ++ i ) { + + var l = hcode[ i ]; + if ( l > 0 ) hcode[ i ] = l | ( hufTableBuffer[ l ] ++ << 6 ); + + } + + } + + function hufUnpackEncTable( uInt8Array, inDataView, inOffset, ni, im, iM, hcode ) { + + var p = inOffset; + var c = 0; + var lc = 0; + + for ( ; im <= iM; im ++ ) { + + if ( p.value - inOffset.value > ni ) return false; + + getBits( 6, c, lc, uInt8Array, p ); + + var l = getBitsReturn.l; + c = getBitsReturn.c; + lc = getBitsReturn.lc; + + hcode[ im ] = l; + + if ( l == LONG_ZEROCODE_RUN ) { + + if ( p.value - inOffset.value > ni ) { + + throw 'Something wrong with hufUnpackEncTable'; + + } + + getBits( 8, c, lc, uInt8Array, p ); + + var zerun = getBitsReturn.l + SHORTEST_LONG_RUN; + c = getBitsReturn.c; + lc = getBitsReturn.lc; + + if ( im + zerun > iM + 1 ) { + + throw 'Something wrong with hufUnpackEncTable'; + + } + + while ( zerun -- ) hcode[ im ++ ] = 0; + + im --; + + } else if ( l >= SHORT_ZEROCODE_RUN ) { + + var zerun = l - SHORT_ZEROCODE_RUN + 2; + + if ( im + zerun > iM + 1 ) { + + throw 'Something wrong with hufUnpackEncTable'; + + } + + while ( zerun -- ) hcode[ im ++ ] = 0; + + im --; + + } + + } + + hufCanonicalCodeTable( hcode ); + + } + + function hufLength( code ) { + + return code & 63; + + } + + function hufCode( code ) { + + return code >> 6; + + } + + function hufBuildDecTable( hcode, im, iM, hdecod ) { + + for ( ; im <= iM; im ++ ) { + + var c = hufCode( hcode[ im ] ); + var l = hufLength( hcode[ im ] ); + + if ( c >> l ) { + + throw 'Invalid table entry'; + + } + + if ( l > HUF_DECBITS ) { + + var pl = hdecod[ ( c >> ( l - HUF_DECBITS ) ) ]; + + if ( pl.len ) { + + throw 'Invalid table entry'; + + } + + pl.lit ++; + + if ( pl.p ) { + + var p = pl.p; + pl.p = new Array( pl.lit ); + + for ( var i = 0; i < pl.lit - 1; ++ i ) { + + pl.p[ i ] = p[ i ]; + + } + + } else { + + pl.p = new Array( 1 ); + + } + + pl.p[ pl.lit - 1 ] = im; + + } else if ( l ) { + + var plOffset = 0; + + for ( var i = 1 << ( HUF_DECBITS - l ); i > 0; i -- ) { + + var pl = hdecod[ ( c << ( HUF_DECBITS - l ) ) + plOffset ]; + + if ( pl.len || pl.p ) { + + throw 'Invalid table entry'; + + } + + pl.len = l; + pl.lit = im; + + plOffset ++; + + } + + } + + } + + return true; + + } + + const getCharReturn = { c: 0, lc: 0 }; + + function getChar( c, lc, uInt8Array, inOffset ) { + + c = ( c << 8 ) | parseUint8Array( uInt8Array, inOffset ); + lc += 8; + + getCharReturn.c = c; + getCharReturn.lc = lc; + + } + + const getCodeReturn = { c: 0, lc: 0 }; + + function getCode( po, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outBufferOffset, outBufferEndOffset ) { + + if ( po == rlc ) { + + if ( lc < 8 ) { + + getChar( c, lc, uInt8Array, inOffset ); + c = getCharReturn.c; + lc = getCharReturn.lc; + + } + + lc -= 8; + + var cs = ( c >> lc ); + var cs = new Uint8Array( [ cs ] )[ 0 ]; + + if ( outBufferOffset.value + cs > outBufferEndOffset ) { + + return false; + + } + + var s = outBuffer[ outBufferOffset.value - 1 ]; + + while ( cs -- > 0 ) { + + outBuffer[ outBufferOffset.value ++ ] = s; + + } + + } else if ( outBufferOffset.value < outBufferEndOffset ) { + + outBuffer[ outBufferOffset.value ++ ] = po; + + } else { + + return false; + + } + + getCodeReturn.c = c; + getCodeReturn.lc = lc; + + } + + function UInt16( value ) { + + return ( value & 0xFFFF ); + + } + + function Int16( value ) { + + var ref = UInt16( value ); + return ( ref > 0x7FFF ) ? ref - 0x10000 : ref; + + } + + const wdec14Return = { a: 0, b: 0 }; + + function wdec14( l, h ) { + + var ls = Int16( l ); + var hs = Int16( h ); + + var hi = hs; + var ai = ls + ( hi & 1 ) + ( hi >> 1 ); + + var as = ai; + var bs = ai - hi; + + wdec14Return.a = as; + wdec14Return.b = bs; + + } + + function wav2Decode( buffer, j, nx, ox, ny, oy ) { + + var n = ( nx > ny ) ? ny : nx; + var p = 1; + var p2; + + while ( p <= n ) p <<= 1; + + p >>= 1; + p2 = p; + p >>= 1; + + while ( p >= 1 ) { + + var py = 0; + var ey = py + oy * ( ny - p2 ); + var oy1 = oy * p; + var oy2 = oy * p2; + var ox1 = ox * p; + var ox2 = ox * p2; + var i00, i01, i10, i11; + + for ( ; py <= ey; py += oy2 ) { + + var px = py; + var ex = py + ox * ( nx - p2 ); + + for ( ; px <= ex; px += ox2 ) { + + var p01 = px + ox1; + var p10 = px + oy1; + var p11 = p10 + ox1; + + wdec14( buffer[ px + j ], buffer[ p10 + j ] ); + + i00 = wdec14Return.a; + i10 = wdec14Return.b; + + wdec14( buffer[ p01 + j ], buffer[ p11 + j ] ); + + i01 = wdec14Return.a; + i11 = wdec14Return.b; + + wdec14( i00, i01 ); + + buffer[ px + j ] = wdec14Return.a; + buffer[ p01 + j ] = wdec14Return.b; + + wdec14( i10, i11 ); + + buffer[ p10 + j ] = wdec14Return.a; + buffer[ p11 + j ] = wdec14Return.b; + + } + + if ( nx & p ) { + + var p10 = px + oy1; + + wdec14( buffer[ px + j ], buffer[ p10 + j ] ); + + i00 = wdec14Return.a; + buffer[ p10 + j ] = wdec14Return.b; + + buffer[ px + j ] = i00; + + } + + } + + if ( ny & p ) { + + var px = py; + var ex = py + ox * ( nx - p2 ); + + for ( ; px <= ex; px += ox2 ) { + + var p01 = px + ox1; + + wdec14( buffer[ px + j ], buffer[ p01 + j ] ); + + i00 = wdec14Return.a; + buffer[ p01 + j ] = wdec14Return.b; + + buffer[ px + j ] = i00; + + } + + } + + p2 = p; + p >>= 1; + + } + + return py; + + } + + function hufDecode( encodingTable, decodingTable, uInt8Array, inDataView, inOffset, ni, rlc, no, outBuffer, outOffset ) { + + var c = 0; + var lc = 0; + var outBufferEndOffset = no; + var inOffsetEnd = Math.trunc( inOffset.value + ( ni + 7 ) / 8 ); + + while ( inOffset.value < inOffsetEnd ) { + + getChar( c, lc, uInt8Array, inOffset ); + + c = getCharReturn.c; + lc = getCharReturn.lc; + + while ( lc >= HUF_DECBITS ) { + + var index = ( c >> ( lc - HUF_DECBITS ) ) & HUF_DECMASK; + var pl = decodingTable[ index ]; + + if ( pl.len ) { + + lc -= pl.len; + + getCode( pl.lit, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset ); + + c = getCodeReturn.c; + lc = getCodeReturn.lc; + + } else { + + if ( ! pl.p ) { + + throw 'hufDecode issues'; + + } + + var j; + + for ( j = 0; j < pl.lit; j ++ ) { + + var l = hufLength( encodingTable[ pl.p[ j ] ] ); + + while ( lc < l && inOffset.value < inOffsetEnd ) { + + getChar( c, lc, uInt8Array, inOffset ); + + c = getCharReturn.c; + lc = getCharReturn.lc; + + } + + if ( lc >= l ) { + + if ( hufCode( encodingTable[ pl.p[ j ] ] ) == ( ( c >> ( lc - l ) ) & ( ( 1 << l ) - 1 ) ) ) { + + lc -= l; + + getCode( pl.p[ j ], rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset ); + + c = getCodeReturn.c; + lc = getCodeReturn.lc; + + break; + + } + + } + + } + + if ( j == pl.lit ) { + + throw 'hufDecode issues'; + + } + + } + + } + + } + + var i = ( 8 - ni ) & 7; + + c >>= i; + lc -= i; + + while ( lc > 0 ) { + + var pl = decodingTable[ ( c << ( HUF_DECBITS - lc ) ) & HUF_DECMASK ]; + + if ( pl.len ) { + + lc -= pl.len; + + getCode( pl.lit, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset ); + + c = getCodeReturn.c; + lc = getCodeReturn.lc; + + } else { + + throw 'hufDecode issues'; + + } + + } + + return true; + + } -THREE.EXRLoader.prototype = Object.create( THREE.DataTextureLoader.prototype ); + function hufUncompress( uInt8Array, inDataView, inOffset, nCompressed, outBuffer, nRaw ) { -THREE.EXRLoader.prototype.setDataType = function ( value ) { + var outOffset = { value: 0 }; + var initialInOffset = inOffset.value; - this.type = value; - return this; + var im = parseUint32( inDataView, inOffset ); + var iM = parseUint32( inDataView, inOffset ); -}; + inOffset.value += 4; -THREE.EXRLoader.prototype.setType = function ( value ) { + var nBits = parseUint32( inDataView, inOffset ); - console.warn( 'THREE.EXRLoader: .setType() has been renamed to .setDataType().' ); + inOffset.value += 4; - return this.setDataType( value ); + if ( im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE ) { -}; + throw 'Something wrong with HUF_ENCSIZE'; -THREE.EXRLoader.prototype._parser = function ( buffer ) { + } + + var freq = new Array( HUF_ENCSIZE ); + var hdec = new Array( HUF_DECSIZE ); - const USHORT_RANGE = ( 1 << 16 ); - const BITMAP_SIZE = ( USHORT_RANGE >> 3 ); + hufClearDecTable( hdec ); - const HUF_ENCBITS = 16; // literal (value) bit length - const HUF_DECBITS = 14; // decoding bit size (>= 8) + var ni = nCompressed - ( inOffset.value - initialInOffset ); - const HUF_ENCSIZE = ( 1 << HUF_ENCBITS ) + 1; // encoding table size - const HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size - const HUF_DECMASK = HUF_DECSIZE - 1; + hufUnpackEncTable( uInt8Array, inDataView, inOffset, ni, im, iM, freq ); - const SHORT_ZEROCODE_RUN = 59; - const LONG_ZEROCODE_RUN = 63; - const SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN; + if ( nBits > 8 * ( nCompressed - ( inOffset.value - initialInOffset ) ) ) { - const BYTES_PER_HALF = 2; + throw 'Something wrong with hufUncompress'; + + } - const ULONG_SIZE = 8; - const FLOAT32_SIZE = 4; - const INT32_SIZE = 4; - const INT16_SIZE = 2; - const INT8_SIZE = 1; + hufBuildDecTable( freq, im, iM, hdec ); - function reverseLutFromBitmap( bitmap, lut ) { + hufDecode( freq, hdec, uInt8Array, inDataView, inOffset, nBits, iM, nRaw, outBuffer, outOffset ); - var k = 0; + } - for ( var i = 0; i < USHORT_RANGE; ++ i ) { + function applyLut( lut, data, nData ) { - if ( ( i == 0 ) || ( bitmap[ i >> 3 ] & ( 1 << ( i & 7 ) ) ) ) { + for ( var i = 0; i < nData; ++ i ) { - lut[ k ++ ] = i; + data[ i ] = lut[ data[ i ] ]; } } - var n = k - 1; + function predictor( source ) { - while ( k < USHORT_RANGE ) lut[ k ++ ] = 0; + for ( var t = 1; t < source.length; t ++ ) { - return n; + var d = source[ t - 1 ] + source[ t ] - 128; + source[ t ] = d; - } + } + + } + + function interleaveScalar( source, out ) { + + var t1 = 0; + var t2 = Math.floor( ( source.length + 1 ) / 2 ); + var s = 0; + var stop = source.length - 1; + + while ( true ) { - function hufClearDecTable( hdec ) { + if ( s > stop ) break; + out[ s ++ ] = source[ t1 ++ ]; - for ( var i = 0; i < HUF_DECSIZE; i ++ ) { + if ( s > stop ) break; + out[ s ++ ] = source[ t2 ++ ]; - hdec[ i ] = {}; - hdec[ i ].len = 0; - hdec[ i ].lit = 0; - hdec[ i ].p = null; + } } - } + function decodeRunLength( source ) { - const getBitsReturn = { l: 0, c: 0, lc: 0 }; + var size = source.byteLength; + var out = new Array(); + var p = 0; - function getBits( nBits, c, lc, uInt8Array, inOffset ) { + var reader = new DataView( source ); - while ( lc < nBits ) { + while ( size > 0 ) { - c = ( c << 8 ) | parseUint8Array( uInt8Array, inOffset ); - lc += 8; + var l = reader.getInt8( p ++ ); - } + if ( l < 0 ) { - lc -= nBits; + var count = - l; + size -= count + 1; - getBitsReturn.l = ( c >> lc ) & ( ( 1 << nBits ) - 1 ); - getBitsReturn.c = c; - getBitsReturn.lc = lc; + for ( var i = 0; i < count; i ++ ) { - } + out.push( reader.getUint8( p ++ ) ); + + } - const hufTableBuffer = new Array( 59 ); - function hufCanonicalCodeTable( hcode ) { + } else { - for ( var i = 0; i <= 58; ++ i ) hufTableBuffer[ i ] = 0; - for ( var i = 0; i < HUF_ENCSIZE; ++ i ) hufTableBuffer[ hcode[ i ] ] += 1; + var count = l; + size -= 2; - var c = 0; + var value = reader.getUint8( p ++ ); - for ( var i = 58; i > 0; -- i ) { + for ( var i = 0; i < count + 1; i ++ ) { - var nc = ( ( c + hufTableBuffer[ i ] ) >> 1 ); - hufTableBuffer[ i ] = c; - c = nc; + out.push( value ); - } + } + + } - for ( var i = 0; i < HUF_ENCSIZE; ++ i ) { + } - var l = hcode[ i ]; - if ( l > 0 ) hcode[ i ] = l | ( hufTableBuffer[ l ] ++ << 6 ); + return out; } - } + function lossyDctDecode( cscSet, rowPtrs, channelData, acBuffer, dcBuffer, outBuffer ) { + + var dataView = new DataView( outBuffer.buffer ); - function hufUnpackEncTable( uInt8Array, inDataView, inOffset, ni, im, iM, hcode ) { + var width = channelData[ cscSet.idx[ 0 ] ].width; + var height = channelData[ cscSet.idx[ 0 ] ].height; - var p = inOffset; - var c = 0; - var lc = 0; + var numComp = 3; - for ( ; im <= iM; im ++ ) { + var numFullBlocksX = Math.floor( width / 8.0 ); + var numBlocksX = Math.ceil( width / 8.0 ); + var numBlocksY = Math.ceil( height / 8.0 ); + var leftoverX = width - ( numBlocksX - 1 ) * 8; + var leftoverY = height - ( numBlocksY - 1 ) * 8; - if ( p.value - inOffset.value > ni ) return false; + var currAcComp = { value: 0 }; + var currDcComp = new Array( numComp ); + var dctData = new Array( numComp ); + var halfZigBlock = new Array( numComp ); + var rowBlock = new Array( numComp ); + var rowOffsets = new Array( numComp ); - getBits( 6, c, lc, uInt8Array, p ); + for ( let comp = 0; comp < numComp; ++ comp ) { - var l = getBitsReturn.l; - c = getBitsReturn.c; - lc = getBitsReturn.lc; + rowOffsets[ comp ] = rowPtrs[ cscSet.idx[ comp ] ]; + currDcComp[ comp ] = ( comp < 1 ) ? 0 : currDcComp[ comp - 1 ] + numBlocksX * numBlocksY; + dctData[ comp ] = new Float32Array( 64 ); + halfZigBlock[ comp ] = new Uint16Array( 64 ); + rowBlock[ comp ] = new Uint16Array( numBlocksX * 64 ); - hcode[ im ] = l; + } - if ( l == LONG_ZEROCODE_RUN ) { + for ( let blocky = 0; blocky < numBlocksY; ++ blocky ) { - if ( p.value - inOffset.value > ni ) { + var maxY = 8; - throw 'Something wrong with hufUnpackEncTable'; + if ( blocky == numBlocksY - 1 ) + maxY = leftoverY; - } + var maxX = 8; - getBits( 8, c, lc, uInt8Array, p ); + for ( let blockx = 0; blockx < numBlocksX; ++ blockx ) { - var zerun = getBitsReturn.l + SHORTEST_LONG_RUN; - c = getBitsReturn.c; - lc = getBitsReturn.lc; + if ( blockx == numBlocksX - 1 ) + maxX = leftoverX; - if ( im + zerun > iM + 1 ) { + for ( let comp = 0; comp < numComp; ++ comp ) { - throw 'Something wrong with hufUnpackEncTable'; + halfZigBlock[ comp ].fill( 0 ); - } + // set block DC component + halfZigBlock[ comp ][ 0 ] = dcBuffer[ currDcComp[ comp ] ++ ]; + // set block AC components + unRleAC( currAcComp, acBuffer, halfZigBlock[ comp ] ); - while ( zerun -- ) hcode[ im ++ ] = 0; + // UnZigZag block to float + unZigZag( halfZigBlock[ comp ], dctData[ comp ] ); + // decode float dct + dctInverse( dctData[ comp ] ); - im --; + } - } else if ( l >= SHORT_ZEROCODE_RUN ) { + if ( numComp == 3 ) { - var zerun = l - SHORT_ZEROCODE_RUN + 2; + csc709Inverse( dctData ); - if ( im + zerun > iM + 1 ) { + } - throw 'Something wrong with hufUnpackEncTable'; + for ( let comp = 0; comp < numComp; ++ comp ) { - } + convertToHalf( dctData[ comp ], rowBlock[ comp ], blockx * 64 ); - while ( zerun -- ) hcode[ im ++ ] = 0; + } - im --; + } // blockx - } + let offset = 0; - } + for ( let comp = 0; comp < numComp; ++ comp ) { - hufCanonicalCodeTable( hcode ); + let type = channelData[ cscSet.idx[ comp ] ].type; - } + for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) { - function hufLength( code ) { + offset = rowOffsets[ comp ][ y ]; - return code & 63; + for ( let blockx = 0; blockx < numFullBlocksX; ++ blockx ) { - } + let src = blockx * 64 + ( ( y & 0x7 ) * 8 ); - function hufCode( code ) { + dataView.setUint16( offset + 0 * INT16_SIZE * type, rowBlock[ comp ][ src + 0 ], true ); + dataView.setUint16( offset + 1 * INT16_SIZE * type, rowBlock[ comp ][ src + 1 ], true ); + dataView.setUint16( offset + 2 * INT16_SIZE * type, rowBlock[ comp ][ src + 2 ], true ); + dataView.setUint16( offset + 3 * INT16_SIZE * type, rowBlock[ comp ][ src + 3 ], true ); - return code >> 6; + dataView.setUint16( offset + 4 * INT16_SIZE * type, rowBlock[ comp ][ src + 4 ], true ); + dataView.setUint16( offset + 5 * INT16_SIZE * type, rowBlock[ comp ][ src + 5 ], true ); + dataView.setUint16( offset + 6 * INT16_SIZE * type, rowBlock[ comp ][ src + 6 ], true ); + dataView.setUint16( offset + 7 * INT16_SIZE * type, rowBlock[ comp ][ src + 7 ], true ); - } + offset += 8 * INT16_SIZE * type; + + } - function hufBuildDecTable( hcode, im, iM, hdecod ) { + } - for ( ; im <= iM; im ++ ) { + // handle partial X blocks + if ( numFullBlocksX != numBlocksX ) { - var c = hufCode( hcode[ im ] ); - var l = hufLength( hcode[ im ] ); + for ( let y = 8 * blocky; y < 8 * blocky + maxY; ++ y ) { - if ( c >> l ) { + let offset = rowOffsets[ comp ][ y ] + 8 * numFullBlocksX * INT16_SIZE * type; + let src = numFullBlocksX * 64 + ( ( y & 0x7 ) * 8 ); - throw 'Invalid table entry'; + for ( let x = 0; x < maxX; ++ x ) { - } + dataView.setUint16( offset + x * INT16_SIZE * type, rowBlock[ comp ][ src + x ], true ); - if ( l > HUF_DECBITS ) { + } - var pl = hdecod[ ( c >> ( l - HUF_DECBITS ) ) ]; + } - if ( pl.len ) { + } - throw 'Invalid table entry'; + } // comp - } + } // blocky - pl.lit ++; + var halfRow = new Uint16Array( width ); + var dataView = new DataView( outBuffer.buffer ); - if ( pl.p ) { + // convert channels back to float, if needed + for ( var comp = 0; comp < numComp; ++ comp ) { - var p = pl.p; - pl.p = new Array( pl.lit ); + channelData[ cscSet.idx[ comp ] ].decoded = true; + var type = channelData[ cscSet.idx[ comp ] ].type; - for ( var i = 0; i < pl.lit - 1; ++ i ) { + if ( channelData[ comp ].type != 2 ) continue; - pl.p[ i ] = p[ i ]; + for ( var y = 0; y < height; ++ y ) { + + let offset = rowOffsets[ comp ][ y ]; + + for ( var x = 0; x < width; ++ x ) { + + halfRow[ x ] = dataView.getUint16( offset + x * INT16_SIZE * type, true ); } - } else { + for ( var x = 0; x < width; ++ x ) { - pl.p = new Array( 1 ); + dataView.setFloat32( offset + x * INT16_SIZE * type, decodeFloat16( halfRow[ x ] ), true ); + + } } - pl.p[ pl.lit - 1 ] = im; + } + + } - } else if ( l ) { + function unRleAC( currAcComp, acBuffer, halfZigBlock ) { - var plOffset = 0; + var acValue; + var dctComp = 1; - for ( var i = 1 << ( HUF_DECBITS - l ); i > 0; i -- ) { + while ( dctComp < 64 ) { - var pl = hdecod[ ( c << ( HUF_DECBITS - l ) ) + plOffset ]; + acValue = acBuffer[ currAcComp.value ]; - if ( pl.len || pl.p ) { + if ( acValue == 0xff00 ) { - throw 'Invalid table entry'; + dctComp = 64; - } + } else if ( acValue >> 8 == 0xff ) { + + dctComp += acValue & 0xff; - pl.len = l; - pl.lit = im; + } else { - plOffset ++; + halfZigBlock[ dctComp ] = acValue; + dctComp ++; } + currAcComp.value ++; + } } - return true; + function unZigZag( src, dst ) { + + dst[ 0 ] = decodeFloat16( src[ 0 ] ); + dst[ 1 ] = decodeFloat16( src[ 1 ] ); + dst[ 2 ] = decodeFloat16( src[ 5 ] ); + dst[ 3 ] = decodeFloat16( src[ 6 ] ); + dst[ 4 ] = decodeFloat16( src[ 14 ] ); + dst[ 5 ] = decodeFloat16( src[ 15 ] ); + dst[ 6 ] = decodeFloat16( src[ 27 ] ); + dst[ 7 ] = decodeFloat16( src[ 28 ] ); + dst[ 8 ] = decodeFloat16( src[ 2 ] ); + dst[ 9 ] = decodeFloat16( src[ 4 ] ); + + dst[ 10 ] = decodeFloat16( src[ 7 ] ); + dst[ 11 ] = decodeFloat16( src[ 13 ] ); + dst[ 12 ] = decodeFloat16( src[ 16 ] ); + dst[ 13 ] = decodeFloat16( src[ 26 ] ); + dst[ 14 ] = decodeFloat16( src[ 29 ] ); + dst[ 15 ] = decodeFloat16( src[ 42 ] ); + dst[ 16 ] = decodeFloat16( src[ 3 ] ); + dst[ 17 ] = decodeFloat16( src[ 8 ] ); + dst[ 18 ] = decodeFloat16( src[ 12 ] ); + dst[ 19 ] = decodeFloat16( src[ 17 ] ); + + dst[ 20 ] = decodeFloat16( src[ 25 ] ); + dst[ 21 ] = decodeFloat16( src[ 30 ] ); + dst[ 22 ] = decodeFloat16( src[ 41 ] ); + dst[ 23 ] = decodeFloat16( src[ 43 ] ); + dst[ 24 ] = decodeFloat16( src[ 9 ] ); + dst[ 25 ] = decodeFloat16( src[ 11 ] ); + dst[ 26 ] = decodeFloat16( src[ 18 ] ); + dst[ 27 ] = decodeFloat16( src[ 24 ] ); + dst[ 28 ] = decodeFloat16( src[ 31 ] ); + dst[ 29 ] = decodeFloat16( src[ 40 ] ); + + dst[ 30 ] = decodeFloat16( src[ 44 ] ); + dst[ 31 ] = decodeFloat16( src[ 53 ] ); + dst[ 32 ] = decodeFloat16( src[ 10 ] ); + dst[ 33 ] = decodeFloat16( src[ 19 ] ); + dst[ 34 ] = decodeFloat16( src[ 23 ] ); + dst[ 35 ] = decodeFloat16( src[ 32 ] ); + dst[ 36 ] = decodeFloat16( src[ 39 ] ); + dst[ 37 ] = decodeFloat16( src[ 45 ] ); + dst[ 38 ] = decodeFloat16( src[ 52 ] ); + dst[ 39 ] = decodeFloat16( src[ 54 ] ); + + dst[ 40 ] = decodeFloat16( src[ 20 ] ); + dst[ 41 ] = decodeFloat16( src[ 22 ] ); + dst[ 42 ] = decodeFloat16( src[ 33 ] ); + dst[ 43 ] = decodeFloat16( src[ 38 ] ); + dst[ 44 ] = decodeFloat16( src[ 46 ] ); + dst[ 45 ] = decodeFloat16( src[ 51 ] ); + dst[ 46 ] = decodeFloat16( src[ 55 ] ); + dst[ 47 ] = decodeFloat16( src[ 60 ] ); + dst[ 48 ] = decodeFloat16( src[ 21 ] ); + dst[ 49 ] = decodeFloat16( src[ 34 ] ); + + dst[ 50 ] = decodeFloat16( src[ 37 ] ); + dst[ 51 ] = decodeFloat16( src[ 47 ] ); + dst[ 52 ] = decodeFloat16( src[ 50 ] ); + dst[ 53 ] = decodeFloat16( src[ 56 ] ); + dst[ 54 ] = decodeFloat16( src[ 59 ] ); + dst[ 55 ] = decodeFloat16( src[ 61 ] ); + dst[ 56 ] = decodeFloat16( src[ 35 ] ); + dst[ 57 ] = decodeFloat16( src[ 36 ] ); + dst[ 58 ] = decodeFloat16( src[ 48 ] ); + dst[ 59 ] = decodeFloat16( src[ 49 ] ); + + dst[ 60 ] = decodeFloat16( src[ 57 ] ); + dst[ 61 ] = decodeFloat16( src[ 58 ] ); + dst[ 62 ] = decodeFloat16( src[ 62 ] ); + dst[ 63 ] = decodeFloat16( src[ 63 ] ); - } + } - const getCharReturn = { c: 0, lc: 0 }; + function dctInverse( data ) { - function getChar( c, lc, uInt8Array, inOffset ) { + const a = 0.5 * Math.cos( 3.14159 / 4.0 ); + const b = 0.5 * Math.cos( 3.14159 / 16.0 ); + const c = 0.5 * Math.cos( 3.14159 / 8.0 ); + const d = 0.5 * Math.cos( 3.0 * 3.14159 / 16.0 ); + const e = 0.5 * Math.cos( 5.0 * 3.14159 / 16.0 ); + const f = 0.5 * Math.cos( 3.0 * 3.14159 / 8.0 ); + const g = 0.5 * Math.cos( 7.0 * 3.14159 / 16.0 ); - c = ( c << 8 ) | parseUint8Array( uInt8Array, inOffset ); - lc += 8; + var alpha = new Array( 4 ); + var beta = new Array( 4 ); + var theta = new Array( 4 ); + var gamma = new Array( 4 ); - getCharReturn.c = c; - getCharReturn.lc = lc; + for ( var row = 0; row < 8; ++ row ) { - } + var rowPtr = row * 8; - const getCodeReturn = { c: 0, lc: 0 }; + alpha[ 0 ] = c * data[ rowPtr + 2 ]; + alpha[ 1 ] = f * data[ rowPtr + 2 ]; + alpha[ 2 ] = c * data[ rowPtr + 6 ]; + alpha[ 3 ] = f * data[ rowPtr + 6 ]; - function getCode( po, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outBufferOffset, outBufferEndOffset ) { + beta[ 0 ] = b * data[ rowPtr + 1 ] + d * data[ rowPtr + 3 ] + e * data[ rowPtr + 5 ] + g * data[ rowPtr + 7 ]; + beta[ 1 ] = d * data[ rowPtr + 1 ] - g * data[ rowPtr + 3 ] - b * data[ rowPtr + 5 ] - e * data[ rowPtr + 7 ]; + beta[ 2 ] = e * data[ rowPtr + 1 ] - b * data[ rowPtr + 3 ] + g * data[ rowPtr + 5 ] + d * data[ rowPtr + 7 ]; + beta[ 3 ] = g * data[ rowPtr + 1 ] - e * data[ rowPtr + 3 ] + d * data[ rowPtr + 5 ] - b * data[ rowPtr + 7 ]; - if ( po == rlc ) { + theta[ 0 ] = a * ( data[ rowPtr + 0 ] + data[ rowPtr + 4 ] ); + theta[ 3 ] = a * ( data[ rowPtr + 0 ] - data[ rowPtr + 4 ] ); + theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ]; + theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ]; - if ( lc < 8 ) { + gamma[ 0 ] = theta[ 0 ] + theta[ 1 ]; + gamma[ 1 ] = theta[ 3 ] + theta[ 2 ]; + gamma[ 2 ] = theta[ 3 ] - theta[ 2 ]; + gamma[ 3 ] = theta[ 0 ] - theta[ 1 ]; - getChar( c, lc, uInt8Array, inOffset ); - c = getCharReturn.c; - lc = getCharReturn.lc; + data[ rowPtr + 0 ] = gamma[ 0 ] + beta[ 0 ]; + data[ rowPtr + 1 ] = gamma[ 1 ] + beta[ 1 ]; + data[ rowPtr + 2 ] = gamma[ 2 ] + beta[ 2 ]; + data[ rowPtr + 3 ] = gamma[ 3 ] + beta[ 3 ]; + + data[ rowPtr + 4 ] = gamma[ 3 ] - beta[ 3 ]; + data[ rowPtr + 5 ] = gamma[ 2 ] - beta[ 2 ]; + data[ rowPtr + 6 ] = gamma[ 1 ] - beta[ 1 ]; + data[ rowPtr + 7 ] = gamma[ 0 ] - beta[ 0 ]; } - lc -= 8; + for ( var column = 0; column < 8; ++ column ) { - var cs = ( c >> lc ); - var cs = new Uint8Array( [ cs ] )[ 0 ]; + alpha[ 0 ] = c * data[ 16 + column ]; + alpha[ 1 ] = f * data[ 16 + column ]; + alpha[ 2 ] = c * data[ 48 + column ]; + alpha[ 3 ] = f * data[ 48 + column ]; - if ( outBufferOffset.value + cs > outBufferEndOffset ) { + beta[ 0 ] = b * data[ 8 + column ] + d * data[ 24 + column ] + e * data[ 40 + column ] + g * data[ 56 + column ]; + beta[ 1 ] = d * data[ 8 + column ] - g * data[ 24 + column ] - b * data[ 40 + column ] - e * data[ 56 + column ]; + beta[ 2 ] = e * data[ 8 + column ] - b * data[ 24 + column ] + g * data[ 40 + column ] + d * data[ 56 + column ]; + beta[ 3 ] = g * data[ 8 + column ] - e * data[ 24 + column ] + d * data[ 40 + column ] - b * data[ 56 + column ]; - return false; + theta[ 0 ] = a * ( data[ column ] + data[ 32 + column ] ); + theta[ 3 ] = a * ( data[ column ] - data[ 32 + column ] ); + + theta[ 1 ] = alpha[ 0 ] + alpha[ 3 ]; + theta[ 2 ] = alpha[ 1 ] - alpha[ 2 ]; + + gamma[ 0 ] = theta[ 0 ] + theta[ 1 ]; + gamma[ 1 ] = theta[ 3 ] + theta[ 2 ]; + gamma[ 2 ] = theta[ 3 ] - theta[ 2 ]; + gamma[ 3 ] = theta[ 0 ] - theta[ 1 ]; + + data[ 0 + column ] = gamma[ 0 ] + beta[ 0 ]; + data[ 8 + column ] = gamma[ 1 ] + beta[ 1 ]; + data[ 16 + column ] = gamma[ 2 ] + beta[ 2 ]; + data[ 24 + column ] = gamma[ 3 ] + beta[ 3 ]; + + data[ 32 + column ] = gamma[ 3 ] - beta[ 3 ]; + data[ 40 + column ] = gamma[ 2 ] - beta[ 2 ]; + data[ 48 + column ] = gamma[ 1 ] - beta[ 1 ]; + data[ 56 + column ] = gamma[ 0 ] - beta[ 0 ]; } - var s = outBuffer[ outBufferOffset.value - 1 ]; + } + + function csc709Inverse( data ) { - while ( cs -- > 0 ) { + for ( var i = 0; i < 64; ++ i ) { - outBuffer[ outBufferOffset.value ++ ] = s; + var y = data[ 0 ][ i ]; + var cb = data[ 1 ][ i ]; + var cr = data[ 2 ][ i ]; + + data[ 0 ][ i ] = y + 1.5747 * cr; + data[ 1 ][ i ] = y - 0.1873 * cb - 0.4682 * cr; + data[ 2 ][ i ] = y + 1.8556 * cb; } - } else if ( outBufferOffset.value < outBufferEndOffset ) { + } + + function convertToHalf( src, dst, idx ) { - outBuffer[ outBufferOffset.value ++ ] = po; + for ( var i = 0; i < 64; ++ i ) { - } else { + dst[ idx + i ] = encodeFloat16( toLinear( src[ i ] ) ); - return false; + } } - getCodeReturn.c = c; - getCodeReturn.lc = lc; + function toLinear( float ) { - } + if ( float <= 1 ) { - function UInt16( value ) { + return Math.sign( float ) * Math.pow( Math.abs( float ), 2.2 ); - return ( value & 0xFFFF ); + } else { - } + return Math.sign( float ) * Math.pow( logBase, Math.abs( float ) - 1.0 ); - function Int16( value ) { + } + + } - var ref = UInt16( value ); - return ( ref > 0x7FFF ) ? ref - 0x10000 : ref; + function uncompressRAW( info ) { - } + return new DataView( info.array.buffer, info.offset.value, info.size ); - const wdec14Return = { a: 0, b: 0 }; + } - function wdec14( l, h ) { + function uncompressRLE( info ) { - var ls = Int16( l ); - var hs = Int16( h ); + var compressed = info.viewer.buffer.slice( info.offset.value, info.offset.value + info.size ); - var hi = hs; - var ai = ls + ( hi & 1 ) + ( hi >> 1 ); + var rawBuffer = new Uint8Array( decodeRunLength( compressed ) ); + var tmpBuffer = new Uint8Array( rawBuffer.length ); - var as = ai; - var bs = ai - hi; + predictor( rawBuffer ); // revert predictor - wdec14Return.a = as; - wdec14Return.b = bs; + interleaveScalar( rawBuffer, tmpBuffer ); // interleave pixels - } + return new DataView( tmpBuffer.buffer ); + + } - function wav2Decode( j, buffer, nx, ox, ny, oy ) { + function uncompressZIP( info ) { - var n = ( nx > ny ) ? ny : nx; - var p = 1; - var p2; + var compressed = info.array.slice( info.offset.value, info.offset.value + info.size ); - while ( p <= n ) p <<= 1; + if ( typeof Zlib === 'undefined' ) { - p >>= 1; - p2 = p; - p >>= 1; + console.error( 'THREE.EXRLoader: External library Inflate.min.js required, obtain or import from https://github.com/imaya/zlib.js' ); - while ( p >= 1 ) { + } - var py = 0; - var ey = py + oy * ( ny - p2 ); - var oy1 = oy * p; - var oy2 = oy * p2; - var ox1 = ox * p; - var ox2 = ox * p2; - var i00, i01, i10, i11; + var inflate = new Zlib.Inflate( compressed, { resize: true, verify: true } ); // eslint-disable-line no-undef - for ( ; py <= ey; py += oy2 ) { + var rawBuffer = new Uint8Array( inflate.decompress().buffer ); + var tmpBuffer = new Uint8Array( rawBuffer.length ); - var px = py; - var ex = py + ox * ( nx - p2 ); + predictor( rawBuffer ); // revert predictor - for ( ; px <= ex; px += ox2 ) { + interleaveScalar( rawBuffer, tmpBuffer ); // interleave pixels - var p01 = px + ox1; - var p10 = px + oy1; - var p11 = p10 + ox1; + return new DataView( tmpBuffer.buffer ); - wdec14( buffer[ px + j ], buffer[ p10 + j ] ); + } - i00 = wdec14Return.a; - i10 = wdec14Return.b; + function uncompressPIZ( info ) { - wdec14( buffer[ p01 + j ], buffer[ p11 + j ] ); + var inDataView = info.viewer; + var inOffset = { value: info.offset.value }; - i01 = wdec14Return.a; - i11 = wdec14Return.b; + var tmpBufSize = info.width * scanlineBlockSize * ( EXRHeader.channels.length * info.type ); + var outBuffer = new Uint16Array( tmpBufSize ); + var bitmap = new Uint8Array( BITMAP_SIZE ); - wdec14( i00, i01 ); + // Setup channel info + var outBufferEnd = 0; + var pizChannelData = new Array( info.channels ); + for ( var i = 0; i < info.channels; i ++ ) { - buffer[ px + j ] = wdec14Return.a; - buffer[ p01 + j ] = wdec14Return.b; + pizChannelData[ i ] = {}; + pizChannelData[ i ][ 'start' ] = outBufferEnd; + pizChannelData[ i ][ 'end' ] = pizChannelData[ i ][ 'start' ]; + pizChannelData[ i ][ 'nx' ] = info.width; + pizChannelData[ i ][ 'ny' ] = info.lines; + pizChannelData[ i ][ 'size' ] = info.type; - wdec14( i10, i11 ); + outBufferEnd += pizChannelData[ i ].nx * pizChannelData[ i ].ny * pizChannelData[ i ].size; - buffer[ p10 + j ] = wdec14Return.a; - buffer[ p11 + j ] = wdec14Return.b; + } - } + // Read range compression data + var minNonZero = parseUint16( inDataView, inOffset ); + var maxNonZero = parseUint16( inDataView, inOffset ); - if ( nx & p ) { + if ( maxNonZero >= BITMAP_SIZE ) { - var p10 = px + oy1; + throw 'Something is wrong with PIZ_COMPRESSION BITMAP_SIZE'; - wdec14( buffer[ px + j ], buffer[ p10 + j ] ); + } + + if ( minNonZero <= maxNonZero ) { - i00 = wdec14Return.a; - buffer[ p10 + j ] = wdec14Return.b; + for ( var i = 0; i < maxNonZero - minNonZero + 1; i ++ ) { - buffer[ px + j ] = i00; + bitmap[ i + minNonZero ] = parseUint8( inDataView, inOffset ); } } - if ( ny & p ) { + // Reverse LUT + var lut = new Uint16Array( USHORT_RANGE ); + reverseLutFromBitmap( bitmap, lut ); - var px = py; - var ex = py + ox * ( nx - p2 ); + var length = parseUint32( inDataView, inOffset ); - for ( ; px <= ex; px += ox2 ) { + // Huffman decoding + hufUncompress( info.array, inDataView, inOffset, length, outBuffer, outBufferEnd ); - var p01 = px + ox1; + // Wavelet decoding + for ( var i = 0; i < info.channels; ++ i ) { - wdec14( buffer[ px + j ], buffer[ p01 + j ] ); + var cd = pizChannelData[ i ]; - i00 = wdec14Return.a; - buffer[ p01 + j ] = wdec14Return.b; + for ( var j = 0; j < pizChannelData[ i ].size; ++ j ) { - buffer[ px + j ] = i00; + wav2Decode( + outBuffer, + cd.start + j, + cd.nx, + cd.size, + cd.ny, + cd.nx * cd.size + ); } } - p2 = p; - p >>= 1; + // Expand the pixel data to their original range + applyLut( lut, outBuffer, outBufferEnd ); - } + // Rearrange the pixel data into the format expected by the caller. + var tmpOffset = 0; + var tmpBuffer = new Uint8Array( outBuffer.buffer.byteLength ); + for ( var y = 0; y < info.lines; y ++ ) { - return py; + for ( var c = 0; c < info.channels; c ++ ) { - } + var cd = pizChannelData[ c ]; - function hufDecode( encodingTable, decodingTable, uInt8Array, inDataView, inOffset, ni, rlc, no, outBuffer, outOffset ) { + var n = cd.nx * cd.size; + var cp = new Uint8Array( outBuffer.buffer, cd.end * INT16_SIZE, n * INT16_SIZE ); - var c = 0; - var lc = 0; - var outBufferEndOffset = no; - var inOffsetEnd = Math.trunc( inOffset.value + ( ni + 7 ) / 8 ); + tmpBuffer.set( cp, tmpOffset ); + tmpOffset += n * INT16_SIZE; + cd.end += n; + + } - while ( inOffset.value < inOffsetEnd ) { + } - getChar( c, lc, uInt8Array, inOffset ); + return new DataView( tmpBuffer.buffer ); - c = getCharReturn.c; - lc = getCharReturn.lc; + } - while ( lc >= HUF_DECBITS ) { + function uncompressDWA( info ) { - var index = ( c >> ( lc - HUF_DECBITS ) ) & HUF_DECMASK; - var pl = decodingTable[ index ]; + var inDataView = info.viewer; + var inOffset = { value: info.offset.value }; + var outBuffer = new Uint8Array( info.width * info.lines * ( EXRHeader.channels.length * info.type * INT16_SIZE ) ); - if ( pl.len ) { + // Read compression header information + var dwaHeader = { - lc -= pl.len; + version: parseInt64( inDataView, inOffset ), + unknownUncompressedSize: parseInt64( inDataView, inOffset ), + unknownCompressedSize: parseInt64( inDataView, inOffset ), + acCompressedSize: parseInt64( inDataView, inOffset ), + dcCompressedSize: parseInt64( inDataView, inOffset ), + rleCompressedSize: parseInt64( inDataView, inOffset ), + rleUncompressedSize: parseInt64( inDataView, inOffset ), + rleRawSize: parseInt64( inDataView, inOffset ), + totalAcUncompressedCount: parseInt64( inDataView, inOffset ), + totalDcUncompressedCount: parseInt64( inDataView, inOffset ), + acCompression: parseInt64( inDataView, inOffset ) - getCode( pl.lit, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset ); + }; - c = getCodeReturn.c; - lc = getCodeReturn.lc; + if ( dwaHeader.version < 2 ) + throw 'EXRLoader.parse: ' + EXRHeader.compression + ' version ' + dwaHeader.version + ' is unsupported'; - } else { + // Read channel ruleset information + var channelRules = new Array(); + var ruleSize = parseUint16( inDataView, inOffset ) - INT16_SIZE; - if ( ! pl.p ) { + while ( ruleSize > 0 ) { - throw 'hufDecode issues'; + var name = parseNullTerminatedString( inDataView.buffer, inOffset ); + var value = parseUint8( inDataView, inOffset ); + var compression = ( value >> 2 ) & 3; + var csc = ( value >> 4 ) - 1; + var index = new Int8Array( [ csc ] )[ 0 ]; + var type = parseUint8( inDataView, inOffset ); - } + channelRules.push( { + name: name, + index: index, + type: type, + compression: compression, + } ); - var j; + ruleSize -= name.length + 3; - for ( j = 0; j < pl.lit; j ++ ) { + } - var l = hufLength( encodingTable[ pl.p[ j ] ] ); + // Classify channels + var channels = EXRHeader.channels; + var channelData = new Array( info.channels ); - while ( lc < l && inOffset.value < inOffsetEnd ) { + for ( var i = 0; i < info.channels; ++ i ) { - getChar( c, lc, uInt8Array, inOffset ); + var cd = channelData[ i ] = {}; + var channel = channels[ i ]; - c = getCharReturn.c; - lc = getCharReturn.lc; + cd.name = channel.name; + cd.compression = UNKNOWN; + cd.decoded = false; + cd.type = channel.pixelType; + cd.pLinear = channel.pLinear; + cd.width = info.width; + cd.height = info.lines; - } + } - if ( lc >= l ) { + var cscSet = { + idx: new Array( 3 ) + }; - if ( hufCode( encodingTable[ pl.p[ j ] ] ) == ( ( c >> ( lc - l ) ) & ( ( 1 << l ) - 1 ) ) ) { + for ( var offset = 0; offset < info.channels; ++ offset ) { - lc -= l; + var cd = channelData[ offset ]; - getCode( pl.p[ j ], rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset ); + for ( var i = 0; i < channelRules.length; ++ i ) { - c = getCodeReturn.c; - lc = getCodeReturn.lc; + var rule = channelRules[ i ]; - break; + if ( cd.name == rule.name ) { - } + cd.compression = rule.compression; - } + if ( rule.index >= 0 ) { - } + cscSet.idx[ rule.index ] = offset; - if ( j == pl.lit ) { + } - throw 'hufDecode issues'; + cd.offset = offset; } @@ -620,620 +1412,757 @@ THREE.EXRLoader.prototype._parser = function ( buffer ) { } - } + // Read DCT - AC component data + if ( dwaHeader.acCompressedSize > 0 ) { - var i = ( 8 - ni ) & 7; + switch ( dwaHeader.acCompression ) { - c >>= i; - lc -= i; + case STATIC_HUFFMAN: - while ( lc > 0 ) { + var acBuffer = new Uint16Array( dwaHeader.totalAcUncompressedCount ); + hufUncompress( info.array, inDataView, inOffset, dwaHeader.acCompressedSize, acBuffer, dwaHeader.totalAcUncompressedCount ); + break; - var pl = decodingTable[ ( c << ( HUF_DECBITS - lc ) ) & HUF_DECMASK ]; + case DEFLATE: - if ( pl.len ) { + var compressed = info.array.slice( inOffset.value, inOffset.value + dwaHeader.totalAcUncompressedCount ); + var inflate = new Zlib.Inflate( compressed, { resize: true, verify: true } ); + var acBuffer = new Uint16Array( inflate.decompress().buffer ); + inOffset.value += dwaHeader.totalAcUncompressedCount; + break; - lc -= pl.len; + } - getCode( pl.lit, rlc, c, lc, uInt8Array, inDataView, inOffset, outBuffer, outOffset, outBufferEndOffset ); - c = getCodeReturn.c; - lc = getCodeReturn.lc; + } - } else { + // Read DCT - DC component data + if ( dwaHeader.dcCompressedSize > 0 ) { - throw 'hufDecode issues'; + var zlibInfo = { + array: info.array, + offset: inOffset, + size: dwaHeader.dcCompressedSize + }; + var dcBuffer = new Uint16Array( uncompressZIP( zlibInfo ).buffer ); + inOffset.value += dwaHeader.dcCompressedSize; } - } + // Read RLE compressed data + if ( dwaHeader.rleRawSize > 0 ) { - return true; + var compressed = info.array.slice( inOffset.value, inOffset.value + dwaHeader.rleCompressedSize ); + var inflate = new Zlib.Inflate( compressed, { resize: true, verify: true } ); + var rleBuffer = decodeRunLength( inflate.decompress().buffer ); - } + inOffset.value += dwaHeader.rleCompressedSize; - function hufUncompress( uInt8Array, inDataView, inOffset, nCompressed, outBuffer, outOffset, nRaw ) { + } - var initialInOffset = inOffset.value; + // Prepare outbuffer data offset + var outBufferEnd = 0; + var rowOffsets = new Array( channelData.length ); + for ( var i = 0; i < rowOffsets.length; ++ i ) { - var im = parseUint32( inDataView, inOffset ); - var iM = parseUint32( inDataView, inOffset ); + rowOffsets[ i ] = new Array(); - inOffset.value += 4; + } - var nBits = parseUint32( inDataView, inOffset ); + for ( var y = 0; y < info.lines; ++ y ) { - inOffset.value += 4; + for ( var chan = 0; chan < channelData.length; ++ chan ) { - if ( im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE ) { + rowOffsets[ chan ].push( outBufferEnd ); + outBufferEnd += channelData[ chan ].width * info.type * INT16_SIZE; - throw 'Something wrong with HUF_ENCSIZE'; + } - } + } - var freq = new Array( HUF_ENCSIZE ); - var hdec = new Array( HUF_DECSIZE ); + // Lossy DCT decode RGB channels + lossyDctDecode( cscSet, rowOffsets, channelData, acBuffer, dcBuffer, outBuffer ); - hufClearDecTable( hdec ); + // Decode other channels + for ( var i = 0; i < channelData.length; ++ i ) { - var ni = nCompressed - ( inOffset.value - initialInOffset ); + var cd = channelData[ i ]; - hufUnpackEncTable( uInt8Array, inDataView, inOffset, ni, im, iM, freq ); + if ( cd.decoded ) continue; - if ( nBits > 8 * ( nCompressed - ( inOffset.value - initialInOffset ) ) ) { + switch ( cd.compression ) { - throw 'Something wrong with hufUncompress'; + case RLE: - } + var row = 0; + var rleOffset = 0; - hufBuildDecTable( freq, im, iM, hdec ); + for ( var y = 0; y < info.lines; ++ y ) { - hufDecode( freq, hdec, uInt8Array, inDataView, inOffset, nBits, iM, nRaw, outBuffer, outOffset ); + var rowOffsetBytes = rowOffsets[ i ][ row ]; - } + for ( var x = 0; x < cd.width; ++ x ) { - function applyLut( lut, data, nData ) { + for ( var byte = 0; byte < INT16_SIZE * cd.type; ++ byte ) { - for ( var i = 0; i < nData; ++ i ) { + outBuffer[ rowOffsetBytes ++ ] = rleBuffer[ rleOffset + byte * cd.width * cd.height ]; - data[ i ] = lut[ data[ i ] ]; + } - } + rleOffset ++; - } + } - function decompressPIZ( outBuffer, outOffset, uInt8Array, inDataView, inOffset, tmpBufSize, num_channels, exrChannelInfos, dataWidth, num_lines ) { + row ++; - var bitmap = new Uint8Array( BITMAP_SIZE ); + } + + break; + + case LOSSY_DCT: // skip + + default: + throw 'EXRLoader.parse: unsupported channel compression'; - var minNonZero = parseUint16( inDataView, inOffset ); - var maxNonZero = parseUint16( inDataView, inOffset ); + } - if ( maxNonZero >= BITMAP_SIZE ) { + } - throw 'Something is wrong with PIZ_COMPRESSION BITMAP_SIZE'; + return new DataView( outBuffer.buffer ); } - if ( minNonZero <= maxNonZero ) { + function parseNullTerminatedString( buffer, offset ) { - for ( var i = 0; i < maxNonZero - minNonZero + 1; i ++ ) { + var uintBuffer = new Uint8Array( buffer ); + var endOffset = 0; - bitmap[ i + minNonZero ] = parseUint8( inDataView, inOffset ); + while ( uintBuffer[ offset.value + endOffset ] != 0 ) { + + endOffset += 1; } + var stringValue = new TextDecoder().decode( + uintBuffer.slice( offset.value, offset.value + endOffset ) + ); + + offset.value = offset.value + endOffset + 1; + + return stringValue; + } - var lut = new Uint16Array( USHORT_RANGE ); - reverseLutFromBitmap( bitmap, lut ); + function parseFixedLengthString( buffer, offset, size ) { - var length = parseUint32( inDataView, inOffset ); + var stringValue = new TextDecoder().decode( + new Uint8Array( buffer ).slice( offset.value, offset.value + size ) + ); - hufUncompress( uInt8Array, inDataView, inOffset, length, outBuffer, outOffset, tmpBufSize ); + offset.value = offset.value + size; - var pizChannelData = new Array( num_channels ); + return stringValue; + + } - var outBufferEnd = 0; + function parseUlong( dataView, offset ) { - for ( var i = 0; i < num_channels; i ++ ) { + var uLong = dataView.getUint32( 0, true ); - pizChannelData[ i ] = {}; - pizChannelData[ i ][ 'start' ] = outBufferEnd; - pizChannelData[ i ][ 'end' ] = pizChannelData[ i ][ 'start' ]; - pizChannelData[ i ][ 'nx' ] = dataWidth; - pizChannelData[ i ][ 'ny' ] = num_lines; - pizChannelData[ i ][ 'size' ] = 1; + offset.value = offset.value + ULONG_SIZE; - outBufferEnd += pizChannelData[ i ].nx * pizChannelData[ i ].ny * pizChannelData[ i ].size; + return uLong; } - var fooOffset = 0; + function parseUint32( dataView, offset ) { - for ( var i = 0; i < num_channels; i ++ ) { + var Uint32 = dataView.getUint32( offset.value, true ); - for ( var j = 0; j < pizChannelData[ i ].size; ++ j ) { + offset.value = offset.value + INT32_SIZE; - fooOffset += wav2Decode( - j + fooOffset, - outBuffer, - pizChannelData[ i ].nx, - pizChannelData[ i ].size, - pizChannelData[ i ].ny, - pizChannelData[ i ].nx * pizChannelData[ i ].size - ); + return Uint32; - } + } + + function parseUint8Array( uInt8Array, offset ) { + + var Uint8 = uInt8Array[ offset.value ]; + + offset.value = offset.value + INT8_SIZE; + + return Uint8; } - applyLut( lut, outBuffer, outBufferEnd ); + function parseUint8( dataView, offset ) { - return true; + var Uint8 = dataView.getUint8( offset.value ); - } + offset.value = offset.value + INT8_SIZE; + + return Uint8; - function parseNullTerminatedString( buffer, offset ) { + } + + function parseInt64( dataView, offset ) { - var uintBuffer = new Uint8Array( buffer ); - var endOffset = 0; + var int = Number( dataView.getBigInt64( offset.value, true ) ); - while ( uintBuffer[ offset.value + endOffset ] != 0 ) { + offset.value += ULONG_SIZE; - endOffset += 1; + return int; } - var stringValue = new TextDecoder().decode( - uintBuffer.slice( offset.value, offset.value + endOffset ) - ); + function parseFloat32( dataView, offset ) { - offset.value = offset.value + endOffset + 1; + var float = dataView.getFloat32( offset.value, true ); - return stringValue; + offset.value += FLOAT32_SIZE; - } + return float; - function parseFixedLengthString( buffer, offset, size ) { + } - var stringValue = new TextDecoder().decode( - new Uint8Array( buffer ).slice( offset.value, offset.value + size ) - ); + // https://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript + function decodeFloat16( binary ) { - offset.value = offset.value + size; + var exponent = ( binary & 0x7C00 ) >> 10, + fraction = binary & 0x03FF; - return stringValue; + return ( binary >> 15 ? - 1 : 1 ) * ( + exponent ? + ( + exponent === 0x1F ? + fraction ? NaN : Infinity : + Math.pow( 2, exponent - 15 ) * ( 1 + fraction / 0x400 ) + ) : + 6.103515625e-5 * ( fraction / 0x400 ) + ); - } + } - function parseUlong( dataView, offset ) { + var encodeFloat16 = ( function () { - var uLong = dataView.getUint32( 0, true ); + // Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410 - offset.value = offset.value + ULONG_SIZE; + var floatView = new Float32Array( 1 ); + var int32View = new Int32Array( floatView.buffer ); - return uLong; + /* This method is faster than the OpenEXR implementation (very often + * used, eg. in Ogre), with the additional benefit of rounding, inspired + * by James Tursa?s half-precision code. */ + return function toHalf( val ) { - } + floatView[ 0 ] = val; + var x = int32View[ 0 ]; - function parseUint32( dataView, offset ) { + var bits = ( x >> 16 ) & 0x8000; /* Get the sign */ + var m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */ + var e = ( x >> 23 ) & 0xff; /* Using int is faster here */ - var Uint32 = dataView.getUint32( offset.value, true ); + /* If zero, or denormal, or exponent underflows too much for a denormal + * half, return signed zero. */ + if ( e < 103 ) return bits; - offset.value = offset.value + INT32_SIZE; + /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */ + if ( e > 142 ) { - return Uint32; + bits |= 0x7c00; + /* If exponent was 0xff and one mantissa bit was set, it means NaN, + * not Inf, so make sure we set one mantissa bit too. */ + bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff ); + return bits; - } + } - function parseUint8Array( uInt8Array, offset ) { + /* If exponent underflows but not too much, return a denormal */ + if ( e < 113 ) { - var Uint8 = uInt8Array[ offset.value ]; + m |= 0x0800; + /* Extra rounding may overflow and set mantissa to 0 and exponent + * to 1, which is OK. */ + bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 ); + return bits; - offset.value = offset.value + INT8_SIZE; + } - return Uint8; + bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 ); + /* Extra rounding. An overflow will set mantissa to 0 and increment + * the exponent, which is OK. */ + bits += m & 1; + return bits; - } + }; - function parseUint8( dataView, offset ) { + } )(); - var Uint8 = dataView.getUint8( offset.value ); + function parseUint16( dataView, offset ) { - offset.value = offset.value + INT8_SIZE; + var Uint16 = dataView.getUint16( offset.value, true ); - return Uint8; + offset.value += INT16_SIZE; - } + return Uint16; - function parseFloat32( dataView, offset ) { + } - var float = dataView.getFloat32( offset.value, true ); + function parseFloat16( buffer, offset ) { - offset.value += FLOAT32_SIZE; + return decodeFloat16( parseUint16( buffer, offset ) ); - return float; + } - } + function parseChlist( dataView, buffer, offset, size ) { - // https://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript - function decodeFloat16( binary ) { + var startOffset = offset.value; + var channels = []; - var exponent = ( binary & 0x7C00 ) >> 10, - fraction = binary & 0x03FF; + while ( offset.value < ( startOffset + size - 1 ) ) { - return ( binary >> 15 ? - 1 : 1 ) * ( - exponent ? - ( - exponent === 0x1F ? - fraction ? NaN : Infinity : - Math.pow( 2, exponent - 15 ) * ( 1 + fraction / 0x400 ) - ) : - 6.103515625e-5 * ( fraction / 0x400 ) - ); + var name = parseNullTerminatedString( buffer, offset ); + var pixelType = parseUint32( dataView, offset ); // TODO: Cast this to UINT, HALF or FLOAT + var pLinear = parseUint8( dataView, offset ); + offset.value += 3; // reserved, three chars + var xSampling = parseUint32( dataView, offset ); + var ySampling = parseUint32( dataView, offset ); - } + channels.push( { + name: name, + pixelType: pixelType, + pLinear: pLinear, + xSampling: xSampling, + ySampling: ySampling + } ); - function parseUint16( dataView, offset ) { + } - var Uint16 = dataView.getUint16( offset.value, true ); + offset.value += 1; - offset.value += INT16_SIZE; + return channels; - return Uint16; + } - } + function parseChromaticities( dataView, offset ) { - function parseFloat16( buffer, offset ) { + var redX = parseFloat32( dataView, offset ); + var redY = parseFloat32( dataView, offset ); + var greenX = parseFloat32( dataView, offset ); + var greenY = parseFloat32( dataView, offset ); + var blueX = parseFloat32( dataView, offset ); + var blueY = parseFloat32( dataView, offset ); + var whiteX = parseFloat32( dataView, offset ); + var whiteY = parseFloat32( dataView, offset ); - return decodeFloat16( parseUint16( buffer, offset ) ); + return { redX: redX, redY: redY, greenX: greenX, greenY: greenY, blueX: blueX, blueY: blueY, whiteX: whiteX, whiteY: whiteY }; - } + } + + function parseCompression( dataView, offset ) { + + var compressionCodes = [ + 'NO_COMPRESSION', + 'RLE_COMPRESSION', + 'ZIPS_COMPRESSION', + 'ZIP_COMPRESSION', + 'PIZ_COMPRESSION', + 'PXR24_COMPRESSION', + 'B44_COMPRESSION', + 'B44A_COMPRESSION', + 'DWAA_COMPRESSION', + 'DWAB_COMPRESSION' + ]; + + var compression = parseUint8( dataView, offset ); - function parseChlist( dataView, buffer, offset, size ) { + return compressionCodes[ compression ]; - var startOffset = offset.value; - var channels = []; + } - while ( offset.value < ( startOffset + size - 1 ) ) { + function parseBox2i( dataView, offset ) { - var name = parseNullTerminatedString( buffer, offset ); - var pixelType = parseUint32( dataView, offset ); // TODO: Cast this to UINT, HALF or FLOAT - var pLinear = parseUint8( dataView, offset ); - offset.value += 3; // reserved, three chars - var xSampling = parseUint32( dataView, offset ); - var ySampling = parseUint32( dataView, offset ); + var xMin = parseUint32( dataView, offset ); + var yMin = parseUint32( dataView, offset ); + var xMax = parseUint32( dataView, offset ); + var yMax = parseUint32( dataView, offset ); - channels.push( { - name: name, - pixelType: pixelType, - pLinear: pLinear, - xSampling: xSampling, - ySampling: ySampling - } ); + return { xMin: xMin, yMin: yMin, xMax: xMax, yMax: yMax }; } - offset.value += 1; + function parseLineOrder( dataView, offset ) { - return channels; + var lineOrders = [ + 'INCREASING_Y' + ]; - } + var lineOrder = parseUint8( dataView, offset ); - function parseChromaticities( dataView, offset ) { + return lineOrders[ lineOrder ]; - var redX = parseFloat32( dataView, offset ); - var redY = parseFloat32( dataView, offset ); - var greenX = parseFloat32( dataView, offset ); - var greenY = parseFloat32( dataView, offset ); - var blueX = parseFloat32( dataView, offset ); - var blueY = parseFloat32( dataView, offset ); - var whiteX = parseFloat32( dataView, offset ); - var whiteY = parseFloat32( dataView, offset ); + } - return { redX: redX, redY: redY, greenX: greenX, greenY: greenY, blueX: blueX, blueY: blueY, whiteX: whiteX, whiteY: whiteY }; + function parseV2f( dataView, offset ) { - } + var x = parseFloat32( dataView, offset ); + var y = parseFloat32( dataView, offset ); - function parseCompression( dataView, offset ) { + return [ x, y ]; - var compressionCodes = [ - 'NO_COMPRESSION', - 'RLE_COMPRESSION', - 'ZIPS_COMPRESSION', - 'ZIP_COMPRESSION', - 'PIZ_COMPRESSION', - 'PXR24_COMPRESSION', - 'B44_COMPRESSION', - 'B44A_COMPRESSION', - 'DWAA_COMPRESSION', - 'DWAB_COMPRESSION' - ]; + } - var compression = parseUint8( dataView, offset ); + function parseValue( dataView, buffer, offset, type, size ) { - return compressionCodes[ compression ]; + if ( type === 'string' || type === 'stringvector' || type === 'iccProfile' ) { - } + return parseFixedLengthString( buffer, offset, size ); - function parseBox2i( dataView, offset ) { + } else if ( type === 'chlist' ) { - var xMin = parseUint32( dataView, offset ); - var yMin = parseUint32( dataView, offset ); - var xMax = parseUint32( dataView, offset ); - var yMax = parseUint32( dataView, offset ); + return parseChlist( dataView, buffer, offset, size ); - return { xMin: xMin, yMin: yMin, xMax: xMax, yMax: yMax }; + } else if ( type === 'chromaticities' ) { - } + return parseChromaticities( dataView, offset ); - function parseLineOrder( dataView, offset ) { + } else if ( type === 'compression' ) { - var lineOrders = [ - 'INCREASING_Y' - ]; + return parseCompression( dataView, offset ); - var lineOrder = parseUint8( dataView, offset ); + } else if ( type === 'box2i' ) { - return lineOrders[ lineOrder ]; + return parseBox2i( dataView, offset ); - } + } else if ( type === 'lineOrder' ) { - function parseV2f( dataView, offset ) { + return parseLineOrder( dataView, offset ); - var x = parseFloat32( dataView, offset ); - var y = parseFloat32( dataView, offset ); + } else if ( type === 'float' ) { - return [ x, y ]; + return parseFloat32( dataView, offset ); - } + } else if ( type === 'v2f' ) { - function parseValue( dataView, buffer, offset, type, size ) { + return parseV2f( dataView, offset ); - if ( type === 'string' || type === 'iccProfile' ) { + } else if ( type === 'int' ) { - return parseFixedLengthString( buffer, offset, size ); + return parseUint32( dataView, offset ); - } else if ( type === 'chlist' ) { + } else { - return parseChlist( dataView, buffer, offset, size ); + throw 'Cannot parse value for unsupported type: ' + type; - } else if ( type === 'chromaticities' ) { + } - return parseChromaticities( dataView, offset ); + } - } else if ( type === 'compression' ) { + var bufferDataView = new DataView( buffer ); + var uInt8Array = new Uint8Array( buffer ); - return parseCompression( dataView, offset ); + var EXRHeader = {}; - } else if ( type === 'box2i' ) { + bufferDataView.getUint32( 0, true ); // magic + bufferDataView.getUint8( 4, true ); // versionByteZero + bufferDataView.getUint8( 5, true ); // fullMask - return parseBox2i( dataView, offset ); + // start of header - } else if ( type === 'lineOrder' ) { + var offset = { value: 8 }; // start at 8, after magic stuff - return parseLineOrder( dataView, offset ); + var keepReading = true; - } else if ( type === 'float' ) { + while ( keepReading ) { - return parseFloat32( dataView, offset ); + var attributeName = parseNullTerminatedString( buffer, offset ); - } else if ( type === 'v2f' ) { + if ( attributeName == 0 ) { - return parseV2f( dataView, offset ); + keepReading = false; - } else if ( type === 'int' ) { + } else { - return parseUint32( dataView, offset ); + var attributeType = parseNullTerminatedString( buffer, offset ); + var attributeSize = parseUint32( bufferDataView, offset ); + var attributeValue = parseValue( bufferDataView, buffer, offset, attributeType, attributeSize ); - } else { + EXRHeader[ attributeName ] = attributeValue; - throw 'Cannot parse value for unsupported type: ' + type; + } } - } + // offsets + var dataWindowHeight = EXRHeader.dataWindow.yMax + 1; - var bufferDataView = new DataView( buffer ); - var uInt8Array = new Uint8Array( buffer ); + var uncompress; + var scanlineBlockSize; - var EXRHeader = {}; + switch ( EXRHeader.compression ) { - bufferDataView.getUint32( 0, true ); // magic - bufferDataView.getUint8( 4, true ); // versionByteZero - bufferDataView.getUint8( 5, true ); // fullMask + case 'NO_COMPRESSION': - // start of header + scanlineBlockSize = 1; + uncompress = uncompressRAW; + break; - var offset = { value: 8 }; // start at 8, after magic stuff + case 'RLE_COMPRESSION': - var keepReading = true; + scanlineBlockSize = 1; + uncompress = uncompressRLE; + break; - while ( keepReading ) { + case 'ZIPS_COMPRESSION': - var attributeName = parseNullTerminatedString( buffer, offset ); + scanlineBlockSize = 1; + uncompress = uncompressZIP; + break; - if ( attributeName == 0 ) { + case 'ZIP_COMPRESSION': - keepReading = false; + scanlineBlockSize = 16; + uncompress = uncompressZIP; + break; - } else { + case 'PIZ_COMPRESSION': - var attributeType = parseNullTerminatedString( buffer, offset ); - var attributeSize = parseUint32( bufferDataView, offset ); - var attributeValue = parseValue( bufferDataView, buffer, offset, attributeType, attributeSize ); + scanlineBlockSize = 32; + uncompress = uncompressPIZ; + break; - EXRHeader[ attributeName ] = attributeValue; + case 'DWAA_COMPRESSION': - } + scanlineBlockSize = 32; + uncompress = uncompressDWA; + break; - } + case 'DWAB_COMPRESSION': + + scanlineBlockSize = 256; + uncompress = uncompressDWA; + break; - // offsets + default: - var dataWindowHeight = EXRHeader.dataWindow.yMax + 1; - var scanlineBlockSize = 1; // 1 for NO_COMPRESSION + throw 'EXRLoader.parse: ' + EXRHeader.compression + ' is unsupported'; - if ( EXRHeader.compression === 'PIZ_COMPRESSION' ) { + } - scanlineBlockSize = 32; + var size_t; + var getValue; - } + // mixed pixelType not supported + var pixelType = EXRHeader.channels[ 0 ].pixelType; - var numBlocks = dataWindowHeight / scanlineBlockSize; + if ( pixelType === 1 ) { // half - for ( var i = 0; i < numBlocks; i ++ ) { + switch ( this.type ) { - parseUlong( bufferDataView, offset ); // scanlineOffset + case THREE.FloatType: - } + getValue = parseFloat16; + size_t = INT16_SIZE; + break; + + case THREE.HalfFloatType: - // we should be passed the scanline offset table, start reading pixel data + getValue = parseUint16; + size_t = INT16_SIZE; + break; - var width = EXRHeader.dataWindow.xMax - EXRHeader.dataWindow.xMin + 1; - var height = EXRHeader.dataWindow.yMax - EXRHeader.dataWindow.yMin + 1; - var numChannels = EXRHeader.channels.length; + } - switch ( this.type ) { + } else if ( pixelType === 2 ) { // float - case THREE.FloatType: + switch ( this.type ) { - var byteArray = new Float32Array( width * height * numChannels ); - break; + case THREE.FloatType: - case THREE.HalfFloatType: + getValue = parseFloat32; + size_t = FLOAT32_SIZE; + break; - var byteArray = new Uint16Array( width * height * numChannels ); - break; + case THREE.HalfFloatType: - default: + throw 'EXRLoader.parse: unsupported HalfFloatType texture for FloatType image file.'; - console.error( 'THREE.EXRLoader: unsupported type: ', this.type ); - break; + } - } + } else { - var channelOffsets = { - R: 0, - G: 1, - B: 2, - A: 3 - }; + throw 'EXRLoader.parse: unsupported pixelType ' + pixelType + ' for ' + EXRHeader.compression + '.'; - if ( EXRHeader.compression === 'NO_COMPRESSION' ) { + } - for ( var y = 0; y < height; y ++ ) { + var numBlocks = dataWindowHeight / scanlineBlockSize; - var y_scanline = parseUint32( bufferDataView, offset ); - parseUint32( bufferDataView, offset ); // dataSize + for ( var i = 0; i < numBlocks; i ++ ) { - for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) { + parseUlong( bufferDataView, offset ); // scanlineOffset - var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ]; + } - if ( EXRHeader.channels[ channelID ].pixelType === 1 ) { // half + // we should be passed the scanline offset table, start reading pixel data - for ( var x = 0; x < width; x ++ ) { + var width = EXRHeader.dataWindow.xMax - EXRHeader.dataWindow.xMin + 1; + var height = EXRHeader.dataWindow.yMax - EXRHeader.dataWindow.yMin + 1; + // Firefox only supports RGBA (half) float textures + // var numChannels = EXRHeader.channels.length; + var numChannels = 4; + var size = width * height * numChannels; - switch ( this.type ) { + // Fill initially with 1s for the alpha value if the texture is not RGBA, RGB values will be overwritten + switch ( this.type ) { - case THREE.FloatType: + case THREE.FloatType: - var val = parseFloat16( bufferDataView, offset ); - break; + var byteArray = new Float32Array( size ); - case THREE.HalfFloatType: + if ( EXRHeader.channels.length < numChannels ) { - var val = parseUint16( bufferDataView, offset ); - break; + byteArray.fill( 1, 0, size ); - } + } - byteArray[ ( ( ( height - y_scanline ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val; + break; - } + case THREE.HalfFloatType: - } else { + var byteArray = new Uint16Array( size ); + + if ( EXRHeader.channels.length < numChannels ) { - throw 'EXRLoader._parser: unsupported pixelType ' + EXRHeader.channels[ channelID ].pixelType + '. Only pixelType is 1 (HALF) is supported.'; + byteArray.fill( 0x3C00, 0, size ); // Uint16Array holds half float data, 0x3C00 is 1 } - } + break; + + default: + + console.error( 'THREE.EXRLoader: unsupported type: ', this.type ); + break; } - } else if ( EXRHeader.compression === 'PIZ_COMPRESSION' ) { + var channelOffsets = { + R: 0, + G: 1, + B: 2, + A: 3 + }; + + var compressionInfo = { + + size: 0, + width: width, + lines: scanlineBlockSize, + + offset: offset, + array: uInt8Array, + viewer: bufferDataView, + + type: pixelType, + channels: EXRHeader.channels.length, + + }; + + var line; + var size; + var viewer; + var tmpOffset = { value: 0 }; for ( var scanlineBlockIdx = 0; scanlineBlockIdx < height / scanlineBlockSize; scanlineBlockIdx ++ ) { - parseUint32( bufferDataView, offset ); // line_no - parseUint32( bufferDataView, offset ); // data_len + line = parseUint32( bufferDataView, offset ); // line_no + size = parseUint32( bufferDataView, offset ); // data_len + + compressionInfo.lines = ( line + scanlineBlockSize > height ) ? height - line : scanlineBlockSize; + compressionInfo.offset = offset; + compressionInfo.size = size; - var tmpBufferSize = width * scanlineBlockSize * ( EXRHeader.channels.length * BYTES_PER_HALF ); - var tmpBuffer = new Uint16Array( tmpBufferSize ); - var tmpOffset = { value: 0 }; + viewer = uncompress( compressionInfo ); - decompressPIZ( tmpBuffer, tmpOffset, uInt8Array, bufferDataView, offset, tmpBufferSize, numChannels, EXRHeader.channels, width, scanlineBlockSize ); + offset.value += size; for ( var line_y = 0; line_y < scanlineBlockSize; line_y ++ ) { + var true_y = line_y + ( scanlineBlockIdx * scanlineBlockSize ); + + if ( true_y >= height ) break; + for ( var channelID = 0; channelID < EXRHeader.channels.length; channelID ++ ) { var cOff = channelOffsets[ EXRHeader.channels[ channelID ].name ]; - if ( EXRHeader.channels[ channelID ].pixelType === 1 ) { // half + for ( var x = 0; x < width; x ++ ) { - for ( var x = 0; x < width; x ++ ) { + var idx = ( line_y * ( EXRHeader.channels.length * width ) ) + ( channelID * width ) + x; + tmpOffset.value = idx * size_t; - var idx = ( channelID * ( scanlineBlockSize * width ) ) + ( line_y * width ) + x; + var val = getValue( viewer, tmpOffset ); - switch ( this.type ) { + byteArray[ ( ( ( height - 1 - true_y ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val; - case THREE.FloatType: + } - var val = decodeFloat16( tmpBuffer[ idx ] ); - break; + } - case THREE.HalfFloatType: + } - var val = tmpBuffer[ idx ]; - break; + } - } + return { + header: EXRHeader, + width: width, + height: height, + data: byteArray, + format: numChannels === 4 ? THREE.RGBAFormat : THREE.RGBFormat, + type: this.type + }; - var true_y = line_y + ( scanlineBlockIdx * scanlineBlockSize ); + }, - byteArray[ ( ( ( height - true_y ) * ( width * numChannels ) ) + ( x * numChannels ) ) + cOff ] = val; + setDataType: function ( value ) { - } + this.type = value; + return this; - } else { + }, - throw 'EXRLoader._parser: unsupported pixelType ' + EXRHeader.channels[ channelID ].pixelType + '. Only pixelType is 1 (HALF) is supported.'; + load: function ( url, onLoad, onProgress, onError ) { - } + function onLoadCallback( texture, texData ) { - } + switch ( texture.type ) { + + case THREE.FloatType: + + texture.encoding = THREE.LinearEncoding; + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.generateMipmaps = false; + texture.flipY = false; + break; + + case THREE.HalfFloatType: + + texture.encoding = THREE.LinearEncoding; + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.generateMipmaps = false; + texture.flipY = false; + break; } - } + if ( onLoad ) onLoad( texture, texData ); - } else { + } - throw 'EXRLoader._parser: ' + EXRHeader.compression + ' is unsupported'; + return THREE.DataTextureLoader.prototype.load.call( this, url, onLoadCallback, onProgress, onError ); } - return { - header: EXRHeader, - width: width, - height: height, - data: byteArray, - format: EXRHeader.channels.length == 4 ? THREE.RGBAFormat : THREE.RGBFormat, - type: this.type - }; - -}; +} ); diff --git a/examples/js/loaders/EquirectangularToCubeGenerator.js b/examples/js/loaders/EquirectangularToCubeGenerator.js deleted file mode 100644 index 841c714cbc7866..00000000000000 --- a/examples/js/loaders/EquirectangularToCubeGenerator.js +++ /dev/null @@ -1,236 +0,0 @@ -/** -* @author Richard M. / https://github.com/richardmonette -* @author WestLangley / http://github.com/WestLangley -*/ - -THREE.CubemapGenerator = function ( renderer ) { - - this.renderer = renderer; - -}; - -THREE.CubemapGenerator.prototype.fromEquirectangular = function ( texture, options ) { - - options = options || {}; - - var scene = new THREE.Scene(); - - var shader = { - - uniforms: { - tEquirect: { value: null }, - }, - - vertexShader: - - ` - varying vec3 vWorldDirection; - - //include - vec3 transformDirection( in vec3 dir, in mat4 matrix ) { - - return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); - - } - - void main() { - - vWorldDirection = transformDirection( position, modelMatrix ); - - #include - #include - - } - `, - - fragmentShader: - - ` - uniform sampler2D tEquirect; - - varying vec3 vWorldDirection; - - //include - #define RECIPROCAL_PI 0.31830988618 - #define RECIPROCAL_PI2 0.15915494 - - void main() { - - vec3 direction = normalize( vWorldDirection ); - - vec2 sampleUV; - - sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; - - sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5; - - gl_FragColor = texture2D( tEquirect, sampleUV ); - - } - ` - }; - - var material = new THREE.ShaderMaterial( { - - type: 'CubemapFromEquirect', - - uniforms: THREE.UniformsUtils.clone( shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader, - side: THREE.BackSide, - blending: THREE.NoBlending - - } ); - - material.uniforms.tEquirect.value = texture; - - var mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 5, 5, 5 ), material ); - - scene.add( mesh ); - - var resolution = options.resolution || 512; - - var params = { - type: texture.type, - format: texture.format, - encoding: texture.encoding, - generateMipmaps: ( options.generateMipmaps !== undefined ) ? options.generateMipmaps : texture.generateMipmaps, - minFilter: ( options.minFilter !== undefined ) ? options.minFilter : texture.minFilter, - magFilter: ( options.magFilter !== undefined ) ? options.magFilter : texture.magFilter - }; - - var camera = new THREE.CubeCamera( 1, 10, resolution, params ); - - camera.update( this.renderer, scene ); - - mesh.geometry.dispose(); - mesh.material.dispose(); - - return camera.renderTarget; - -}; - -// - -THREE.EquirectangularToCubeGenerator = ( function () { - - var camera = new THREE.PerspectiveCamera( 90, 1, 0.1, 10 ); - var scene = new THREE.Scene(); - var boxMesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 1, 1, 1 ), getShader() ); - boxMesh.material.side = THREE.BackSide; - scene.add( boxMesh ); - - var EquirectangularToCubeGenerator = function ( sourceTexture, options ) { - - options = options || {}; - - this.sourceTexture = sourceTexture; - this.resolution = options.resolution || 512; - - this.views = [ - { t: [ 1, 0, 0 ], u: [ 0, - 1, 0 ] }, - { t: [ - 1, 0, 0 ], u: [ 0, - 1, 0 ] }, - { t: [ 0, 1, 0 ], u: [ 0, 0, 1 ] }, - { t: [ 0, - 1, 0 ], u: [ 0, 0, - 1 ] }, - { t: [ 0, 0, 1 ], u: [ 0, - 1, 0 ] }, - { t: [ 0, 0, - 1 ], u: [ 0, - 1, 0 ] }, - ]; - - var params = { - format: options.format || this.sourceTexture.format, - magFilter: this.sourceTexture.magFilter, - minFilter: this.sourceTexture.minFilter, - type: options.type || this.sourceTexture.type, - generateMipmaps: this.sourceTexture.generateMipmaps, - anisotropy: this.sourceTexture.anisotropy, - encoding: this.sourceTexture.encoding - }; - - this.renderTarget = new THREE.WebGLRenderTargetCube( this.resolution, this.resolution, params ); - - }; - - EquirectangularToCubeGenerator.prototype = { - - constructor: EquirectangularToCubeGenerator, - - update: function ( renderer ) { - - var currentRenderTarget = renderer.getRenderTarget(); - - boxMesh.material.uniforms.equirectangularMap.value = this.sourceTexture; - - for ( var i = 0; i < 6; i ++ ) { - - var v = this.views[ i ]; - - camera.position.set( 0, 0, 0 ); - camera.up.set( v.u[ 0 ], v.u[ 1 ], v.u[ 2 ] ); - camera.lookAt( v.t[ 0 ], v.t[ 1 ], v.t[ 2 ] ); - - renderer.setRenderTarget( this.renderTarget, i ); - renderer.clear(); - renderer.render( scene, camera ); - - } - - renderer.setRenderTarget( currentRenderTarget ); - - return this.renderTarget.texture; - - }, - - dispose: function () { - - this.renderTarget.dispose(); - - } - - }; - - function getShader() { - - var shaderMaterial = new THREE.ShaderMaterial( { - - uniforms: { - "equirectangularMap": { value: null }, - }, - - vertexShader: - "varying vec3 localPosition;\n\ - \n\ - void main() {\n\ - localPosition = position;\n\ - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\ - }", - - fragmentShader: - "#include \n\ - varying vec3 localPosition;\n\ - uniform sampler2D equirectangularMap;\n\ - \n\ - vec2 EquirectangularSampleUV(vec3 v) {\n\ - vec2 uv = vec2(atan(v.z, v.x), asin(v.y));\n\ - uv *= vec2(0.1591, 0.3183); // inverse atan\n\ - uv += 0.5;\n\ - return uv;\n\ - }\n\ - \n\ - void main() {\n\ - vec2 uv = EquirectangularSampleUV(normalize(localPosition));\n\ - gl_FragColor = texture2D(equirectangularMap, uv);\n\ - }", - - blending: THREE.NoBlending - - } ); - - shaderMaterial.type = 'EquirectangularToCubeGenerator'; - - return shaderMaterial; - - } - - return EquirectangularToCubeGenerator; - -} )(); diff --git a/examples/js/loaders/FBXLoader.js b/examples/js/loaders/FBXLoader.js index 1932e35c3108bb..c2339db037a6fe 100644 --- a/examples/js/loaders/FBXLoader.js +++ b/examples/js/loaders/FBXLoader.js @@ -27,21 +27,19 @@ THREE.FBXLoader = ( function () { function FBXLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); } - FBXLoader.prototype = { + FBXLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: FBXLoader, - crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { var self = this; - var path = ( self.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : self.path; + var path = ( self.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : self.path; var loader = new THREE.FileLoader( this.manager ); loader.setPath( self.path ); @@ -69,27 +67,6 @@ THREE.FBXLoader = ( function () { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - parse: function ( FBXBuffer, path ) { if ( isFbxFormatBinary( FBXBuffer ) ) { @@ -120,16 +97,17 @@ THREE.FBXLoader = ( function () { var textureLoader = new THREE.TextureLoader( this.manager ).setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin ); - return new FBXTreeParser( textureLoader ).parse( fbxTree ); + return new FBXTreeParser( textureLoader, this.manager ).parse( fbxTree ); } - }; + } ); // Parse the FBXTree object returned by the BinaryParser or TextParser and return a THREE.Group - function FBXTreeParser( textureLoader ) { + function FBXTreeParser( textureLoader, manager ) { this.textureLoader = textureLoader; + this.manager = manager; } @@ -288,7 +266,7 @@ THREE.FBXLoader = ( function () { case 'tga': - if ( THREE.Loader.Handlers.get( '.tga' ) === null ) { + if ( this.manager.getHandler( '.tga' ) === null ) { console.warn( 'FBXLoader: TGA loader not found, skipping ', fileName ); @@ -401,7 +379,7 @@ THREE.FBXLoader = ( function () { if ( extension === 'tga' ) { - var loader = THREE.Loader.Handlers.get( '.tga' ); + var loader = this.manager.getHandler( '.tga' ); if ( loader === null ) { @@ -844,7 +822,7 @@ THREE.FBXLoader = ( function () { var transform = generateTransform( node.userData.transformData ); - node.applyMatrix( transform ); + node.applyMatrix4( transform ); } @@ -905,7 +883,8 @@ THREE.FBXLoader = ( function () { } - model.name = THREE.PropertyBinding.sanitizeNodeName( node.attrName ); + model.name = node.attrName ? THREE.PropertyBinding.sanitizeNodeName( node.attrName ) : ''; + model.ID = id; } @@ -939,7 +918,8 @@ THREE.FBXLoader = ( function () { bone.matrixWorld.copy( rawBone.transformLink ); // set name and id here - otherwise in cases where "subBone" is created it will not have a name / id - bone.name = THREE.PropertyBinding.sanitizeNodeName( name ); + + bone.name = name ? THREE.PropertyBinding.sanitizeNodeName( name ) : ''; bone.ID = id; skeleton.bones[ i ] = bone; @@ -1142,7 +1122,7 @@ THREE.FBXLoader = ( function () { if ( lightAttribute.InnerAngle !== undefined ) { - angle = THREE.Math.degToRad( lightAttribute.InnerAngle.value ); + angle = THREE.MathUtils.degToRad( lightAttribute.InnerAngle.value ); } @@ -1152,7 +1132,7 @@ THREE.FBXLoader = ( function () { // TODO: this is not correct - FBX calculates outer and inner angle in degrees // with OuterAngle > InnerAngle && OuterAngle <= Math.PI // while three.js uses a penumbra between (0, 1) to attenuate the inner angle - penumbra = THREE.Math.degToRad( lightAttribute.OuterAngle.value ); + penumbra = THREE.MathUtils.degToRad( lightAttribute.OuterAngle.value ); penumbra = Math.max( penumbra, 1 ); } @@ -1222,7 +1202,7 @@ THREE.FBXLoader = ( function () { materials.forEach( function ( material ) { - material.vertexColors = THREE.VertexColors; + material.vertexColors = true; } ); @@ -1551,7 +1531,7 @@ THREE.FBXLoader = ( function () { parseMeshGeometry: function ( relationships, geoNode, deformers ) { var skeletons = deformers.skeletons; - var morphTargets = deformers.morphTargets; + var morphTargets = []; var modelNodes = relationships.parents.map( function ( parent ) { @@ -1570,13 +1550,15 @@ THREE.FBXLoader = ( function () { }, null ); - var morphTarget = relationships.children.reduce( function ( morphTarget, child ) { + relationships.children.forEach( function ( child ) { - if ( morphTargets[ child.ID ] !== undefined ) morphTarget = morphTargets[ child.ID ]; + if ( deformers.morphTargets[ child.ID ] !== undefined ) { - return morphTarget; + morphTargets.push( deformers.morphTargets[ child.ID ] ); - }, null ); + } + + } ); // Assume one model and get the preRotation from that // if there is more than one model associated with the geometry this may cause problems @@ -1593,12 +1575,12 @@ THREE.FBXLoader = ( function () { var transform = generateTransform( transformData ); - return this.genGeometry( geoNode, skeleton, morphTarget, transform ); + return this.genGeometry( geoNode, skeleton, morphTargets, transform ); }, // Generate a THREE.BufferGeometry from a node in FBXTree.Objects.Geometry - genGeometry: function ( geoNode, skeleton, morphTarget, preTransform ) { + genGeometry: function ( geoNode, skeleton, morphTargets, preTransform ) { var geo = new THREE.BufferGeometry(); if ( geoNode.attrName ) geo.name = geoNode.attrName; @@ -1608,21 +1590,21 @@ THREE.FBXLoader = ( function () { var positionAttribute = new THREE.Float32BufferAttribute( buffers.vertex, 3 ); - preTransform.applyToBufferAttribute( positionAttribute ); + positionAttribute.applyMatrix4( preTransform ); - geo.addAttribute( 'position', positionAttribute ); + geo.setAttribute( 'position', positionAttribute ); if ( buffers.colors.length > 0 ) { - geo.addAttribute( 'color', new THREE.Float32BufferAttribute( buffers.colors, 3 ) ); + geo.setAttribute( 'color', new THREE.Float32BufferAttribute( buffers.colors, 3 ) ); } if ( skeleton ) { - geo.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( buffers.weightsIndices, 4 ) ); + geo.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( buffers.weightsIndices, 4 ) ); - geo.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( buffers.vertexWeights, 4 ) ); + geo.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( buffers.vertexWeights, 4 ) ); // used later to bind the skeleton to the model geo.FBX_Deformer = skeleton; @@ -1631,12 +1613,12 @@ THREE.FBXLoader = ( function () { if ( buffers.normal.length > 0 ) { - var normalAttribute = new THREE.Float32BufferAttribute( buffers.normal, 3 ); - var normalMatrix = new THREE.Matrix3().getNormalMatrix( preTransform ); - normalMatrix.applyToBufferAttribute( normalAttribute ); - geo.addAttribute( 'normal', normalAttribute ); + var normalAttribute = new THREE.Float32BufferAttribute( buffers.normal, 3 ); + normalAttribute.applyNormalMatrix( normalMatrix ); + + geo.setAttribute( 'normal', normalAttribute ); } @@ -1652,7 +1634,7 @@ THREE.FBXLoader = ( function () { } - geo.addAttribute( name, new THREE.Float32BufferAttribute( buffers.uvs[ i ], 2 ) ); + geo.setAttribute( name, new THREE.Float32BufferAttribute( buffers.uvs[ i ], 2 ) ); } ); @@ -1699,7 +1681,7 @@ THREE.FBXLoader = ( function () { } - this.addMorphTargets( geo, geoNode, morphTarget, preTransform ); + this.addMorphTargets( geo, geoNode, morphTargets, preTransform ); return geo; @@ -2072,23 +2054,29 @@ THREE.FBXLoader = ( function () { }, - addMorphTargets: function ( parentGeo, parentGeoNode, morphTarget, preTransform ) { + addMorphTargets: function ( parentGeo, parentGeoNode, morphTargets, preTransform ) { - if ( morphTarget === null ) return; + if ( morphTargets.length === 0 ) return; + + parentGeo.morphTargetsRelative = true; parentGeo.morphAttributes.position = []; // parentGeo.morphAttributes.normal = []; // not implemented var self = this; - morphTarget.rawTargets.forEach( function ( rawTarget ) { + morphTargets.forEach( function ( morphTarget ) { - var morphGeoNode = fbxTree.Objects.Geometry[ rawTarget.geoID ]; + morphTarget.rawTargets.forEach( function ( rawTarget ) { - if ( morphGeoNode !== undefined ) { + var morphGeoNode = fbxTree.Objects.Geometry[ rawTarget.geoID ]; - self.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name ); + if ( morphGeoNode !== undefined ) { - } + self.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, preTransform, rawTarget.name ); + + } + + } ); } ); @@ -2100,33 +2088,29 @@ THREE.FBXLoader = ( function () { // Normal and position attributes only have data for the vertices that are affected by the morph genMorphGeometry: function ( parentGeo, parentGeoNode, morphGeoNode, preTransform, name ) { - var morphGeo = new THREE.BufferGeometry(); - if ( morphGeoNode.attrName ) morphGeo.name = morphGeoNode.attrName; - var vertexIndices = ( parentGeoNode.PolygonVertexIndex !== undefined ) ? parentGeoNode.PolygonVertexIndex.a : []; - // make a copy of the parent's vertex positions - var vertexPositions = ( parentGeoNode.Vertices !== undefined ) ? parentGeoNode.Vertices.a.slice() : []; - - var morphPositions = ( morphGeoNode.Vertices !== undefined ) ? morphGeoNode.Vertices.a : []; + var morphPositionsSparse = ( morphGeoNode.Vertices !== undefined ) ? morphGeoNode.Vertices.a : []; var indices = ( morphGeoNode.Indexes !== undefined ) ? morphGeoNode.Indexes.a : []; + var length = parentGeo.attributes.position.count * 3; + var morphPositions = new Float32Array( length ); + for ( var i = 0; i < indices.length; i ++ ) { var morphIndex = indices[ i ] * 3; - // FBX format uses blend shapes rather than morph targets. This can be converted - // by additively combining the blend shape positions with the original geometry's positions - vertexPositions[ morphIndex ] += morphPositions[ i * 3 ]; - vertexPositions[ morphIndex + 1 ] += morphPositions[ i * 3 + 1 ]; - vertexPositions[ morphIndex + 2 ] += morphPositions[ i * 3 + 2 ]; + morphPositions[ morphIndex ] = morphPositionsSparse[ i * 3 ]; + morphPositions[ morphIndex + 1 ] = morphPositionsSparse[ i * 3 + 1 ]; + morphPositions[ morphIndex + 2 ] = morphPositionsSparse[ i * 3 + 2 ]; } // TODO: add morph normal support var morphGeoInfo = { vertexIndices: vertexIndices, - vertexPositions: vertexPositions, + vertexPositions: morphPositions, + }; var morphBuffers = this.genBuffers( morphGeoInfo ); @@ -2134,7 +2118,7 @@ THREE.FBXLoader = ( function () { var positionAttribute = new THREE.Float32BufferAttribute( morphBuffers.vertex, 3 ); positionAttribute.name = name || morphGeoNode.attrName; - preTransform.applyToBufferAttribute( positionAttribute ); + positionAttribute.applyMatrix4( preTransform ); parentGeo.morphAttributes.position.push( positionAttribute ); @@ -2320,7 +2304,7 @@ THREE.FBXLoader = ( function () { } ); var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); return geometry; @@ -2508,7 +2492,7 @@ THREE.FBXLoader = ( function () { var node = { - modelName: THREE.PropertyBinding.sanitizeNodeName( rawModel.attrName ), + modelName: rawModel.attrName ? THREE.PropertyBinding.sanitizeNodeName( rawModel.attrName ) : '', ID: rawModel.id, initialPosition: [ 0, 0, 0 ], initialRotation: [ 0, 0, 0 ], @@ -2563,7 +2547,7 @@ THREE.FBXLoader = ( function () { var node = { - modelName: THREE.PropertyBinding.sanitizeNodeName( rawModel.attrName ), + modelName: rawModel.attrName ? THREE.PropertyBinding.sanitizeNodeName( rawModel.attrName ) : '', morphName: fbxTree.Objects.Deformer[ deformerID ].attrName, }; @@ -2701,19 +2685,19 @@ THREE.FBXLoader = ( function () { if ( curves.x !== undefined ) { this.interpolateRotations( curves.x ); - curves.x.values = curves.x.values.map( THREE.Math.degToRad ); + curves.x.values = curves.x.values.map( THREE.MathUtils.degToRad ); } if ( curves.y !== undefined ) { this.interpolateRotations( curves.y ); - curves.y.values = curves.y.values.map( THREE.Math.degToRad ); + curves.y.values = curves.y.values.map( THREE.MathUtils.degToRad ); } if ( curves.z !== undefined ) { this.interpolateRotations( curves.z ); - curves.z.values = curves.z.values.map( THREE.Math.degToRad ); + curves.z.values = curves.z.values.map( THREE.MathUtils.degToRad ); } @@ -2722,7 +2706,7 @@ THREE.FBXLoader = ( function () { if ( preRotation !== undefined ) { - preRotation = preRotation.map( THREE.Math.degToRad ); + preRotation = preRotation.map( THREE.MathUtils.degToRad ); preRotation.push( eulerOrder ); preRotation = new THREE.Euler().fromArray( preRotation ); @@ -2732,7 +2716,7 @@ THREE.FBXLoader = ( function () { if ( postRotation !== undefined ) { - postRotation = postRotation.map( THREE.Math.degToRad ); + postRotation = postRotation.map( THREE.MathUtils.degToRad ); postRotation.push( eulerOrder ); postRotation = new THREE.Euler().fromArray( postRotation ); @@ -3963,7 +3947,7 @@ THREE.FBXLoader = ( function () { if ( transformData.preRotation ) { - var array = transformData.preRotation.map( THREE.Math.degToRad ); + var array = transformData.preRotation.map( THREE.MathUtils.degToRad ); array.push( transformData.eulerOrder ); lPreRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); @@ -3971,7 +3955,7 @@ THREE.FBXLoader = ( function () { if ( transformData.rotation ) { - var array = transformData.rotation.map( THREE.Math.degToRad ); + var array = transformData.rotation.map( THREE.MathUtils.degToRad ); array.push( transformData.eulerOrder ); lRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); @@ -3979,7 +3963,7 @@ THREE.FBXLoader = ( function () { if ( transformData.postRotation ) { - var array = transformData.postRotation.map( THREE.Math.degToRad ); + var array = transformData.postRotation.map( THREE.MathUtils.degToRad ); array.push( transformData.eulerOrder ); lPostRotationM.makeRotationFromEuler( tempEuler.fromArray( array ) ); @@ -4126,4 +4110,4 @@ THREE.FBXLoader = ( function () { return FBXLoader; -} )(); \ No newline at end of file +} )(); diff --git a/examples/js/loaders/GCodeLoader.js b/examples/js/loaders/GCodeLoader.js index 9b4c6e75f797eb..ce7868a1947214 100644 --- a/examples/js/loaders/GCodeLoader.js +++ b/examples/js/loaders/GCodeLoader.js @@ -11,13 +11,13 @@ THREE.GCodeLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); this.splitLayer = false; }; -THREE.GCodeLoader.prototype = { +THREE.GCodeLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.GCodeLoader, @@ -35,13 +35,6 @@ THREE.GCodeLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( data ) { var state = { x: 0, y: 0, z: 0, e: 0, f: 0, extruding: false, relative: false }; @@ -182,7 +175,7 @@ THREE.GCodeLoader.prototype = { function addObject( vertex, extruding ) { var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertex, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertex, 3 ) ); var segments = new THREE.LineSegments( geometry, extruding ? extrudingMaterial : pathMaterial ); segments.name = 'layer' + i; @@ -227,4 +220,4 @@ THREE.GCodeLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index 0968d24cacf098..afc2253b0d8142 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -10,29 +10,28 @@ THREE.GLTFLoader = ( function () { function GLTFLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + this.dracoLoader = null; this.ddsLoader = null; } - GLTFLoader.prototype = { + GLTFLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: GLTFLoader, - crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { var scope = this; var resourcePath; - if ( this.resourcePath !== undefined ) { + if ( this.resourcePath !== '' ) { resourcePath = this.resourcePath; - } else if ( this.path !== undefined ) { + } else if ( this.path !== '' ) { resourcePath = this.path; @@ -97,27 +96,6 @@ THREE.GLTFLoader = ( function () { }, - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - setDRACOLoader: function ( dracoLoader ) { this.dracoLoader = dracoLoader; @@ -172,7 +150,7 @@ THREE.GLTFLoader = ( function () { if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) { - if ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported. Use LegacyGLTFLoader instead.' ) ); + if ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.' ) ); return; } @@ -203,11 +181,15 @@ THREE.GLTFLoader = ( function () { break; case EXTENSIONS.MSFT_TEXTURE_DDS: - extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension( this.ddsLoader ); + extensions[ extensionName ] = new GLTFTextureDDSExtension( this.ddsLoader ); break; case EXTENSIONS.KHR_TEXTURE_TRANSFORM: - extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] = new GLTFTextureTransformExtension(); + extensions[ extensionName ] = new GLTFTextureTransformExtension(); + break; + + case EXTENSIONS.KHR_MESH_QUANTIZATION: + extensions[ extensionName ] = new GLTFMeshQuantizationExtension(); break; default: @@ -236,7 +218,7 @@ THREE.GLTFLoader = ( function () { } - }; + } ); /* GLTFREGISTRY */ @@ -285,14 +267,14 @@ THREE.GLTFLoader = ( function () { KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness', KHR_MATERIALS_UNLIT: 'KHR_materials_unlit', KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform', + KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization', MSFT_TEXTURE_DDS: 'MSFT_texture_dds' }; /** * DDS Texture Extension * - * Specification: - * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds * */ function GLTFTextureDDSExtension( ddsLoader ) { @@ -309,9 +291,9 @@ THREE.GLTFLoader = ( function () { } /** - * Lights Extension + * Punctual Lights Extension * - * Specification: PENDING + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual */ function GLTFLightsExtension( json ) { @@ -378,9 +360,9 @@ THREE.GLTFLoader = ( function () { }; /** - * Unlit Materials Extension (pending) + * Unlit Materials Extension * - * PR: https://github.com/KhronosGroup/glTF/pull/1163 + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit */ function GLTFMaterialsUnlitExtension() { @@ -451,7 +433,7 @@ THREE.GLTFLoader = ( function () { } else if ( this.header.version < 2.0 ) { - throw new Error( 'THREE.GLTFLoader: Legacy binary file detected. Use LegacyGLTFLoader instead.' ); + throw new Error( 'THREE.GLTFLoader: Legacy binary file detected.' ); } @@ -495,7 +477,7 @@ THREE.GLTFLoader = ( function () { /** * DRACO Mesh Compression Extension * - * Specification: https://github.com/KhronosGroup/glTF/pull/874 + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression */ function GLTFDracoMeshCompressionExtension( json, dracoLoader ) { @@ -508,6 +490,7 @@ THREE.GLTFLoader = ( function () { this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION; this.json = json; this.dracoLoader = dracoLoader; + this.dracoLoader.preload(); } @@ -573,7 +556,7 @@ THREE.GLTFLoader = ( function () { /** * Texture Transform Extension * - * Specification: + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform */ function GLTFTextureTransformExtension() { @@ -620,6 +603,158 @@ THREE.GLTFLoader = ( function () { * * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness */ + + /** + * A sub class of THREE.StandardMaterial with some of the functionality + * changed via the `onBeforeCompile` callback + * @pailhead + */ + + function GLTFMeshStandardSGMaterial( params ) { + + THREE.MeshStandardMaterial.call( this ); + + this.isGLTFSpecularGlossinessMaterial = true; + + //various chunks that need replacing + var specularMapParsFragmentChunk = [ + '#ifdef USE_SPECULARMAP', + ' uniform sampler2D specularMap;', + '#endif' + ].join( '\n' ); + + var glossinessMapParsFragmentChunk = [ + '#ifdef USE_GLOSSINESSMAP', + ' uniform sampler2D glossinessMap;', + '#endif' + ].join( '\n' ); + + var specularMapFragmentChunk = [ + 'vec3 specularFactor = specular;', + '#ifdef USE_SPECULARMAP', + ' vec4 texelSpecular = texture2D( specularMap, vUv );', + ' texelSpecular = sRGBToLinear( texelSpecular );', + ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', + ' specularFactor *= texelSpecular.rgb;', + '#endif' + ].join( '\n' ); + + var glossinessMapFragmentChunk = [ + 'float glossinessFactor = glossiness;', + '#ifdef USE_GLOSSINESSMAP', + ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', + ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', + ' glossinessFactor *= texelGlossiness.a;', + '#endif' + ].join( '\n' ); + + var lightPhysicalFragmentChunk = [ + 'PhysicalMaterial material;', + 'material.diffuseColor = diffuseColor.rgb;', + 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );', + 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );', + 'material.specularRoughness = max( 1.0 - glossinessFactor, 0.0525 );// 0.0525 corresponds to the base mip of a 256 cubemap.', + 'material.specularRoughness += geometryRoughness;', + 'material.specularRoughness = min( material.specularRoughness, 1.0 );', + 'material.specularColor = specularFactor.rgb;', + ].join( '\n' ); + + var uniforms = { + specular: { value: new THREE.Color().setHex( 0xffffff ) }, + glossiness: { value: 1 }, + specularMap: { value: null }, + glossinessMap: { value: null } + }; + + this._extraUniforms = uniforms; + + // please see #14031 or #13198 for an alternate approach + this.onBeforeCompile = function ( shader ) { + + for ( var uniformName in uniforms ) { + + shader.uniforms[ uniformName ] = uniforms[ uniformName ]; + + } + + shader.fragmentShader = shader.fragmentShader.replace( 'uniform float roughness;', 'uniform vec3 specular;' ); + shader.fragmentShader = shader.fragmentShader.replace( 'uniform float metalness;', 'uniform float glossiness;' ); + shader.fragmentShader = shader.fragmentShader.replace( '#include ', specularMapParsFragmentChunk ); + shader.fragmentShader = shader.fragmentShader.replace( '#include ', glossinessMapParsFragmentChunk ); + shader.fragmentShader = shader.fragmentShader.replace( '#include ', specularMapFragmentChunk ); + shader.fragmentShader = shader.fragmentShader.replace( '#include ', glossinessMapFragmentChunk ); + shader.fragmentShader = shader.fragmentShader.replace( '#include ', lightPhysicalFragmentChunk ); + + }; + + /*eslint-disable*/ + Object.defineProperties( + this, + { + specular: { + get: function () { return uniforms.specular.value; }, + set: function ( v ) { uniforms.specular.value = v; } + }, + specularMap: { + get: function () { return uniforms.specularMap.value; }, + set: function ( v ) { uniforms.specularMap.value = v; } + }, + glossiness: { + get: function () { return uniforms.glossiness.value; }, + set: function ( v ) { uniforms.glossiness.value = v; } + }, + glossinessMap: { + get: function () { return uniforms.glossinessMap.value; }, + set: function ( v ) { + + uniforms.glossinessMap.value = v; + //how about something like this - @pailhead + if ( v ) { + + this.defines.USE_GLOSSINESSMAP = ''; + // set USE_ROUGHNESSMAP to enable vUv + this.defines.USE_ROUGHNESSMAP = ''; + + } else { + + delete this.defines.USE_ROUGHNESSMAP; + delete this.defines.USE_GLOSSINESSMAP; + + } + + } + } + } + ); + + /*eslint-enable*/ + delete this.metalness; + delete this.roughness; + delete this.metalnessMap; + delete this.roughnessMap; + + this.setValues( params ); + + } + + GLTFMeshStandardSGMaterial.prototype = Object.create( THREE.MeshStandardMaterial.prototype ); + GLTFMeshStandardSGMaterial.prototype.constructor = GLTFMeshStandardSGMaterial; + + GLTFMeshStandardSGMaterial.prototype.copy = function ( source ) { + + THREE.MeshStandardMaterial.prototype.copy.call( this, source ); + this.specularMap = source.specularMap; + this.specular.copy( source.specular ); + this.glossinessMap = source.glossinessMap; + this.glossiness = source.glossiness; + delete this.metalness; + delete this.roughness; + delete this.metalnessMap; + delete this.roughnessMap; + return this; + + }; + function GLTFMaterialsPbrSpecularGlossinessExtension() { return { @@ -639,6 +774,7 @@ THREE.GLTFLoader = ( function () { 'bumpMap', 'bumpScale', 'normalMap', + 'normalMapType', 'displacementMap', 'displacementScale', 'displacementBias', @@ -654,7 +790,7 @@ THREE.GLTFLoader = ( function () { getMaterialType: function () { - return THREE.ShaderMaterial; + return GLTFMeshStandardSGMaterial; }, @@ -662,72 +798,6 @@ THREE.GLTFLoader = ( function () { var pbrSpecularGlossiness = materialDef.extensions[ this.name ]; - var shader = THREE.ShaderLib[ 'standard' ]; - - var uniforms = THREE.UniformsUtils.clone( shader.uniforms ); - - var specularMapParsFragmentChunk = [ - '#ifdef USE_SPECULARMAP', - ' uniform sampler2D specularMap;', - '#endif' - ].join( '\n' ); - - var glossinessMapParsFragmentChunk = [ - '#ifdef USE_GLOSSINESSMAP', - ' uniform sampler2D glossinessMap;', - '#endif' - ].join( '\n' ); - - var specularMapFragmentChunk = [ - 'vec3 specularFactor = specular;', - '#ifdef USE_SPECULARMAP', - ' vec4 texelSpecular = texture2D( specularMap, vUv );', - ' texelSpecular = sRGBToLinear( texelSpecular );', - ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', - ' specularFactor *= texelSpecular.rgb;', - '#endif' - ].join( '\n' ); - - var glossinessMapFragmentChunk = [ - 'float glossinessFactor = glossiness;', - '#ifdef USE_GLOSSINESSMAP', - ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', - ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', - ' glossinessFactor *= texelGlossiness.a;', - '#endif' - ].join( '\n' ); - - var lightPhysicalFragmentChunk = [ - 'PhysicalMaterial material;', - 'material.diffuseColor = diffuseColor.rgb;', - 'material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 );', - 'material.specularColor = specularFactor.rgb;', - ].join( '\n' ); - - var fragmentShader = shader.fragmentShader - .replace( 'uniform float roughness;', 'uniform vec3 specular;' ) - .replace( 'uniform float metalness;', 'uniform float glossiness;' ) - .replace( '#include ', specularMapParsFragmentChunk ) - .replace( '#include ', glossinessMapParsFragmentChunk ) - .replace( '#include ', specularMapFragmentChunk ) - .replace( '#include ', glossinessMapFragmentChunk ) - .replace( '#include ', lightPhysicalFragmentChunk ); - - delete uniforms.roughness; - delete uniforms.metalness; - delete uniforms.roughnessMap; - delete uniforms.metalnessMap; - - uniforms.specular = { value: new THREE.Color().setHex( 0x111111 ) }; - uniforms.glossiness = { value: 0.5 }; - uniforms.specularMap = { value: null }; - uniforms.glossinessMap = { value: null }; - - materialParams.vertexShader = shader.vertexShader; - materialParams.fragmentShader = fragmentShader; - materialParams.uniforms = uniforms; - materialParams.defines = { 'STANDARD': '' }; - materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 ); materialParams.opacity = 1.0; @@ -770,237 +840,66 @@ THREE.GLTFLoader = ( function () { }, - createMaterial: function ( params ) { + createMaterial: function ( materialParams ) { - // setup material properties based on MeshStandardMaterial for Specular-Glossiness - - var material = new THREE.ShaderMaterial( { - defines: params.defines, - vertexShader: params.vertexShader, - fragmentShader: params.fragmentShader, - uniforms: params.uniforms, - fog: true, - lights: true, - opacity: params.opacity, - transparent: params.transparent - } ); + var material = new GLTFMeshStandardSGMaterial( materialParams ); + material.fog = true; - material.isGLTFSpecularGlossinessMaterial = true; + material.color = materialParams.color; - material.color = params.color; - - material.map = params.map === undefined ? null : params.map; + material.map = materialParams.map === undefined ? null : materialParams.map; material.lightMap = null; material.lightMapIntensity = 1.0; - material.aoMap = params.aoMap === undefined ? null : params.aoMap; + material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap; material.aoMapIntensity = 1.0; - material.emissive = params.emissive; + material.emissive = materialParams.emissive; material.emissiveIntensity = 1.0; - material.emissiveMap = params.emissiveMap === undefined ? null : params.emissiveMap; + material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap; - material.bumpMap = params.bumpMap === undefined ? null : params.bumpMap; + material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap; material.bumpScale = 1; - material.normalMap = params.normalMap === undefined ? null : params.normalMap; + material.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap; + material.normalMapType = THREE.TangentSpaceNormalMap; - if ( params.normalScale ) material.normalScale = params.normalScale; + if ( materialParams.normalScale ) material.normalScale = materialParams.normalScale; material.displacementMap = null; material.displacementScale = 1; material.displacementBias = 0; - material.specularMap = params.specularMap === undefined ? null : params.specularMap; - material.specular = params.specular; + material.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap; + material.specular = materialParams.specular; - material.glossinessMap = params.glossinessMap === undefined ? null : params.glossinessMap; - material.glossiness = params.glossiness; + material.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap; + material.glossiness = materialParams.glossiness; material.alphaMap = null; - material.envMap = params.envMap === undefined ? null : params.envMap; + material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap; material.envMapIntensity = 1.0; material.refractionRatio = 0.98; - material.extensions.derivatives = true; - return material; }, - /** - * Clones a GLTFSpecularGlossinessMaterial instance. The ShaderMaterial.copy() method can - * copy only properties it knows about or inherits, and misses many properties that would - * normally be defined by MeshStandardMaterial. - * - * This method allows GLTFSpecularGlossinessMaterials to be cloned in the process of - * loading a glTF model, but cloning later (e.g. by the user) would require these changes - * AND also updating `.onBeforeRender` on the parent mesh. - * - * @param {THREE.ShaderMaterial} source - * @return {THREE.ShaderMaterial} - */ - cloneMaterial: function ( source ) { - - var target = source.clone(); - - target.isGLTFSpecularGlossinessMaterial = true; - - var params = this.specularGlossinessParams; - - for ( var i = 0, il = params.length; i < il; i ++ ) { - - var value = source[ params[ i ] ]; - target[ params[ i ] ] = ( value && value.isColor ) ? value.clone() : value; - - } - - return target; - - }, - - // Here's based on refreshUniformsCommon() and refreshUniformsStandard() in WebGLRenderer. - refreshUniforms: function ( renderer, scene, camera, geometry, material ) { - - if ( material.isGLTFSpecularGlossinessMaterial !== true ) { - - return; - - } - - var uniforms = material.uniforms; - var defines = material.defines; - - uniforms.opacity.value = material.opacity; - - uniforms.diffuse.value.copy( material.color ); - uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity ); - - uniforms.map.value = material.map; - uniforms.specularMap.value = material.specularMap; - uniforms.alphaMap.value = material.alphaMap; - - uniforms.lightMap.value = material.lightMap; - uniforms.lightMapIntensity.value = material.lightMapIntensity; - - uniforms.aoMap.value = material.aoMap; - uniforms.aoMapIntensity.value = material.aoMapIntensity; - - // uv repeat and offset setting priorities - // 1. color map - // 2. specular map - // 3. normal map - // 4. bump map - // 5. alpha map - // 6. emissive map - - var uvScaleMap; - - if ( material.map ) { - - uvScaleMap = material.map; - - } else if ( material.specularMap ) { - - uvScaleMap = material.specularMap; - - } else if ( material.displacementMap ) { - - uvScaleMap = material.displacementMap; - - } else if ( material.normalMap ) { - - uvScaleMap = material.normalMap; - - } else if ( material.bumpMap ) { - - uvScaleMap = material.bumpMap; - - } else if ( material.glossinessMap ) { - - uvScaleMap = material.glossinessMap; - - } else if ( material.alphaMap ) { - - uvScaleMap = material.alphaMap; - - } else if ( material.emissiveMap ) { - - uvScaleMap = material.emissiveMap; - - } - - if ( uvScaleMap !== undefined ) { - - // backwards compatibility - if ( uvScaleMap.isWebGLRenderTarget ) { - - uvScaleMap = uvScaleMap.texture; - - } - - if ( uvScaleMap.matrixAutoUpdate === true ) { - - uvScaleMap.updateMatrix(); - - } - - uniforms.uvTransform.value.copy( uvScaleMap.matrix ); - - } - - if ( material.envMap ) { - - uniforms.envMap.value = material.envMap; - uniforms.envMapIntensity.value = material.envMapIntensity; - - // don't flip CubeTexture envMaps, flip everything else: - // WebGLRenderTargetCube will be flipped for backwards compatibility - // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture - // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future - uniforms.flipEnvMap.value = material.envMap.isCubeTexture ? - 1 : 1; - - uniforms.reflectivity.value = material.reflectivity; - uniforms.refractionRatio.value = material.refractionRatio; - - uniforms.maxMipLevel.value = renderer.properties.get( material.envMap ).__maxMipLevel; - - } - - uniforms.specular.value.copy( material.specular ); - uniforms.glossiness.value = material.glossiness; - - uniforms.glossinessMap.value = material.glossinessMap; - - uniforms.emissiveMap.value = material.emissiveMap; - uniforms.bumpMap.value = material.bumpMap; - uniforms.normalMap.value = material.normalMap; - - uniforms.displacementMap.value = material.displacementMap; - uniforms.displacementScale.value = material.displacementScale; - uniforms.displacementBias.value = material.displacementBias; - - if ( uniforms.glossinessMap.value !== null && defines.USE_GLOSSINESSMAP === undefined ) { - - defines.USE_GLOSSINESSMAP = ''; - // set USE_ROUGHNESSMAP to enable vUv - defines.USE_ROUGHNESSMAP = ''; - - } - - if ( uniforms.glossinessMap.value === null && defines.USE_GLOSSINESSMAP !== undefined ) { - - delete defines.USE_GLOSSINESSMAP; - delete defines.USE_ROUGHNESSMAP; + }; - } + } - } + /** + * Mesh Quantization Extension + * + * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization + */ + function GLTFMeshQuantizationExtension() { - }; + this.name = EXTENSIONS.KHR_MESH_QUANTIZATION; } @@ -1187,11 +1086,11 @@ THREE.GLTFLoader = ( function () { // Invalid URL if ( typeof url !== 'string' || url === '' ) return ''; - + // Host Relative URL if ( /^https?:\/\//i.test( path ) && /^\//.test( url ) ) { - path = path.replace( /(^https?:\/\/[^\/]+).*/i , '$1' ); + path = path.replace( /(^https?:\/\/[^\/]+).*/i, '$1' ); } @@ -1209,24 +1108,26 @@ THREE.GLTFLoader = ( function () { } - var defaultMaterial; - /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material */ - function createDefaultMaterial() { - - defaultMaterial = defaultMaterial || new THREE.MeshStandardMaterial( { - color: 0xFFFFFF, - emissive: 0x000000, - metalness: 1, - roughness: 1, - transparent: false, - depthTest: true, - side: THREE.FrontSide - } ); + function createDefaultMaterial( cache ) { + + if ( cache[ 'DefaultMaterial' ] === undefined ) { + + cache[ 'DefaultMaterial' ] = new THREE.MeshStandardMaterial( { + color: 0xFFFFFF, + emissive: 0x000000, + metalness: 1, + roughness: 1, + transparent: false, + depthTest: true, + side: THREE.FrontSide + } ); - return defaultMaterial; + } + + return cache[ 'DefaultMaterial' ]; } @@ -1332,95 +1233,9 @@ THREE.GLTFLoader = ( function () { var morphPositions = accessors[ 0 ]; var morphNormals = accessors[ 1 ]; - // Clone morph target accessors before modifying them. - - for ( var i = 0, il = morphPositions.length; i < il; i ++ ) { - - if ( geometry.attributes.position === morphPositions[ i ] ) continue; - - morphPositions[ i ] = cloneBufferAttribute( morphPositions[ i ] ); - - } - - for ( var i = 0, il = morphNormals.length; i < il; i ++ ) { - - if ( geometry.attributes.normal === morphNormals[ i ] ) continue; - - morphNormals[ i ] = cloneBufferAttribute( morphNormals[ i ] ); - - } - - for ( var i = 0, il = targets.length; i < il; i ++ ) { - - var target = targets[ i ]; - var attributeName = 'morphTarget' + i; - - if ( hasMorphPosition ) { - - // Three.js morph position is absolute value. The formula is - // basePosition - // + weight0 * ( morphPosition0 - basePosition ) - // + weight1 * ( morphPosition1 - basePosition ) - // ... - // while the glTF one is relative - // basePosition - // + weight0 * glTFmorphPosition0 - // + weight1 * glTFmorphPosition1 - // ... - // then we need to convert from relative to absolute here. - - if ( target.POSITION !== undefined ) { - - var positionAttribute = morphPositions[ i ]; - positionAttribute.name = attributeName; - - var position = geometry.attributes.position; - - for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) { - - positionAttribute.setXYZ( - j, - positionAttribute.getX( j ) + position.getX( j ), - positionAttribute.getY( j ) + position.getY( j ), - positionAttribute.getZ( j ) + position.getZ( j ) - ); - - } - - } - - } - - if ( hasMorphNormal ) { - - // see target.POSITION's comment - - if ( target.NORMAL !== undefined ) { - - var normalAttribute = morphNormals[ i ]; - normalAttribute.name = attributeName; - - var normal = geometry.attributes.normal; - - for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) { - - normalAttribute.setXYZ( - j, - normalAttribute.getX( j ) + normal.getX( j ), - normalAttribute.getY( j ) + normal.getY( j ), - normalAttribute.getZ( j ) + normal.getZ( j ) - ); - - } - - } - - } - - } - if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions; if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals; + geometry.morphTargetsRelative = true; return geometry; @@ -1508,31 +1323,6 @@ THREE.GLTFLoader = ( function () { } - function cloneBufferAttribute( attribute ) { - - if ( attribute.isInterleavedBufferAttribute ) { - - var count = attribute.count; - var itemSize = attribute.itemSize; - var array = attribute.array.slice( 0, count * itemSize ); - - for ( var i = 0, j = 0; i < count; ++ i ) { - - array[ j ++ ] = attribute.getX( i ); - if ( itemSize >= 2 ) array[ j ++ ] = attribute.getY( i ); - if ( itemSize >= 3 ) array[ j ++ ] = attribute.getZ( i ); - if ( itemSize >= 4 ) array[ j ++ ] = attribute.getW( i ); - - } - - return new THREE.BufferAttribute( array, itemSize, attribute.normalized ); - - } - - return attribute.clone(); - - } - /* GLTF PARSER */ function GLTFParser( json, extensions, options ) { @@ -1899,7 +1689,7 @@ THREE.GLTFLoader = ( function () { } - bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, (byteOffset % byteStride) / elementBytes, normalized ); + bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, ( byteOffset % byteStride ) / elementBytes, normalized ); } else { @@ -1932,7 +1722,7 @@ THREE.GLTFLoader = ( function () { if ( bufferView !== null ) { // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes. - bufferAttribute.setArray( bufferAttribute.array.slice() ); + bufferAttribute = new THREE.BufferAttribute( bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized ); } @@ -2008,7 +1798,7 @@ THREE.GLTFLoader = ( function () { // Load Texture resource. - var loader = THREE.Loader.Handlers.get( sourceURI ); + var loader = options.manager.getHandler( sourceURI ); if ( ! loader ) { @@ -2036,7 +1826,7 @@ THREE.GLTFLoader = ( function () { texture.flipY = false; - if ( textureDef.name !== undefined ) texture.name = textureDef.name; + if ( textureDef.name ) texture.name = textureDef.name; // Ignore unknown mime types, like DDS files. if ( source.mimeType in MIME_TYPE_FORMATS ) { @@ -2088,6 +1878,14 @@ THREE.GLTFLoader = ( function () { } + // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured + // However, we will copy UV set 0 to UV set 1 on demand for aoMap + if ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) { + + console.warn( 'THREE.GLTFLoader: Custom UV set ' + mapDef.texCoord + ' for texture ' + mapName + ' not yet supported.' ); + + } + if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) { var transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined; @@ -2118,7 +1916,6 @@ THREE.GLTFLoader = ( function () { var geometry = mesh.geometry; var material = mesh.material; - var extensions = this.extensions; var useVertexTangents = geometry.attributes.tangent !== undefined; var useVertexColors = geometry.attributes.color !== undefined; @@ -2139,7 +1936,6 @@ THREE.GLTFLoader = ( function () { THREE.Material.prototype.copy.call( pointsMaterial, material ); pointsMaterial.color.copy( material.color ); pointsMaterial.map = material.map; - pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px this.cache.add( cacheKey, pointsMaterial ); @@ -2159,7 +1955,6 @@ THREE.GLTFLoader = ( function () { lineMaterial = new THREE.LineBasicMaterial(); THREE.Material.prototype.copy.call( lineMaterial, material ); lineMaterial.color.copy( material.color ); - lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet this.cache.add( cacheKey, lineMaterial ); @@ -2186,13 +1981,11 @@ THREE.GLTFLoader = ( function () { if ( ! cachedMaterial ) { - cachedMaterial = material.isGLTFSpecularGlossinessMaterial - ? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material ) - : material.clone(); + cachedMaterial = material.clone(); if ( useSkinning ) cachedMaterial.skinning = true; if ( useVertexTangents ) cachedMaterial.vertexTangents = true; - if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors; + if ( useVertexColors ) cachedMaterial.vertexColors = true; if ( useFlatShading ) cachedMaterial.flatShading = true; if ( useMorphTargets ) cachedMaterial.morphTargets = true; if ( useMorphNormals ) cachedMaterial.morphNormals = true; @@ -2209,15 +2002,14 @@ THREE.GLTFLoader = ( function () { if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) { - console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' ); - geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) ); + geometry.setAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) ); } - if ( material.isGLTFSpecularGlossinessMaterial ) { + // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995 + if ( material.normalScale && ! useVertexTangents ) { - // for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update - mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms; + material.normalScale.y = - material.normalScale.y; } @@ -2306,6 +2098,9 @@ THREE.GLTFLoader = ( function () { materialParams.transparent = true; + // See: https://github.com/mrdoob/three.js/issues/17706 + materialParams.depthWrite = false; + } else { materialParams.transparent = false; @@ -2360,7 +2155,7 @@ THREE.GLTFLoader = ( function () { var material; - if ( materialType === THREE.ShaderMaterial ) { + if ( materialType === GLTFMeshStandardSGMaterial ) { material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams ); @@ -2370,12 +2165,11 @@ THREE.GLTFLoader = ( function () { } - if ( materialDef.name !== undefined ) material.name = materialDef.name; + if ( materialDef.name ) material.name = materialDef.name; // baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding. if ( material.map ) material.map.encoding = THREE.sRGBEncoding; if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding; - if ( material.specularMap ) material.specularMap.encoding = THREE.sRGBEncoding; assignExtrasToUserData( material, materialDef ); @@ -2387,6 +2181,96 @@ THREE.GLTFLoader = ( function () { }; + /** + * @param {THREE.BufferGeometry} geometry + * @param {GLTF.Primitive} primitiveDef + * @param {GLTFParser} parser + */ + function computeBounds( geometry, primitiveDef, parser ) { + + var attributes = primitiveDef.attributes; + + var box = new THREE.Box3(); + + if ( attributes.POSITION !== undefined ) { + + var accessor = parser.json.accessors[ attributes.POSITION ]; + + var min = accessor.min; + var max = accessor.max; + + // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement. + + if ( min !== undefined && max !== undefined ) { + + box.set( + new THREE.Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ), + new THREE.Vector3( max[ 0 ], max[ 1 ], max[ 2 ] ) ); + + } else { + + console.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' ); + + return; + + } + + } else { + + return; + + } + + var targets = primitiveDef.targets; + + if ( targets !== undefined ) { + + var vector = new THREE.Vector3(); + + for ( var i = 0, il = targets.length; i < il; i ++ ) { + + var target = targets[ i ]; + + if ( target.POSITION !== undefined ) { + + var accessor = parser.json.accessors[ target.POSITION ]; + var min = accessor.min; + var max = accessor.max; + + // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement. + + if ( min !== undefined && max !== undefined ) { + + // we need to get max of absolute components because target weight is [-1,1] + vector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) ); + vector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) ); + vector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) ); + + box.expandByVector( vector ); + + } else { + + console.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' ); + + } + + } + + } + + } + + geometry.boundingBox = box; + + var sphere = new THREE.Sphere(); + + box.getCenter( sphere.center ); + sphere.radius = box.min.distanceTo( box.max ) / 2; + + geometry.boundingSphere = sphere; + + } + /** * @param {THREE.BufferGeometry} geometry * @param {GLTF.Primitive} primitiveDef @@ -2404,7 +2288,7 @@ THREE.GLTFLoader = ( function () { return parser.getDependency( 'accessor', accessorIndex ) .then( function ( accessor ) { - geometry.addAttribute( attributeName, accessor ); + geometry.setAttribute( attributeName, accessor ); } ); @@ -2435,6 +2319,8 @@ THREE.GLTFLoader = ( function () { assignExtrasToUserData( geometry, primitiveDef ); + computeBounds( geometry, primitiveDef, parser ); + return Promise.all( pending ).then( function () { return primitiveDef.targets !== undefined @@ -2445,6 +2331,100 @@ THREE.GLTFLoader = ( function () { } + /** + * @param {THREE.BufferGeometry} geometry + * @param {Number} drawMode + * @return {THREE.BufferGeometry} + */ + function toTrianglesDrawMode( geometry, drawMode ) { + + var index = geometry.getIndex(); + + // generate index if not present + + if ( index === null ) { + + var indices = []; + + var position = geometry.getAttribute( 'position' ); + + if ( position !== undefined ) { + + for ( var i = 0; i < position.count; i ++ ) { + + indices.push( i ); + + } + + geometry.setIndex( indices ); + index = geometry.getIndex(); + + } else { + + console.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' ); + return geometry; + + } + + } + + // + + var numberOfTriangles = index.count - 2; + var newIndices = []; + + if ( drawMode === THREE.TriangleFanDrawMode ) { + + // gl.TRIANGLE_FAN + + for ( var i = 1; i <= numberOfTriangles; i ++ ) { + + newIndices.push( index.getX( 0 ) ); + newIndices.push( index.getX( i ) ); + newIndices.push( index.getX( i + 1 ) ); + + } + + } else { + + // gl.TRIANGLE_STRIP + + for ( var i = 0; i < numberOfTriangles; i ++ ) { + + if ( i % 2 === 0 ) { + + newIndices.push( index.getX( i ) ); + newIndices.push( index.getX( i + 1 ) ); + newIndices.push( index.getX( i + 2 ) ); + + + } else { + + newIndices.push( index.getX( i + 2 ) ); + newIndices.push( index.getX( i + 1 ) ); + newIndices.push( index.getX( i ) ); + + } + + } + + } + + if ( ( newIndices.length / 3 ) !== numberOfTriangles ) { + + console.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' ); + + } + + // build final geometry + + var newGeometry = geometry.clone(); + newGeometry.setIndex( newIndices ); + + return newGeometry; + + } + /** * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry * @@ -2533,115 +2513,116 @@ THREE.GLTFLoader = ( function () { for ( var i = 0, il = primitives.length; i < il; i ++ ) { var material = primitives[ i ].material === undefined - ? createDefaultMaterial() + ? createDefaultMaterial( this.cache ) : this.getDependency( 'material', primitives[ i ].material ); pending.push( material ); } - return Promise.all( pending ).then( function ( originalMaterials ) { + pending.push( parser.loadGeometries( primitives ) ); - return parser.loadGeometries( primitives ).then( function ( geometries ) { + return Promise.all( pending ).then( function ( results ) { - var meshes = []; + var materials = results.slice( 0, results.length - 1 ); + var geometries = results[ results.length - 1 ]; - for ( var i = 0, il = geometries.length; i < il; i ++ ) { + var meshes = []; - var geometry = geometries[ i ]; - var primitive = primitives[ i ]; + for ( var i = 0, il = geometries.length; i < il; i ++ ) { - // 1. create Mesh + var geometry = geometries[ i ]; + var primitive = primitives[ i ]; - var mesh; + // 1. create Mesh - var material = originalMaterials[ i ]; + var mesh; - if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || - primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || - primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || - primitive.mode === undefined ) { + var material = materials[ i ]; - // .isSkinnedMesh isn't in glTF spec. See .markDefs() - mesh = meshDef.isSkinnedMesh === true - ? new THREE.SkinnedMesh( geometry, material ) - : new THREE.Mesh( geometry, material ); + if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || + primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || + primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || + primitive.mode === undefined ) { - if ( mesh.isSkinnedMesh === true && ! mesh.geometry.attributes.skinWeight.normalized ) { + // .isSkinnedMesh isn't in glTF spec. See .markDefs() + mesh = meshDef.isSkinnedMesh === true + ? new THREE.SkinnedMesh( geometry, material ) + : new THREE.Mesh( geometry, material ); - // we normalize floating point skin weight array to fix malformed assets (see #15319) - // it's important to skip this for non-float32 data since normalizeSkinWeights assumes non-normalized inputs - mesh.normalizeSkinWeights(); + if ( mesh.isSkinnedMesh === true && ! mesh.geometry.attributes.skinWeight.normalized ) { - } + // we normalize floating point skin weight array to fix malformed assets (see #15319) + // it's important to skip this for non-float32 data since normalizeSkinWeights assumes non-normalized inputs + mesh.normalizeSkinWeights(); - if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) { + } - mesh.drawMode = THREE.TriangleStripDrawMode; + if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) { - } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) { + mesh.geometry = toTrianglesDrawMode( mesh.geometry, THREE.TriangleStripDrawMode ); - mesh.drawMode = THREE.TriangleFanDrawMode; + } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) { - } + mesh.geometry = toTrianglesDrawMode( mesh.geometry, THREE.TriangleFanDrawMode ); - } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) { + } - mesh = new THREE.LineSegments( geometry, material ); + } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) { - } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) { + mesh = new THREE.LineSegments( geometry, material ); - mesh = new THREE.Line( geometry, material ); + } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) { - } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) { + mesh = new THREE.Line( geometry, material ); - mesh = new THREE.LineLoop( geometry, material ); + } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) { - } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) { + mesh = new THREE.LineLoop( geometry, material ); - mesh = new THREE.Points( geometry, material ); + } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) { - } else { + mesh = new THREE.Points( geometry, material ); - throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode ); + } else { - } + throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode ); - if ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) { + } - updateMorphTargets( mesh, meshDef ); + if ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) { - } + updateMorphTargets( mesh, meshDef ); - mesh.name = meshDef.name || ( 'mesh_' + meshIndex ); + } - if ( geometries.length > 1 ) mesh.name += '_' + i; + mesh.name = meshDef.name || ( 'mesh_' + meshIndex ); - assignExtrasToUserData( mesh, meshDef ); + if ( geometries.length > 1 ) mesh.name += '_' + i; - parser.assignFinalMaterial( mesh ); + assignExtrasToUserData( mesh, meshDef ); - meshes.push( mesh ); + parser.assignFinalMaterial( mesh ); - } + meshes.push( mesh ); - if ( meshes.length === 1 ) { + } - return meshes[ 0 ]; + if ( meshes.length === 1 ) { - } + return meshes[ 0 ]; - var group = new THREE.Group(); + } - for ( var i = 0, il = meshes.length; i < il; i ++ ) { + var group = new THREE.Group(); - group.add( meshes[ i ] ); + for ( var i = 0, il = meshes.length; i < il; i ++ ) { - } + group.add( meshes[ i ] ); - return group; + } - } ); + return group; } ); @@ -2667,7 +2648,7 @@ THREE.GLTFLoader = ( function () { if ( cameraDef.type === 'perspective' ) { - camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 ); + camera = new THREE.PerspectiveCamera( THREE.MathUtils.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 ); } else if ( cameraDef.type === 'orthographic' ) { @@ -2675,7 +2656,7 @@ THREE.GLTFLoader = ( function () { } - if ( cameraDef.name !== undefined ) camera.name = cameraDef.name; + if ( cameraDef.name ) camera.name = cameraDef.name; assignExtrasToUserData( camera, cameraDef ); @@ -2896,7 +2877,7 @@ THREE.GLTFLoader = ( function () { } - var name = animationDef.name !== undefined ? animationDef.name : 'animation_' + animationIndex; + var name = animationDef.name ? animationDef.name : 'animation_' + animationIndex; return new THREE.AnimationClip( name, undefined, tracks ); @@ -2937,16 +2918,6 @@ THREE.GLTFLoader = ( function () { node = mesh.clone(); node.name += '_instance_' + instanceNum; - // onBeforeRender copy for Specular-Glossiness - node.onBeforeRender = mesh.onBeforeRender; - - for ( var i = 0, il = node.children.length; i < il; i ++ ) { - - node.children[ i ].name += '_instance_' + instanceNum; - node.children[ i ].onBeforeRender = mesh.children[ i ].onBeforeRender; - - } - } else { node = mesh; @@ -3025,7 +2996,7 @@ THREE.GLTFLoader = ( function () { } - if ( nodeDef.name !== undefined ) { + if ( nodeDef.name ) { node.userData.name = nodeDef.name; node.name = THREE.PropertyBinding.sanitizeNodeName( nodeDef.name ); @@ -3040,7 +3011,7 @@ THREE.GLTFLoader = ( function () { var matrix = new THREE.Matrix4(); matrix.fromArray( nodeDef.matrix ); - node.applyMatrix( matrix ); + node.applyMatrix4( matrix ); } else { @@ -3073,7 +3044,7 @@ THREE.GLTFLoader = ( function () { /** * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes * @param {number} sceneIndex - * @return {Promise} + * @return {Promise} */ GLTFParser.prototype.loadScene = function () { @@ -3182,8 +3153,10 @@ THREE.GLTFLoader = ( function () { var sceneDef = this.json.scenes[ sceneIndex ]; var parser = this; - var scene = new THREE.Scene(); - if ( sceneDef.name !== undefined ) scene.name = sceneDef.name; + // Loader returns Group, not Scene. + // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172 + var scene = new THREE.Group(); + if ( sceneDef.name ) scene.name = sceneDef.name; assignExtrasToUserData( scene, sceneDef ); diff --git a/examples/js/loaders/HDRCubeTextureLoader.js b/examples/js/loaders/HDRCubeTextureLoader.js index ca49180cdde266..1318c68865a6f5 100644 --- a/examples/js/loaders/HDRCubeTextureLoader.js +++ b/examples/js/loaders/HDRCubeTextureLoader.js @@ -5,134 +5,127 @@ THREE.HDRCubeTextureLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + this.hdrLoader = new THREE.RGBELoader(); this.type = THREE.UnsignedByteType; }; -THREE.HDRCubeTextureLoader.prototype.load = function ( urls, onLoad, onProgress, onError ) { +THREE.HDRCubeTextureLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { - if ( ! Array.isArray( urls ) ) { + constructor: THREE.HDRCubeTextureLoader, - console.warn( 'THREE.HDRCubeTextureLoader signature has changed. Use .setDataType() instead.' ); + load: function ( urls, onLoad, onProgress, onError ) { - this.setDataType( urls ); + if ( ! Array.isArray( urls ) ) { - urls = onLoad; - onLoad = onProgress; - onProgress = onError; - onError = arguments[ 4 ]; + console.warn( 'THREE.HDRCubeTextureLoader signature has changed. Use .setDataType() instead.' ); - } + this.setDataType( urls ); - var texture = new THREE.CubeTexture(); + urls = onLoad; + onLoad = onProgress; + onProgress = onError; + onError = arguments[ 4 ]; - texture.type = this.type; + } - switch ( texture.type ) { + var texture = new THREE.CubeTexture(); - case THREE.UnsignedByteType: + texture.type = this.type; - texture.encoding = THREE.RGBEEncoding; - texture.format = THREE.RGBAFormat; - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.generateMipmaps = false; - break; + switch ( texture.type ) { - case THREE.FloatType: + case THREE.UnsignedByteType: - texture.encoding = THREE.LinearEncoding; - texture.format = THREE.RGBFormat; - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.generateMipmaps = false; - break; + texture.encoding = THREE.RGBEEncoding; + texture.format = THREE.RGBAFormat; + texture.minFilter = THREE.NearestFilter; + texture.magFilter = THREE.NearestFilter; + texture.generateMipmaps = false; + break; - case THREE.HalfFloatType: + case THREE.FloatType: - texture.encoding = THREE.LinearEncoding; - texture.format = THREE.RGBFormat; - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.generateMipmaps = false; - break; + texture.encoding = THREE.LinearEncoding; + texture.format = THREE.RGBFormat; + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.generateMipmaps = false; + break; - } + case THREE.HalfFloatType: - var scope = this; + texture.encoding = THREE.LinearEncoding; + texture.format = THREE.RGBFormat; + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.generateMipmaps = false; + break; - var loaded = 0; + } - function loadHDRData( i, onLoad, onProgress, onError ) { + var scope = this; - new THREE.FileLoader( scope.manager ) - .setPath( scope.path ) - .setResponseType( 'arraybuffer' ) - .load( urls[ i ], function ( buffer ) { + var loaded = 0; - loaded ++; + function loadHDRData( i, onLoad, onProgress, onError ) { - var texData = scope.hdrLoader._parser( buffer ); + new THREE.FileLoader( scope.manager ) + .setPath( scope.path ) + .setResponseType( 'arraybuffer' ) + .load( urls[ i ], function ( buffer ) { - if ( ! texData ) return; + loaded ++; - if ( texData.data !== undefined ) { + var texData = scope.hdrLoader.parse( buffer ); - var dataTexture = new THREE.DataTexture( texData.data, texData.width, texData.height ); + if ( ! texData ) return; - dataTexture.type = texture.type; - dataTexture.encoding = texture.encoding; - dataTexture.format = texture.format; - dataTexture.minFilter = texture.minFilter; - dataTexture.magFilter = texture.magFilter; - dataTexture.generateMipmaps = texture.generateMipmaps; + if ( texData.data !== undefined ) { - texture.images[ i ] = dataTexture; + var dataTexture = new THREE.DataTexture( texData.data, texData.width, texData.height ); - } + dataTexture.type = texture.type; + dataTexture.encoding = texture.encoding; + dataTexture.format = texture.format; + dataTexture.minFilter = texture.minFilter; + dataTexture.magFilter = texture.magFilter; + dataTexture.generateMipmaps = texture.generateMipmaps; - if ( loaded === 6 ) { + texture.images[ i ] = dataTexture; - texture.needsUpdate = true; - if ( onLoad ) onLoad( texture ); + } - } + if ( loaded === 6 ) { - }, onProgress, onError ); + texture.needsUpdate = true; + if ( onLoad ) onLoad( texture ); - } + } - for ( var i = 0; i < urls.length; i ++ ) { + }, onProgress, onError ); - loadHDRData( i, onLoad, onProgress, onError ); + } - } + for ( var i = 0; i < urls.length; i ++ ) { - return texture; + loadHDRData( i, onLoad, onProgress, onError ); -}; + } -THREE.HDRCubeTextureLoader.prototype.setPath = function ( value ) { + return texture; - this.path = value; - return this; + }, -}; + setDataType: function ( value ) { -THREE.HDRCubeTextureLoader.prototype.setDataType = function ( value ) { + this.type = value; + this.hdrLoader.setDataType( value ); - this.type = value; - this.hdrLoader.setDataType( value ); - return this; + return this; -}; - -THREE.HDRCubeTextureLoader.prototype.setType = function ( value ) { - - console.warn( 'THREE.HDRCubeTextureLoader: .setType() has been renamed to .setDataType().' ); - - return this.setDataType( value ); + } -}; +} ); diff --git a/examples/js/loaders/KMZLoader.js b/examples/js/loaders/KMZLoader.js index 22e171fc6d4d5a..da91eacc783dd2 100644 --- a/examples/js/loaders/KMZLoader.js +++ b/examples/js/loaders/KMZLoader.js @@ -4,11 +4,11 @@ THREE.KMZLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.KMZLoader.prototype = { +THREE.KMZLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.KMZLoader, @@ -27,13 +27,6 @@ THREE.KMZLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( data ) { function findFile( url ) { @@ -109,4 +102,4 @@ THREE.KMZLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/KTXLoader.js b/examples/js/loaders/KTXLoader.js index 055fc51da1e3e6..d96d4af3871f43 100644 --- a/examples/js/loaders/KTXLoader.js +++ b/examples/js/loaders/KTXLoader.js @@ -12,27 +12,28 @@ THREE.KTXLoader = function ( manager ) { THREE.CompressedTextureLoader.call( this, manager ); - this._parser = THREE.KTXLoader.parse; - }; -THREE.KTXLoader.prototype = Object.create( THREE.CompressedTextureLoader.prototype ); -THREE.KTXLoader.prototype.constructor = THREE.KTXLoader; +THREE.KTXLoader.prototype = Object.assign( Object.create( THREE.CompressedTextureLoader.prototype ), { -THREE.KTXLoader.parse = function ( buffer, loadMipmaps ) { + constructor: THREE.KTXLoader, - var ktx = new KhronosTextureContainer( buffer, 1 ); + parse: function ( buffer, loadMipmaps ) { - return { - mipmaps: ktx.mipmaps( loadMipmaps ), - width: ktx.pixelWidth, - height: ktx.pixelHeight, - format: ktx.glInternalFormat, - isCubemap: ktx.numberOfFaces === 6, - mipmapCount: ktx.numberOfMipmapLevels - }; + var ktx = new KhronosTextureContainer( buffer, 1 ); -}; + return { + mipmaps: ktx.mipmaps( loadMipmaps ), + width: ktx.pixelWidth, + height: ktx.pixelHeight, + format: ktx.glInternalFormat, + isCubemap: ktx.numberOfFaces === 6, + mipmapCount: ktx.numberOfMipmapLevels + }; + + } + +} ); var KhronosTextureContainer = ( function () { diff --git a/examples/js/loaders/LDrawLoader.js b/examples/js/loaders/LDrawLoader.js index 39c2672186c8ca..b1f65e8692343c 100644 --- a/examples/js/loaders/LDrawLoader.js +++ b/examples/js/loaders/LDrawLoader.js @@ -77,10 +77,10 @@ THREE.LDrawLoader = ( function () { #include outgoingLight = diffuseColor.rgb; // simple shader gl_FragColor = vec4( outgoingLight, diffuseColor.a ); - #include #include #include #include + #include } `; @@ -450,11 +450,11 @@ THREE.LDrawLoader = ( function () { } - bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); + bufferGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); if ( elementSize === 3 ) { - bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + bufferGeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); } @@ -508,9 +508,9 @@ THREE.LDrawLoader = ( function () { } - bufferGeometry.addAttribute( 'control0', new THREE.BufferAttribute( controlArray0, 3, false ) ); - bufferGeometry.addAttribute( 'control1', new THREE.BufferAttribute( controlArray1, 3, false ) ); - bufferGeometry.addAttribute( 'direction', new THREE.BufferAttribute( directionArray, 3, false ) ); + bufferGeometry.setAttribute( 'control0', new THREE.BufferAttribute( controlArray0, 3, false ) ); + bufferGeometry.setAttribute( 'control1', new THREE.BufferAttribute( controlArray1, 3, false ) ); + bufferGeometry.setAttribute( 'direction', new THREE.BufferAttribute( directionArray, 3, false ) ); } @@ -522,7 +522,7 @@ THREE.LDrawLoader = ( function () { function LDrawLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); // This is a stack of 'parse scopes' with one level per subobject loaded file. // Each level contains a material lib and also other runtime variables passed between parent and child subobjects @@ -530,8 +530,6 @@ THREE.LDrawLoader = ( function () { // Each material library is an object map keyed by colour codes. this.parseScopesStack = null; - this.path = ''; - // Array of THREE.Material this.materials = []; @@ -576,7 +574,7 @@ THREE.LDrawLoader = ( function () { LDrawLoader.FILE_LOCATION_TRY_ABSOLUTE = 5; LDrawLoader.FILE_LOCATION_NOT_FOUND = 6; - LDrawLoader.prototype = { + LDrawLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: LDrawLoader, @@ -608,14 +606,6 @@ THREE.LDrawLoader = ( function () { }, - setPath: function ( value ) { - - this.path = value; - - return this; - - }, - setMaterials: function ( materials ) { // Clears parse scopes stack, adds new scope with material library @@ -1040,8 +1030,6 @@ THREE.LDrawLoader = ( function () { objectParse: function ( text ) { - //console.time( 'LDrawLoader' ); - // Retrieve data from the parent parse scope var parentParseScope = this.getParentParseScope(); @@ -1947,7 +1935,7 @@ THREE.LDrawLoader = ( function () { } - }; + } ); return LDrawLoader; diff --git a/examples/js/loaders/LWOLoader.js b/examples/js/loaders/LWOLoader.js index 9006257d9ab584..6bd03801f5c009 100644 --- a/examples/js/loaders/LWOLoader.js +++ b/examples/js/loaders/LWOLoader.js @@ -2021,25 +2021,23 @@ var lwoTree; THREE.LWOLoader = function ( manager, parameters ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); parameters = parameters || {}; - this.resourcePath = ( parameters.resourcePath !== undefined ) ? parameters.resourcePath : undefined; + this.resourcePath = ( parameters.resourcePath !== undefined ) ? parameters.resourcePath : ''; }; -THREE.LWOLoader.prototype = { +THREE.LWOLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.LWOLoader, - crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { var self = this; - var path = ( self.path === undefined ) ? extractParentUrl( url, 'Objects' ) : self.path; + var path = ( self.path === '' ) ? extractParentUrl( url, 'Objects' ) : self.path; // give the mesh a default name based on the filename var modelName = url.split( path ).pop().split( '.' )[ 0 ]; @@ -2058,27 +2056,6 @@ THREE.LWOLoader.prototype = { }, - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - parse: function ( iffBuffer, path, modelName ) { lwoTree = new IFFParser().parse( iffBuffer ); @@ -2091,7 +2068,7 @@ THREE.LWOLoader.prototype = { } -}; +} ); // Parse the lwoTree object function LWOTreeParser( textureLoader ) { @@ -2276,7 +2253,7 @@ LWOTreeParser.prototype = { if ( ! duplicateUVs ) return; - geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) ); + geometry.setAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) ); }, @@ -2593,11 +2570,11 @@ MaterialParser.prototype = { if ( attributes.Clearcoat && attributes.Clearcoat.value > 0 ) { - params.clearCoat = attributes.Clearcoat.value; + params.clearcoat = attributes.Clearcoat.value; if ( attributes[ 'Clearcoat Gloss' ] ) { - params.clearCoatRoughness = 0.5 * ( 1 - attributes[ 'Clearcoat Gloss' ].value ); + params.clearcoatRoughness = 0.5 * ( 1 - attributes[ 'Clearcoat Gloss' ].value ); } @@ -2781,7 +2758,7 @@ GeometryParser.prototype = { var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geoData.points, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geoData.points, 3 ) ); var indices = this.splitIndices( geoData.vertexIndices, geoData.polygonDimensions ); geometry.setIndex( indices ); @@ -2994,7 +2971,7 @@ GeometryParser.prototype = { } - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( remappedUVs, 2 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( remappedUVs, 2 ) ); }, @@ -3036,6 +3013,8 @@ GeometryParser.prototype = { } + geometry.morphTargetsRelative = false; + }, }; diff --git a/examples/js/loaders/MD2Loader.js b/examples/js/loaders/MD2Loader.js index c8878c9f624864..4f427aa495947d 100644 --- a/examples/js/loaders/MD2Loader.js +++ b/examples/js/loaders/MD2Loader.js @@ -4,11 +4,11 @@ THREE.MD2Loader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.MD2Loader.prototype = { +THREE.MD2Loader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.MD2Loader, @@ -27,13 +27,6 @@ THREE.MD2Loader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: ( function () { var normalData = [ @@ -122,8 +115,6 @@ THREE.MD2Loader.prototype = { return function ( buffer ) { - console.time( 'MD2Loader' ); - var data = new DataView( buffer ); // http://tfc.duke.free.fr/coding/md2-specs-en.html @@ -307,9 +298,9 @@ THREE.MD2Loader.prototype = { } - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); // animation @@ -373,15 +364,14 @@ THREE.MD2Loader.prototype = { geometry.morphAttributes.position = morphPositions; geometry.morphAttributes.normal = morphNormals; + geometry.morphTargetsRelative = false; geometry.animations = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( frames, 10 ); - console.timeEnd( 'MD2Loader' ); - return geometry; }; } )() -}; +} ); diff --git a/examples/js/loaders/MMDLoader.js b/examples/js/loaders/MMDLoader.js index f825c732e73662..2a3f4a47736c9a 100644 --- a/examples/js/loaders/MMDLoader.js +++ b/examples/js/loaders/MMDLoader.js @@ -36,7 +36,7 @@ THREE.MMDLoader = ( function () { */ function MMDLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); this.loader = new THREE.FileLoader( this.manager ); @@ -46,23 +46,10 @@ THREE.MMDLoader = ( function () { } - MMDLoader.prototype = { + MMDLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: MMDLoader, - crossOrigin: 'anonymous', - - /** - * @param {string} crossOrigin - * @return {THREE.MMDLoader} - */ - setCrossOrigin: function ( crossOrigin ) { - - this.crossOrigin = crossOrigin; - return this; - - }, - /** * @param {string} animationPath * @return {THREE.MMDLoader} @@ -74,28 +61,6 @@ THREE.MMDLoader = ( function () { }, - /** - * @param {string} path - * @return {THREE.MMDLoader} - */ - setPath: function ( path ) { - - this.path = path; - return this; - - }, - - /** - * @param {string} resourcePath - * @return {THREE.MMDLoader} - */ - setResoucePath: function ( resourcePath ) { - - this.resourcePath = resourcePath; - return this; - - }, - // Load MMD assets as Three.js Object /** @@ -114,11 +79,11 @@ THREE.MMDLoader = ( function () { var resourcePath; - if ( this.resourcePath !== undefined ) { + if ( this.resourcePath !== '' ) { resourcePath = this.resourcePath; - } else if ( this.path !== undefined ) { + } else if ( this.path !== '' ) { resourcePath = this.path; @@ -340,7 +305,7 @@ THREE.MMDLoader = ( function () { } - }; + } ); // Utilities @@ -940,11 +905,11 @@ THREE.MMDLoader = ( function () { var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); - geometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); - geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + geometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); + geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); geometry.setIndex( indices ); for ( var i = 0, il = groups.length; i < il; i ++ ) { @@ -957,6 +922,7 @@ THREE.MMDLoader = ( function () { geometry.morphTargets = morphTargets; geometry.morphAttributes.position = morphPositions; + geometry.morphTargetsRelative = false; geometry.userData.MMD = { bones: bones, @@ -1067,7 +1033,6 @@ THREE.MMDLoader = ( function () { params.skinning = geometry.bones.length > 0 ? true : false; params.morphTargets = geometry.morphTargets.length > 0 ? true : false; - params.lights = true; params.fog = true; // blend @@ -1319,7 +1284,7 @@ THREE.MMDLoader = ( function () { try { - index = parseInt( filePath.match( 'toon([0-9]{2})\.bmp$' )[ 1 ] ); + index = parseInt( filePath.match( /toon([0-9]{2})\.bmp$/ )[ 1 ] ); } catch ( e ) { @@ -1340,7 +1305,7 @@ THREE.MMDLoader = ( function () { if ( textures[ fullPath ] !== undefined ) return textures[ fullPath ]; - var loader = THREE.Loader.Handlers.get( fullPath ); + var loader = this.manager.getHandler( fullPath ); if ( loader === null ) { diff --git a/examples/js/loaders/MTLLoader.js b/examples/js/loaders/MTLLoader.js index 4e7d9159a032d9..8b57f29b0d1c9f 100644 --- a/examples/js/loaders/MTLLoader.js +++ b/examples/js/loaders/MTLLoader.js @@ -6,16 +6,14 @@ THREE.MTLLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.MTLLoader.prototype = { +THREE.MTLLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.MTLLoader, - crossOrigin: 'anonymous', - /** * Loads and parses a MTL asset from a URL. * @@ -33,7 +31,7 @@ THREE.MTLLoader.prototype = { var scope = this; - var path = ( this.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : this.path; + var path = ( this.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : this.path; var loader = new THREE.FileLoader( this.manager ); loader.setPath( this.path ); @@ -45,58 +43,6 @@ THREE.MTLLoader.prototype = { }, - /** - * Set base path for resolving references. - * If set this path will be prepended to each loaded and found reference. - * - * @see setResourcePath - * @param {String} path - * @return {THREE.MTLLoader} - * - * @example - * mtlLoader.setPath( 'assets/obj/' ); - * mtlLoader.load( 'my.mtl', ... ); - */ - setPath: function ( path ) { - - this.path = path; - return this; - - }, - - /** - * Set base path for additional resources like textures. - * - * @see setPath - * @param {String} path - * @return {THREE.MTLLoader} - * - * @example - * mtlLoader.setPath( 'assets/obj/' ); - * mtlLoader.setResourcePath( 'assets/textures/' ); - * mtlLoader.load( 'my.mtl', ... ); - */ - setResourcePath: function ( path ) { - - this.resourcePath = path; - return this; - - }, - - setTexturePath: function ( path ) { - - console.warn( 'THREE.MTLLoader: .setTexturePath() has been renamed to .setResourcePath().' ); - return this.setResourcePath( path ); - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - setMaterialOptions: function ( value ) { this.materialOptions = value; @@ -174,10 +120,10 @@ THREE.MTLLoader.prototype = { } -}; +} ); /** - * Create a new THREE-MTLLoader.MaterialCreator + * Create a new THREE.MTLLoader.MaterialCreator * @param baseUrl - Url relative to which textures are loaded * @param options - Set of options on how to construct the materials * side: Which side to apply the material @@ -564,8 +510,8 @@ THREE.MTLLoader.MaterialCreator.prototype = { loadTexture: function ( url, mapping, onLoad, onProgress, onError ) { var texture; - var loader = THREE.Loader.Handlers.get( url ); var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager; + var loader = manager.getHandler( url ); if ( loader === null ) { diff --git a/examples/js/loaders/NRRDLoader.js b/examples/js/loaders/NRRDLoader.js index 1eaa5b53c18c51..28edafc8f0a6f4 100644 --- a/examples/js/loaders/NRRDLoader.js +++ b/examples/js/loaders/NRRDLoader.js @@ -4,12 +4,11 @@ THREE.NRRDLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - + THREE.Loader.call( this, manager ); }; -THREE.NRRDLoader.prototype = { +THREE.NRRDLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.NRRDLoader, @@ -28,13 +27,6 @@ THREE.NRRDLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( data ) { // this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X @@ -62,7 +54,7 @@ THREE.NRRDLoader.prototype = { switch ( type ) { - // 1 byte data types + // 1 byte data types case 'uchar': break; case 'schar': @@ -600,4 +592,4 @@ THREE.NRRDLoader.prototype = { } } -}; +} ); diff --git a/examples/js/loaders/OBJLoader.js b/examples/js/loaders/OBJLoader.js index 8e2ae4c53b622d..be9abbf2405dc1 100644 --- a/examples/js/loaders/OBJLoader.js +++ b/examples/js/loaders/OBJLoader.js @@ -10,6 +10,8 @@ THREE.OBJLoader = ( function () { var material_library_pattern = /^mtllib /; // usemtl material_name var material_use_pattern = /^usemtl /; + // usemap map_name + var map_use_pattern = /^usemap /; function ParserState() { @@ -22,6 +24,7 @@ THREE.OBJLoader = ( function () { colors: [], uvs: [], + materials: {}, materialLibraries: [], startObject: function ( name, fromDeclaration ) { @@ -286,6 +289,12 @@ THREE.OBJLoader = ( function () { this.addVertex( ia, ib, ic ); + if ( this.colors.length > 0 ) { + + this.addColor( ia, ib, ic ); + + } + if ( ua !== undefined && ua !== '' ) { var uvLen = this.uvs.length; @@ -309,12 +318,6 @@ THREE.OBJLoader = ( function () { } - if ( this.colors.length > 0 ) { - - this.addColor( ia, ib, ic ); - - } - }, addPointGeometry: function ( vertices ) { @@ -364,13 +367,13 @@ THREE.OBJLoader = ( function () { function OBJLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); this.materials = null; } - OBJLoader.prototype = { + OBJLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: OBJLoader, @@ -388,14 +391,6 @@ THREE.OBJLoader = ( function () { }, - setPath: function ( value ) { - - this.path = value; - - return this; - - }, - setMaterials: function ( materials ) { this.materials = materials; @@ -406,8 +401,6 @@ THREE.OBJLoader = ( function () { parse: function ( text ) { - console.time( 'OBJLoader' ); - var state = new ParserState(); if ( text.indexOf( '\r\n' ) !== - 1 ) { @@ -578,6 +571,13 @@ THREE.OBJLoader = ( function () { state.materialLibraries.push( line.substring( 7 ).trim() ); + } else if ( map_use_pattern.test( line ) ) { + + // the line is parsed but ignored since the loader assumes textures are defined MTL files + // (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method) + + console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' ); + } else if ( lineFirstChar === 's' ) { result = line.split( ' ' ); @@ -621,7 +621,7 @@ THREE.OBJLoader = ( function () { // Handle null terminated files without exception if ( line === '\0' ) continue; - throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' ); + console.warn( 'THREE.OBJLoader: Unexpected line: "' + line + '"' ); } @@ -646,11 +646,11 @@ THREE.OBJLoader = ( function () { var buffergeometry = new THREE.BufferGeometry(); - buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) ); + buffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) ); if ( geometry.normals.length > 0 ) { - buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) ); + buffergeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) ); } else { @@ -661,13 +661,13 @@ THREE.OBJLoader = ( function () { if ( geometry.colors.length > 0 ) { hasVertexColors = true; - buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) ); + buffergeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) ); } if ( geometry.uvs.length > 0 ) { - buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) ); + buffergeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) ); } @@ -678,7 +678,8 @@ THREE.OBJLoader = ( function () { for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) { var sourceMaterial = materials[ mi ]; - var material = undefined; + var materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors; + var material = state.materials[ materialHash ]; if ( this.materials !== null ) { @@ -690,7 +691,6 @@ THREE.OBJLoader = ( function () { var materialLine = new THREE.LineBasicMaterial(); THREE.Material.prototype.copy.call( materialLine, material ); materialLine.color.copy( material.color ); - materialLine.lights = false; material = materialLine; } else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) { @@ -699,14 +699,13 @@ THREE.OBJLoader = ( function () { THREE.Material.prototype.copy.call( materialPoints, material ); materialPoints.color.copy( material.color ); materialPoints.map = material.map; - materialPoints.lights = false; material = materialPoints; } } - if ( ! material ) { + if ( material === undefined ) { if ( isLine ) { @@ -723,11 +722,12 @@ THREE.OBJLoader = ( function () { } material.name = sourceMaterial.name; + material.flatShading = sourceMaterial.smooth ? false : true; + material.vertexColors = hasVertexColors; - } + state.materials[ materialHash ] = material; - material.flatShading = sourceMaterial.smooth ? false : true; - material.vertexColors = hasVertexColors ? THREE.VertexColors : THREE.NoColors; + } createdMaterials.push( material ); @@ -784,13 +784,11 @@ THREE.OBJLoader = ( function () { } - console.timeEnd( 'OBJLoader' ); - return container; } - }; + } ); return OBJLoader; diff --git a/examples/js/loaders/PCDLoader.js b/examples/js/loaders/PCDLoader.js index fe5e554acdaf5f..48a4b5e76f78b4 100644 --- a/examples/js/loaders/PCDLoader.js +++ b/examples/js/loaders/PCDLoader.js @@ -3,20 +3,18 @@ * @author Mugen87 / https://github.com/Mugen87 * * Description: A THREE loader for PCD ascii and binary files. - * - * Limitations: Compressed binary files are not supported. - * */ THREE.PCDLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + this.littleEndian = true; }; -THREE.PCDLoader.prototype = { +THREE.PCDLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.PCDLoader, @@ -51,14 +49,61 @@ THREE.PCDLoader.prototype = { }, - setPath: function ( value ) { + parse: function ( data, url ) { - this.path = value; - return this; + // from https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js - }, + function decompressLZF( inData, outLength ) { - parse: function ( data, url ) { + var inLength = inData.length; + var outData = new Uint8Array( outLength ); + var inPtr = 0; + var outPtr = 0; + var ctrl; + var len; + var ref; + do { + + ctrl = inData[ inPtr ++ ]; + if ( ctrl < ( 1 << 5 ) ) { + + ctrl ++; + if ( outPtr + ctrl > outLength ) throw new Error( 'Output buffer is not large enough' ); + if ( inPtr + ctrl > inLength ) throw new Error( 'Invalid compressed data' ); + do { + + outData[ outPtr ++ ] = inData[ inPtr ++ ]; + + } while ( -- ctrl ); + + } else { + + len = ctrl >> 5; + ref = outPtr - ( ( ctrl & 0x1f ) << 8 ) - 1; + if ( inPtr >= inLength ) throw new Error( 'Invalid compressed data' ); + if ( len === 7 ) { + + len += inData[ inPtr ++ ]; + if ( inPtr >= inLength ) throw new Error( 'Invalid compressed data' ); + + } + ref -= inData[ inPtr ++ ]; + if ( outPtr + len + 2 > outLength ) throw new Error( 'Output buffer is not large enough' ); + if ( ref < 0 ) throw new Error( 'Invalid compressed data' ); + if ( ref >= outPtr ) throw new Error( 'Invalid compressed data' ); + do { + + outData[ outPtr ++ ] = outData[ ref ++ ]; + + } while ( -- len + 2 ); + + } + + } while ( inPtr < inLength ); + + return outData; + + } function parseHeader( data ) { @@ -225,15 +270,54 @@ THREE.PCDLoader.prototype = { } - // binary + // binary-compressed + + // normally data in PCD files are organized as array of structures: XYZRGBXYZRGB + // binary compressed PCD files organize their data as structure of arrays: XXYYZZRGBRGB + // that requires a totally different parsing approach compared to non-compressed data if ( PCDheader.data === 'binary_compressed' ) { - console.error( 'THREE.PCDLoader: binary_compressed files are not supported' ); - return; + var sizes = new Uint32Array( data.slice( PCDheader.headerLen, PCDheader.headerLen + 8 ) ); + var compressedSize = sizes[ 0 ]; + var decompressedSize = sizes[ 1 ]; + var decompressed = decompressLZF( new Uint8Array( data, PCDheader.headerLen + 8, compressedSize ), decompressedSize ); + var dataview = new DataView( decompressed.buffer ); + + var offset = PCDheader.offset; + + for ( var i = 0; i < PCDheader.points; i ++ ) { + + if ( offset.x !== undefined ) { + + position.push( dataview.getFloat32( ( PCDheader.points * offset.x ) + PCDheader.size[ 0 ] * i, this.littleEndian ) ); + position.push( dataview.getFloat32( ( PCDheader.points * offset.y ) + PCDheader.size[ 1 ] * i, this.littleEndian ) ); + position.push( dataview.getFloat32( ( PCDheader.points * offset.z ) + PCDheader.size[ 2 ] * i, this.littleEndian ) ); + + } + + if ( offset.rgb !== undefined ) { + + color.push( dataview.getUint8( ( PCDheader.points * offset.rgb ) + PCDheader.size[ 3 ] * i + 0 ) / 255.0 ); + color.push( dataview.getUint8( ( PCDheader.points * offset.rgb ) + PCDheader.size[ 3 ] * i + 1 ) / 255.0 ); + color.push( dataview.getUint8( ( PCDheader.points * offset.rgb ) + PCDheader.size[ 3 ] * i + 2 ) / 255.0 ); + + } + + if ( offset.normal_x !== undefined ) { + + normal.push( dataview.getFloat32( ( PCDheader.points * offset.normal_x ) + PCDheader.size[ 4 ] * i, this.littleEndian ) ); + normal.push( dataview.getFloat32( ( PCDheader.points * offset.normal_y ) + PCDheader.size[ 5 ] * i, this.littleEndian ) ); + normal.push( dataview.getFloat32( ( PCDheader.points * offset.normal_z ) + PCDheader.size[ 6 ] * i, this.littleEndian ) ); + + } + + } } + // binary + if ( PCDheader.data === 'binary' ) { var dataview = new DataView( data, PCDheader.headerLen ); @@ -273,9 +357,9 @@ THREE.PCDLoader.prototype = { var geometry = new THREE.BufferGeometry(); - if ( position.length > 0 ) geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); - if ( normal.length > 0 ) geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normal, 3 ) ); - if ( color.length > 0 ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) ); + if ( position.length > 0 ) geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); + if ( normal.length > 0 ) geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normal, 3 ) ); + if ( color.length > 0 ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) ); geometry.computeBoundingSphere(); @@ -285,7 +369,7 @@ THREE.PCDLoader.prototype = { if ( color.length > 0 ) { - material.vertexColors = THREE.VertexColors; + material.vertexColors = true; } else { @@ -293,7 +377,7 @@ THREE.PCDLoader.prototype = { } - // build mesh + // build point cloud var mesh = new THREE.Points( geometry, material ); var name = url.split( '' ).reverse().join( '' ); @@ -305,4 +389,4 @@ THREE.PCDLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/PDBLoader.js b/examples/js/loaders/PDBLoader.js index 3de2385acd991f..62207596d9a20c 100644 --- a/examples/js/loaders/PDBLoader.js +++ b/examples/js/loaders/PDBLoader.js @@ -5,11 +5,11 @@ THREE.PDBLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.PDBLoader.prototype = { +THREE.PDBLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.PDBLoader, @@ -27,13 +27,6 @@ THREE.PDBLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - // Based on CanvasMol PDB parser parse: function ( text ) { @@ -143,10 +136,10 @@ THREE.PDBLoader.prototype = { // build geometry - geometryAtoms.addAttribute( 'position', new THREE.Float32BufferAttribute( verticesAtoms, 3 ) ); - geometryAtoms.addAttribute( 'color', new THREE.Float32BufferAttribute( colorsAtoms, 3 ) ); + geometryAtoms.setAttribute( 'position', new THREE.Float32BufferAttribute( verticesAtoms, 3 ) ); + geometryAtoms.setAttribute( 'color', new THREE.Float32BufferAttribute( colorsAtoms, 3 ) ); - geometryBonds.addAttribute( 'position', new THREE.Float32BufferAttribute( verticesBonds, 3 ) ); + geometryBonds.setAttribute( 'position', new THREE.Float32BufferAttribute( verticesBonds, 3 ) ); return build; @@ -214,4 +207,4 @@ THREE.PDBLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/PLYLoader.js b/examples/js/loaders/PLYLoader.js index b0efd85b312703..905e17214fb449 100644 --- a/examples/js/loaders/PLYLoader.js +++ b/examples/js/loaders/PLYLoader.js @@ -29,13 +29,13 @@ THREE.PLYLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); this.propertyNameMapping = {}; }; -THREE.PLYLoader.prototype = { +THREE.PLYLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.PLYLoader, @@ -54,13 +54,6 @@ THREE.PLYLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - setPropertyNameMapping: function ( mapping ) { this.propertyNameMapping = mapping; @@ -303,32 +296,32 @@ THREE.PLYLoader.prototype = { } - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) ); // optional buffer data if ( buffer.normals.length > 0 ) { - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( buffer.normals, 3 ) ); + geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( buffer.normals, 3 ) ); } if ( buffer.uvs.length > 0 ) { - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( buffer.uvs, 2 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( buffer.uvs, 2 ) ); } if ( buffer.colors.length > 0 ) { - geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( buffer.colors, 3 ) ); + geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( buffer.colors, 3 ) ); } if ( buffer.faceVertexUvs.length > 0 ) { geometry = geometry.toNonIndexed(); - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( buffer.faceVertexUvs, 2 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( buffer.faceVertexUvs, 2 ) ); } @@ -502,4 +495,4 @@ THREE.PLYLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/PRWMLoader.js b/examples/js/loaders/PRWMLoader.js index a25cfecc9df098..d99092cc019cc0 100644 --- a/examples/js/loaders/PRWMLoader.js +++ b/examples/js/loaders/PRWMLoader.js @@ -224,13 +224,13 @@ THREE.PRWMLoader = ( function () { function PRWMLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); } - PRWMLoader.prototype = { + PRWMLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { - constructor: THREE.PRWMLoader, + constructor: PRWMLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -250,13 +250,6 @@ THREE.PRWMLoader = ( function () { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( arrayBuffer ) { var data = decodePrwm( arrayBuffer ), @@ -268,7 +261,7 @@ THREE.PRWMLoader = ( function () { for ( i = 0; i < attributesKey.length; i ++ ) { attribute = data.attributes[ attributesKey[ i ] ]; - bufferGeometry.addAttribute( attributesKey[ i ], new THREE.BufferAttribute( attribute.values, attribute.cardinality, attribute.normalized ) ); + bufferGeometry.setAttribute( attributesKey[ i ], new THREE.BufferAttribute( attribute.values, attribute.cardinality, attribute.normalized ) ); } @@ -282,7 +275,7 @@ THREE.PRWMLoader = ( function () { } - }; + } ); PRWMLoader.isBigEndianPlatform = function () { diff --git a/examples/js/loaders/PVRLoader.js b/examples/js/loaders/PVRLoader.js index a4007eedf85b54..a5b89ad0caa069 100644 --- a/examples/js/loaders/PVRLoader.js +++ b/examples/js/loaders/PVRLoader.js @@ -12,44 +12,44 @@ THREE.PVRLoader = function ( manager ) { THREE.CompressedTextureLoader.call( this, manager ); - this._parser = THREE.PVRLoader.parse; - }; -THREE.PVRLoader.prototype = Object.create( THREE.CompressedTextureLoader.prototype ); -THREE.PVRLoader.prototype.constructor = THREE.PVRLoader; +THREE.PVRLoader.prototype = Object.assign( Object.create( THREE.CompressedTextureLoader.prototype ), { + constructor: THREE.PVRLoader, -THREE.PVRLoader.parse = function ( buffer, loadMipmaps ) { + parse: function ( buffer, loadMipmaps ) { - var headerLengthInt = 13; - var header = new Uint32Array( buffer, 0, headerLengthInt ); + var headerLengthInt = 13; + var header = new Uint32Array( buffer, 0, headerLengthInt ); - var pvrDatas = { - buffer: buffer, - header: header, - loadMipmaps: loadMipmaps - }; + var pvrDatas = { + buffer: buffer, + header: header, + loadMipmaps: loadMipmaps + }; - if ( header[ 0 ] === 0x03525650 ) { + if ( header[ 0 ] === 0x03525650 ) { - // PVR v3 + // PVR v3 - return THREE.PVRLoader._parseV3( pvrDatas ); + return THREE.PVRLoader._parseV3( pvrDatas ); - } else if ( header[ 11 ] === 0x21525650 ) { + } else if ( header[ 11 ] === 0x21525650 ) { - // PVR v2 + // PVR v2 - return THREE.PVRLoader._parseV2( pvrDatas ); + return THREE.PVRLoader._parseV2( pvrDatas ); - } else { + } else { - console.error( 'THREE.PVRLoader: Unknown PVR format.' ); + console.error( 'THREE.PVRLoader: Unknown PVR format.' ); + + } } -}; +} ); THREE.PVRLoader._parseV3 = function ( pvrDatas ) { diff --git a/examples/js/loaders/PlayCanvasLoader.js b/examples/js/loaders/PlayCanvasLoader.js deleted file mode 100644 index 00f8ced7dc1284..00000000000000 --- a/examples/js/loaders/PlayCanvasLoader.js +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 - */ - -THREE.PlayCanvasLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.PlayCanvasLoader.prototype = { - - constructor: THREE.PlayCanvasLoader, - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var loader = new THREE.FileLoader( scope.manager ); - loader.setPath( scope.path ); - loader.load( url, function ( text ) { - - onLoad( scope.parse( JSON.parse( text ) ) ); - - }, onProgress, onError ); - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - parse: function ( json ) { - - function parseVertices( data ) { - - var attributes = {}; - - // create a buffer attribute for each array that contains vertex information - - for ( var name in data ) { - - var array = data[ name ]; - - var type = array.type; - var size = array.components; - - var attribute; - - switch ( type ) { - - case 'float32': - attribute = new THREE.Float32BufferAttribute( array.data, size ); - break; - - case 'uint8': - attribute = new THREE.Uint8BufferAttribute( array.data, size ); - break; - - case 'uint16': - attribute = new THREE.Uint16BufferAttribute( array.data, size ); - break; - - default: - console.log( 'THREE.PlayCanvasLoader: Array type "%s" not yet supported.', type ); - - } - - attributes[ name ] = attribute; - - } - - data._attributes = attributes; - - } - - function parseMeshes( data ) { - - // create buffer geometry - - var geometry = new THREE.BufferGeometry(); - - geometry.setIndex( data.indices ); - - var attributes = model.vertices[ data.vertices ]._attributes; - - for ( var name in attributes ) { - - var attribute = attributes[ name ]; - - if ( name === 'texCoord0' ) name = 'uv'; - - geometry.addAttribute( name, attribute ); - - } - - data._geometry = geometry; - - } - - function parseMeshInstances( data ) { - - var node = model.nodes[ data.node ]; - var mesh = model.meshes[ data.mesh ]; - - if ( node._geometries === undefined ) { - - node._geometries = []; - - } - - node._geometries.push( mesh._geometry ); - - } - - function parseNodes( data ) { - - var object = new THREE.Group(); - - var geometries = data._geometries; - - if ( geometries !== undefined ) { - - var material = new THREE.MeshPhongMaterial(); - - for ( var i = 0, l = geometries.length; i < l; i ++ ) { - - var geometry = geometries[ i ]; - - object.add( new THREE.Mesh( geometry, material ) ); - - } - - } - - for ( var i = 0, l = data.rotation.length; i < l; i ++ ) { - - data.rotation[ i ] *= Math.PI / 180; - - } - - // - - object.name = data.name; - - object.position.fromArray( data.position ); - object.quaternion.setFromEuler( new THREE.Euler().fromArray( data.rotation ) ); - object.scale.fromArray( data.scale ); - - data._object = object; - - } - - // - - var model = json.model; - - for ( var i = 0, l = model.vertices.length; i < l; i ++ ) { - - parseVertices( model.vertices[ i ] ); - - } - - for ( var i = 0, l = model.meshes.length; i < l; i ++ ) { - - parseMeshes( model.meshes[ i ] ); - - } - - for ( var i = 0, l = model.meshInstances.length; i < l; i ++ ) { - - parseMeshInstances( model.meshInstances[ i ] ); - - } - - for ( var i = 0, l = model.nodes.length; i < l; i ++ ) { - - parseNodes( model.nodes[ i ] ); - - } - - // setup scene hierarchy - - for ( var i = 0, l = model.parents.length; i < l; i ++ ) { - - var parent = model.parents[ i ]; - - if ( parent === - 1 ) continue; - - model.nodes[ parent ]._object.add( model.nodes[ i ]._object ); - - - } - - return model.nodes[ 0 ]._object; - - } - -}; diff --git a/examples/js/loaders/RGBELoader.js b/examples/js/loaders/RGBELoader.js index 88ea82b2f18130..c74e4b7632f411 100644 --- a/examples/js/loaders/RGBELoader.js +++ b/examples/js/loaders/RGBELoader.js @@ -7,523 +7,520 @@ THREE.RGBELoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.DataTextureLoader.call( this, manager ); + this.type = THREE.UnsignedByteType; }; -// extend THREE.DataTextureLoader -THREE.RGBELoader.prototype = Object.create( THREE.DataTextureLoader.prototype ); +THREE.RGBELoader.prototype = Object.assign( Object.create( THREE.DataTextureLoader.prototype ), { -// adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html -THREE.RGBELoader.prototype._parser = function ( buffer ) { + constructor: THREE.RGBELoader, - var - /* return codes for rgbe routines */ - //RGBE_RETURN_SUCCESS = 0, - RGBE_RETURN_FAILURE = - 1, + // adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html - /* default error routine. change this to change error handling */ - rgbe_read_error = 1, - rgbe_write_error = 2, - rgbe_format_error = 3, - rgbe_memory_error = 4, - rgbe_error = function ( rgbe_error_code, msg ) { + parse: function ( buffer ) { - switch ( rgbe_error_code ) { + var + /* return codes for rgbe routines */ + //RGBE_RETURN_SUCCESS = 0, + RGBE_RETURN_FAILURE = - 1, - case rgbe_read_error: console.error( "THREE.RGBELoader Read Error: " + ( msg || '' ) ); - break; - case rgbe_write_error: console.error( "THREE.RGBELoader Write Error: " + ( msg || '' ) ); - break; - case rgbe_format_error: console.error( "THREE.RGBELoader Bad File Format: " + ( msg || '' ) ); - break; - default: - case rgbe_memory_error: console.error( "THREE.RGBELoader: Error: " + ( msg || '' ) ); + /* default error routine. change this to change error handling */ + rgbe_read_error = 1, + rgbe_write_error = 2, + rgbe_format_error = 3, + rgbe_memory_error = 4, + rgbe_error = function ( rgbe_error_code, msg ) { - } - return RGBE_RETURN_FAILURE; + switch ( rgbe_error_code ) { - }, + case rgbe_read_error: console.error( "THREE.RGBELoader Read Error: " + ( msg || '' ) ); + break; + case rgbe_write_error: console.error( "THREE.RGBELoader Write Error: " + ( msg || '' ) ); + break; + case rgbe_format_error: console.error( "THREE.RGBELoader Bad File Format: " + ( msg || '' ) ); + break; + default: + case rgbe_memory_error: console.error( "THREE.RGBELoader: Error: " + ( msg || '' ) ); - /* offsets to red, green, and blue components in a data (float) pixel */ - //RGBE_DATA_RED = 0, - //RGBE_DATA_GREEN = 1, - //RGBE_DATA_BLUE = 2, + } + return RGBE_RETURN_FAILURE; - /* number of floats per pixel, use 4 since stored in rgba image format */ - //RGBE_DATA_SIZE = 4, + }, - /* flags indicating which fields in an rgbe_header_info are valid */ - RGBE_VALID_PROGRAMTYPE = 1, - RGBE_VALID_FORMAT = 2, - RGBE_VALID_DIMENSIONS = 4, + /* offsets to red, green, and blue components in a data (float) pixel */ + //RGBE_DATA_RED = 0, + //RGBE_DATA_GREEN = 1, + //RGBE_DATA_BLUE = 2, - NEWLINE = "\n", + /* number of floats per pixel, use 4 since stored in rgba image format */ + //RGBE_DATA_SIZE = 4, - fgets = function ( buffer, lineLimit, consume ) { + /* flags indicating which fields in an rgbe_header_info are valid */ + RGBE_VALID_PROGRAMTYPE = 1, + RGBE_VALID_FORMAT = 2, + RGBE_VALID_DIMENSIONS = 4, - lineLimit = ! lineLimit ? 1024 : lineLimit; - var p = buffer.pos, - i = - 1, len = 0, s = '', chunkSize = 128, - chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) ) - ; - while ( ( 0 > ( i = chunk.indexOf( NEWLINE ) ) ) && ( len < lineLimit ) && ( p < buffer.byteLength ) ) { + NEWLINE = "\n", - s += chunk; len += chunk.length; - p += chunkSize; - chunk += String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) ); + fgets = function ( buffer, lineLimit, consume ) { - } + lineLimit = ! lineLimit ? 1024 : lineLimit; + var p = buffer.pos, + i = - 1, len = 0, s = '', chunkSize = 128, + chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) ) + ; + while ( ( 0 > ( i = chunk.indexOf( NEWLINE ) ) ) && ( len < lineLimit ) && ( p < buffer.byteLength ) ) { - if ( - 1 < i ) { + s += chunk; len += chunk.length; + p += chunkSize; + chunk += String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) ); - /*for (i=l-1; i>=0; i--) { - byteCode = m.charCodeAt(i); - if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++; - else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2; - if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate - }*/ - if ( false !== consume ) buffer.pos += len + i + 1; - return s + chunk.slice( 0, i ); + } - } - return false; + if ( - 1 < i ) { - }, + /*for (i=l-1; i>=0; i--) { + byteCode = m.charCodeAt(i); + if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++; + else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2; + if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate + }*/ + if ( false !== consume ) buffer.pos += len + i + 1; + return s + chunk.slice( 0, i ); - /* minimal header reading. modify if you want to parse more information */ - RGBE_ReadHeader = function ( buffer ) { + } + return false; - var line, match, + }, - // regexes to parse header info fields - magic_token_re = /^#\?(\S+)$/, - gamma_re = /^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/, - exposure_re = /^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/, - format_re = /^\s*FORMAT=(\S+)\s*$/, - dimensions_re = /^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/, + /* minimal header reading. modify if you want to parse more information */ + RGBE_ReadHeader = function ( buffer ) { - // RGBE format header struct - header = { + var line, match, - valid: 0, /* indicate which fields are valid */ + // regexes to parse header info fields + magic_token_re = /^#\?(\S+)$/, + gamma_re = /^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/, + exposure_re = /^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/, + format_re = /^\s*FORMAT=(\S+)\s*$/, + dimensions_re = /^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/, - string: '', /* the actual header string */ + // RGBE format header struct + header = { - comments: '', /* comments found in header */ + valid: 0, /* indicate which fields are valid */ - programtype: 'RGBE', /* listed at beginning of file to identify it after "#?". defaults to "RGBE" */ + string: '', /* the actual header string */ - format: '', /* RGBE format, default 32-bit_rle_rgbe */ + comments: '', /* comments found in header */ - gamma: 1.0, /* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */ + programtype: 'RGBE', /* listed at beginning of file to identify it after "#?". defaults to "RGBE" */ - exposure: 1.0, /* a value of 1.0 in an image corresponds to watts/steradian/m^2. defaults to 1.0 */ + format: '', /* RGBE format, default 32-bit_rle_rgbe */ - width: 0, height: 0 /* image dimensions, width/height */ + gamma: 1.0, /* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */ - }; + exposure: 1.0, /* a value of 1.0 in an image corresponds to watts/steradian/m^2. defaults to 1.0 */ - if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) { + width: 0, height: 0 /* image dimensions, width/height */ - return rgbe_error( rgbe_read_error, "no header found" ); + }; - } - /* if you want to require the magic token then uncomment the next line */ - if ( ! ( match = line.match( magic_token_re ) ) ) { + if ( buffer.pos >= buffer.byteLength || ! ( line = fgets( buffer ) ) ) { - return rgbe_error( rgbe_format_error, "bad initial token" ); + return rgbe_error( rgbe_read_error, "no header found" ); - } - header.valid |= RGBE_VALID_PROGRAMTYPE; - header.programtype = match[ 1 ]; - header.string += line + "\n"; - - while ( true ) { - - line = fgets( buffer ); - if ( false === line ) break; - header.string += line + "\n"; - - if ( '#' === line.charAt( 0 ) ) { + } + /* if you want to require the magic token then uncomment the next line */ + if ( ! ( match = line.match( magic_token_re ) ) ) { - header.comments += line + "\n"; - continue; // comment line + return rgbe_error( rgbe_format_error, "bad initial token" ); } + header.valid |= RGBE_VALID_PROGRAMTYPE; + header.programtype = match[ 1 ]; + header.string += line + "\n"; - if ( match = line.match( gamma_re ) ) { + while ( true ) { - header.gamma = parseFloat( match[ 1 ], 10 ); + line = fgets( buffer ); + if ( false === line ) break; + header.string += line + "\n"; - } - if ( match = line.match( exposure_re ) ) { + if ( '#' === line.charAt( 0 ) ) { - header.exposure = parseFloat( match[ 1 ], 10 ); + header.comments += line + "\n"; + continue; // comment line - } - if ( match = line.match( format_re ) ) { + } - header.valid |= RGBE_VALID_FORMAT; - header.format = match[ 1 ];//'32-bit_rle_rgbe'; + if ( match = line.match( gamma_re ) ) { - } - if ( match = line.match( dimensions_re ) ) { + header.gamma = parseFloat( match[ 1 ], 10 ); - header.valid |= RGBE_VALID_DIMENSIONS; - header.height = parseInt( match[ 1 ], 10 ); - header.width = parseInt( match[ 2 ], 10 ); + } + if ( match = line.match( exposure_re ) ) { - } + header.exposure = parseFloat( match[ 1 ], 10 ); - if ( ( header.valid & RGBE_VALID_FORMAT ) && ( header.valid & RGBE_VALID_DIMENSIONS ) ) break; + } + if ( match = line.match( format_re ) ) { - } + header.valid |= RGBE_VALID_FORMAT; + header.format = match[ 1 ];//'32-bit_rle_rgbe'; - if ( ! ( header.valid & RGBE_VALID_FORMAT ) ) { + } + if ( match = line.match( dimensions_re ) ) { - return rgbe_error( rgbe_format_error, "missing format specifier" ); + header.valid |= RGBE_VALID_DIMENSIONS; + header.height = parseInt( match[ 1 ], 10 ); + header.width = parseInt( match[ 2 ], 10 ); - } - if ( ! ( header.valid & RGBE_VALID_DIMENSIONS ) ) { + } - return rgbe_error( rgbe_format_error, "missing image size specifier" ); + if ( ( header.valid & RGBE_VALID_FORMAT ) && ( header.valid & RGBE_VALID_DIMENSIONS ) ) break; - } + } - return header; + if ( ! ( header.valid & RGBE_VALID_FORMAT ) ) { - }, + return rgbe_error( rgbe_format_error, "missing format specifier" ); - RGBE_ReadPixels_RLE = function ( buffer, w, h ) { + } + if ( ! ( header.valid & RGBE_VALID_DIMENSIONS ) ) { - var data_rgba, offset, pos, count, byteValue, - scanline_buffer, ptr, ptr_end, i, l, off, isEncodedRun, - scanline_width = w, num_scanlines = h, rgbeStart - ; + return rgbe_error( rgbe_format_error, "missing image size specifier" ); - if ( - // run length encoding is not allowed so read flat - ( ( scanline_width < 8 ) || ( scanline_width > 0x7fff ) ) || - // this file is not run length encoded - ( ( 2 !== buffer[ 0 ] ) || ( 2 !== buffer[ 1 ] ) || ( buffer[ 2 ] & 0x80 ) ) - ) { + } - // return the flat buffer - return new Uint8Array( buffer ); + return header; - } + }, - if ( scanline_width !== ( ( buffer[ 2 ] << 8 ) | buffer[ 3 ] ) ) { + RGBE_ReadPixels_RLE = function ( buffer, w, h ) { - return rgbe_error( rgbe_format_error, "wrong scanline width" ); + var data_rgba, offset, pos, count, byteValue, + scanline_buffer, ptr, ptr_end, i, l, off, isEncodedRun, + scanline_width = w, num_scanlines = h, rgbeStart + ; - } + if ( + // run length encoding is not allowed so read flat + ( ( scanline_width < 8 ) || ( scanline_width > 0x7fff ) ) || + // this file is not run length encoded + ( ( 2 !== buffer[ 0 ] ) || ( 2 !== buffer[ 1 ] ) || ( buffer[ 2 ] & 0x80 ) ) + ) { - data_rgba = new Uint8Array( 4 * w * h ); + // return the flat buffer + return new Uint8Array( buffer ); - if ( ! data_rgba || ! data_rgba.length ) { + } - return rgbe_error( rgbe_memory_error, "unable to allocate buffer space" ); + if ( scanline_width !== ( ( buffer[ 2 ] << 8 ) | buffer[ 3 ] ) ) { - } + return rgbe_error( rgbe_format_error, "wrong scanline width" ); - offset = 0; pos = 0; ptr_end = 4 * scanline_width; - rgbeStart = new Uint8Array( 4 ); - scanline_buffer = new Uint8Array( ptr_end ); + } - // read in each successive scanline - while ( ( num_scanlines > 0 ) && ( pos < buffer.byteLength ) ) { + data_rgba = new Uint8Array( 4 * w * h ); - if ( pos + 4 > buffer.byteLength ) { + if ( ! data_rgba || ! data_rgba.length ) { - return rgbe_error( rgbe_read_error ); + return rgbe_error( rgbe_memory_error, "unable to allocate buffer space" ); } - rgbeStart[ 0 ] = buffer[ pos ++ ]; - rgbeStart[ 1 ] = buffer[ pos ++ ]; - rgbeStart[ 2 ] = buffer[ pos ++ ]; - rgbeStart[ 3 ] = buffer[ pos ++ ]; + offset = 0; pos = 0; ptr_end = 4 * scanline_width; + rgbeStart = new Uint8Array( 4 ); + scanline_buffer = new Uint8Array( ptr_end ); - if ( ( 2 != rgbeStart[ 0 ] ) || ( 2 != rgbeStart[ 1 ] ) || ( ( ( rgbeStart[ 2 ] << 8 ) | rgbeStart[ 3 ] ) != scanline_width ) ) { + // read in each successive scanline + while ( ( num_scanlines > 0 ) && ( pos < buffer.byteLength ) ) { - return rgbe_error( rgbe_format_error, "bad rgbe scanline format" ); + if ( pos + 4 > buffer.byteLength ) { - } + return rgbe_error( rgbe_read_error ); - // read each of the four channels for the scanline into the buffer - // first red, then green, then blue, then exponent - ptr = 0; - while ( ( ptr < ptr_end ) && ( pos < buffer.byteLength ) ) { + } - count = buffer[ pos ++ ]; - isEncodedRun = count > 128; - if ( isEncodedRun ) count -= 128; + rgbeStart[ 0 ] = buffer[ pos ++ ]; + rgbeStart[ 1 ] = buffer[ pos ++ ]; + rgbeStart[ 2 ] = buffer[ pos ++ ]; + rgbeStart[ 3 ] = buffer[ pos ++ ]; - if ( ( 0 === count ) || ( ptr + count > ptr_end ) ) { + if ( ( 2 != rgbeStart[ 0 ] ) || ( 2 != rgbeStart[ 1 ] ) || ( ( ( rgbeStart[ 2 ] << 8 ) | rgbeStart[ 3 ] ) != scanline_width ) ) { - return rgbe_error( rgbe_format_error, "bad scanline data" ); + return rgbe_error( rgbe_format_error, "bad rgbe scanline format" ); } - if ( isEncodedRun ) { + // read each of the four channels for the scanline into the buffer + // first red, then green, then blue, then exponent + ptr = 0; + while ( ( ptr < ptr_end ) && ( pos < buffer.byteLength ) ) { + + count = buffer[ pos ++ ]; + isEncodedRun = count > 128; + if ( isEncodedRun ) count -= 128; - // a (encoded) run of the same value - byteValue = buffer[ pos ++ ]; - for ( i = 0; i < count; i ++ ) { + if ( ( 0 === count ) || ( ptr + count > ptr_end ) ) { - scanline_buffer[ ptr ++ ] = byteValue; + return rgbe_error( rgbe_format_error, "bad scanline data" ); } - //ptr += count; - } else { + if ( isEncodedRun ) { + + // a (encoded) run of the same value + byteValue = buffer[ pos ++ ]; + for ( i = 0; i < count; i ++ ) { - // a literal-run - scanline_buffer.set( buffer.subarray( pos, pos + count ), ptr ); - ptr += count; pos += count; + scanline_buffer[ ptr ++ ] = byteValue; + + } + //ptr += count; + + } else { + + // a literal-run + scanline_buffer.set( buffer.subarray( pos, pos + count ), ptr ); + ptr += count; pos += count; + + } } - } + // now convert data from buffer into rgba + // first red, then green, then blue, then exponent (alpha) + l = scanline_width; //scanline_buffer.byteLength; + for ( i = 0; i < l; i ++ ) { - // now convert data from buffer into rgba - // first red, then green, then blue, then exponent (alpha) - l = scanline_width; //scanline_buffer.byteLength; - for ( i = 0; i < l; i ++ ) { + off = 0; + data_rgba[ offset ] = scanline_buffer[ i + off ]; + off += scanline_width; //1; + data_rgba[ offset + 1 ] = scanline_buffer[ i + off ]; + off += scanline_width; //1; + data_rgba[ offset + 2 ] = scanline_buffer[ i + off ]; + off += scanline_width; //1; + data_rgba[ offset + 3 ] = scanline_buffer[ i + off ]; + offset += 4; - off = 0; - data_rgba[ offset ] = scanline_buffer[ i + off ]; - off += scanline_width; //1; - data_rgba[ offset + 1 ] = scanline_buffer[ i + off ]; - off += scanline_width; //1; - data_rgba[ offset + 2 ] = scanline_buffer[ i + off ]; - off += scanline_width; //1; - data_rgba[ offset + 3 ] = scanline_buffer[ i + off ]; - offset += 4; + } + + num_scanlines --; } - num_scanlines --; + return data_rgba; - } + }; - return data_rgba; + var RGBEByteToRGBFloat = function ( sourceArray, sourceOffset, destArray, destOffset ) { - }; + var e = sourceArray[ sourceOffset + 3 ]; + var scale = Math.pow( 2.0, e - 128.0 ) / 255.0; - var RGBEByteToRGBFloat = function ( sourceArray, sourceOffset, destArray, destOffset ) { + destArray[ destOffset + 0 ] = sourceArray[ sourceOffset + 0 ] * scale; + destArray[ destOffset + 1 ] = sourceArray[ sourceOffset + 1 ] * scale; + destArray[ destOffset + 2 ] = sourceArray[ sourceOffset + 2 ] * scale; - var e = sourceArray[ sourceOffset + 3 ]; - var scale = Math.pow( 2.0, e - 128.0 ) / 255.0; + }; - destArray[ destOffset + 0 ] = sourceArray[ sourceOffset + 0 ] * scale; - destArray[ destOffset + 1 ] = sourceArray[ sourceOffset + 1 ] * scale; - destArray[ destOffset + 2 ] = sourceArray[ sourceOffset + 2 ] * scale; + var RGBEByteToRGBHalf = ( function () { - }; + // Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410 - var RGBEByteToRGBHalf = ( function () { + var floatView = new Float32Array( 1 ); + var int32View = new Int32Array( floatView.buffer ); - // Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410 + /* This method is faster than the OpenEXR implementation (very often + * used, eg. in Ogre), with the additional benefit of rounding, inspired + * by James Tursa?s half-precision code. */ + function toHalf( val ) { - var floatView = new Float32Array( 1 ); - var int32View = new Int32Array( floatView.buffer ); + floatView[ 0 ] = val; + var x = int32View[ 0 ]; - /* This method is faster than the OpenEXR implementation (very often - * used, eg. in Ogre), with the additional benefit of rounding, inspired - * by James Tursa?s half-precision code. */ - function toHalf( val ) { + var bits = ( x >> 16 ) & 0x8000; /* Get the sign */ + var m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */ + var e = ( x >> 23 ) & 0xff; /* Using int is faster here */ - floatView[ 0 ] = val; - var x = int32View[ 0 ]; + /* If zero, or denormal, or exponent underflows too much for a denormal + * half, return signed zero. */ + if ( e < 103 ) return bits; - var bits = ( x >> 16 ) & 0x8000; /* Get the sign */ - var m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */ - var e = ( x >> 23 ) & 0xff; /* Using int is faster here */ + /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */ + if ( e > 142 ) { - /* If zero, or denormal, or exponent underflows too much for a denormal - * half, return signed zero. */ - if ( e < 103 ) return bits; + bits |= 0x7c00; + /* If exponent was 0xff and one mantissa bit was set, it means NaN, + * not Inf, so make sure we set one mantissa bit too. */ + bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff ); + return bits; - /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */ - if ( e > 142 ) { + } - bits |= 0x7c00; - /* If exponent was 0xff and one mantissa bit was set, it means NaN, - * not Inf, so make sure we set one mantissa bit too. */ - bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff ); - return bits; + /* If exponent underflows but not too much, return a denormal */ + if ( e < 113 ) { - } + m |= 0x0800; + /* Extra rounding may overflow and set mantissa to 0 and exponent + * to 1, which is OK. */ + bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 ); + return bits; - /* If exponent underflows but not too much, return a denormal */ - if ( e < 113 ) { + } - m |= 0x0800; - /* Extra rounding may overflow and set mantissa to 0 and exponent - * to 1, which is OK. */ - bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 ); + bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 ); + /* Extra rounding. An overflow will set mantissa to 0 and increment + * the exponent, which is OK. */ + bits += m & 1; return bits; } - bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 ); - /* Extra rounding. An overflow will set mantissa to 0 and increment - * the exponent, which is OK. */ - bits += m & 1; - return bits; + return function ( sourceArray, sourceOffset, destArray, destOffset ) { - } + var e = sourceArray[ sourceOffset + 3 ]; + var scale = Math.pow( 2.0, e - 128.0 ) / 255.0; - return function ( sourceArray, sourceOffset, destArray, destOffset ) { + destArray[ destOffset + 0 ] = toHalf( sourceArray[ sourceOffset + 0 ] * scale ); + destArray[ destOffset + 1 ] = toHalf( sourceArray[ sourceOffset + 1 ] * scale ); + destArray[ destOffset + 2 ] = toHalf( sourceArray[ sourceOffset + 2 ] * scale ); - var e = sourceArray[ sourceOffset + 3 ]; - var scale = Math.pow( 2.0, e - 128.0 ) / 255.0; + }; - destArray[ destOffset + 0 ] = toHalf( sourceArray[ sourceOffset + 0 ] * scale ); - destArray[ destOffset + 1 ] = toHalf( sourceArray[ sourceOffset + 1 ] * scale ); - destArray[ destOffset + 2 ] = toHalf( sourceArray[ sourceOffset + 2 ] * scale ); + } )(); - }; + var byteArray = new Uint8Array( buffer ); + byteArray.pos = 0; + var rgbe_header_info = RGBE_ReadHeader( byteArray ); - } )(); + if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) { - var byteArray = new Uint8Array( buffer ); - byteArray.pos = 0; - var rgbe_header_info = RGBE_ReadHeader( byteArray ); + var w = rgbe_header_info.width, + h = rgbe_header_info.height, + image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h ); - if ( RGBE_RETURN_FAILURE !== rgbe_header_info ) { + if ( RGBE_RETURN_FAILURE !== image_rgba_data ) { - var w = rgbe_header_info.width, - h = rgbe_header_info.height, - image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray( byteArray.pos ), w, h ); + switch ( this.type ) { - if ( RGBE_RETURN_FAILURE !== image_rgba_data ) { + case THREE.UnsignedByteType: - switch ( this.type ) { + var data = image_rgba_data; + var format = THREE.RGBEFormat; // handled as THREE.RGBAFormat in shaders + var type = THREE.UnsignedByteType; + break; - case THREE.UnsignedByteType: + case THREE.FloatType: - var data = image_rgba_data; - var format = THREE.RGBEFormat; // handled as THREE.RGBAFormat in shaders - var type = THREE.UnsignedByteType; - break; + var numElements = ( image_rgba_data.length / 4 ) * 3; + var floatArray = new Float32Array( numElements ); - case THREE.FloatType: + for ( var j = 0; j < numElements; j ++ ) { - var numElements = ( image_rgba_data.length / 4 ) * 3; - var floatArray = new Float32Array( numElements ); + RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 3 ); - for ( var j = 0; j < numElements; j ++ ) { + } - RGBEByteToRGBFloat( image_rgba_data, j * 4, floatArray, j * 3 ); + var data = floatArray; + var format = THREE.RGBFormat; + var type = THREE.FloatType; + break; - } + case THREE.HalfFloatType: - var data = floatArray; - var format = THREE.RGBFormat; - var type = THREE.FloatType; - break; + var numElements = ( image_rgba_data.length / 4 ) * 3; + var halfArray = new Uint16Array( numElements ); - case THREE.HalfFloatType: + for ( var j = 0; j < numElements; j ++ ) { - var numElements = ( image_rgba_data.length / 4 ) * 3; - var halfArray = new Uint16Array( numElements ); + RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 3 ); - for ( var j = 0; j < numElements; j ++ ) { + } - RGBEByteToRGBHalf( image_rgba_data, j * 4, halfArray, j * 3 ); + var data = halfArray; + var format = THREE.RGBFormat; + var type = THREE.HalfFloatType; + break; - } + default: - var data = halfArray; - var format = THREE.RGBFormat; - var type = THREE.HalfFloatType; - break; + console.error( 'THREE.RGBELoader: unsupported type: ', this.type ); + break; - default: + } - console.error( 'THREE.RGBELoader: unsupported type: ', this.type ); - break; + return { + width: w, height: h, + data: data, + header: rgbe_header_info.string, + gamma: rgbe_header_info.gamma, + exposure: rgbe_header_info.exposure, + format: format, + type: type + }; } - return { - width: w, height: h, - data: data, - header: rgbe_header_info.string, - gamma: rgbe_header_info.gamma, - exposure: rgbe_header_info.exposure, - format: format, - type: type - }; - } - } - - return null; - -}; - -THREE.RGBELoader.prototype.setDataType = function ( value ) { + return null; - this.type = value; - return this; + }, -}; + setDataType: function ( value ) { -THREE.RGBELoader.prototype.setType = function ( value ) { + this.type = value; + return this; - console.warn( 'THREE.RGBELoader: .setType() has been renamed to .setDataType().' ); + }, - return this.setDataType( value ); + load: function ( url, onLoad, onProgress, onError ) { -}; + function onLoadCallback( texture, texData ) { -THREE.RGBELoader.prototype.load = function ( url, onLoad, onProgress, onError ) { + switch ( texture.type ) { - function onLoadCallback( texture, texData ) { + case THREE.UnsignedByteType: - switch ( texture.type ) { + texture.encoding = THREE.RGBEEncoding; + texture.minFilter = THREE.NearestFilter; + texture.magFilter = THREE.NearestFilter; + texture.generateMipmaps = false; + texture.flipY = true; + break; - case THREE.UnsignedByteType: + case THREE.FloatType: - texture.encoding = THREE.RGBEEncoding; - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.generateMipmaps = false; - texture.flipY = true; - break; + texture.encoding = THREE.LinearEncoding; + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.generateMipmaps = false; + texture.flipY = true; + break; - case THREE.FloatType: + case THREE.HalfFloatType: - texture.encoding = THREE.LinearEncoding; - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.generateMipmaps = false; - texture.flipY = true; - break; + texture.encoding = THREE.LinearEncoding; + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + texture.generateMipmaps = false; + texture.flipY = true; + break; - case THREE.HalfFloatType: + } - texture.encoding = THREE.LinearEncoding; - texture.minFilter = THREE.LinearFilter; - texture.magFilter = THREE.LinearFilter; - texture.generateMipmaps = false; - texture.flipY = true; - break; + if ( onLoad ) onLoad( texture, texData ); } - if ( onLoad ) onLoad( texture, texData ); + return THREE.DataTextureLoader.prototype.load.call( this, url, onLoadCallback, onProgress, onError ); } - return THREE.DataTextureLoader.prototype.load.call( this, url, onLoadCallback, onProgress, onError ); - -}; +} ); diff --git a/examples/js/loaders/STLLoader.js b/examples/js/loaders/STLLoader.js index 2dde1da174cff2..9008bd1362c6cb 100644 --- a/examples/js/loaders/STLLoader.js +++ b/examples/js/loaders/STLLoader.js @@ -25,19 +25,44 @@ * For binary STLs geometry might contain colors for vertices. To use it: * // use the same code to load STL as above * if (geometry.hasColors) { - * material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors }); + * material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: true }); * } else { .... } * var mesh = new THREE.Mesh( geometry, material ); + * + * For ASCII STLs containing multiple solids, each solid is assigned to a different group. + * Groups can be used to assign a different color by defining an array of materials with the same length of + * geometry.groups and passing it to the Mesh constructor: + * + * var mesh = new THREE.Mesh( geometry, material ); + * + * For example: + * + * var materials = []; + * var nGeometryGroups = geometry.groups.length; + * + * var colorMap = ...; // Some logic to index colors. + * + * for (var i = 0; i < nGeometryGroups; i++) { + * + * var material = new THREE.MeshPhongMaterial({ + * color: colorMap[i], + * wireframe: false + * }); + * + * } + * + * materials.push(material); + * var mesh = new THREE.Mesh(geometry, materials); */ THREE.STLLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.STLLoader.prototype = { +THREE.STLLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.STLLoader, @@ -68,13 +93,6 @@ THREE.STLLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( data ) { function isBinary( data ) { @@ -107,7 +125,7 @@ THREE.STLLoader.prototype = { // If "solid" text is matched to the current offset, declare it to be an ASCII STL. - if ( matchDataViewAt ( solid, reader, off ) ) return false; + if ( matchDataViewAt( solid, reader, off ) ) return false; } @@ -201,7 +219,7 @@ THREE.STLLoader.prototype = { var vertexstart = start + i * 12; var componentIdx = ( face * 3 * 3 ) + ( ( i - 1 ) * 3 ); - + vertices[ componentIdx ] = reader.getFloat32( vertexstart, true ); vertices[ componentIdx + 1 ] = reader.getFloat32( vertexstart + 4, true ); vertices[ componentIdx + 2 ] = reader.getFloat32( vertexstart + 8, true ); @@ -222,12 +240,12 @@ THREE.STLLoader.prototype = { } - geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); if ( hasColors ) { - geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); geometry.hasColors = true; geometry.alpha = alpha; @@ -240,6 +258,7 @@ THREE.STLLoader.prototype = { function parseASCII( data ) { var geometry = new THREE.BufferGeometry(); + var patternSolid = /solid([\s\S]*?)endsolid/g; var patternFace = /facet([\s\S]*?)endfacet/g; var faceCounter = 0; @@ -254,52 +273,71 @@ THREE.STLLoader.prototype = { var result; - while ( ( result = patternFace.exec( data ) ) !== null ) { + var groupCount = 0; + var startVertex = 0; + var endVertex = 0; - var vertexCountPerFace = 0; - var normalCountPerFace = 0; + while ( ( result = patternSolid.exec( data ) ) !== null ) { - var text = result[ 0 ]; + startVertex = endVertex; - while ( ( result = patternNormal.exec( text ) ) !== null ) { + var solid = result[ 0 ]; - normal.x = parseFloat( result[ 1 ] ); - normal.y = parseFloat( result[ 2 ] ); - normal.z = parseFloat( result[ 3 ] ); - normalCountPerFace ++; + while ( ( result = patternFace.exec( solid ) ) !== null ) { - } + var vertexCountPerFace = 0; + var normalCountPerFace = 0; - while ( ( result = patternVertex.exec( text ) ) !== null ) { + var text = result[ 0 ]; - vertices.push( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) ); - normals.push( normal.x, normal.y, normal.z ); - vertexCountPerFace ++; + while ( ( result = patternNormal.exec( text ) ) !== null ) { - } + normal.x = parseFloat( result[ 1 ] ); + normal.y = parseFloat( result[ 2 ] ); + normal.z = parseFloat( result[ 3 ] ); + normalCountPerFace ++; - // every face have to own ONE valid normal + } - if ( normalCountPerFace !== 1 ) { + while ( ( result = patternVertex.exec( text ) ) !== null ) { - console.error( 'THREE.STLLoader: Something isn\'t right with the normal of face number ' + faceCounter ); + vertices.push( parseFloat( result[ 1 ] ), parseFloat( result[ 2 ] ), parseFloat( result[ 3 ] ) ); + normals.push( normal.x, normal.y, normal.z ); + vertexCountPerFace ++; + endVertex ++; - } + } - // each face have to own THREE valid vertices + // every face have to own ONE valid normal + + if ( normalCountPerFace !== 1 ) { + + console.error( 'THREE.STLLoader: Something isn\'t right with the normal of face number ' + faceCounter ); + + } - if ( vertexCountPerFace !== 3 ) { + // each face have to own THREE valid vertices - console.error( 'THREE.STLLoader: Something isn\'t right with the vertices of face number ' + faceCounter ); + if ( vertexCountPerFace !== 3 ) { + + console.error( 'THREE.STLLoader: Something isn\'t right with the vertices of face number ' + faceCounter ); + + } + + faceCounter ++; } - faceCounter ++; + var start = startVertex; + var count = endVertex - startVertex; + + geometry.addGroup( start, count, groupCount ); + groupCount ++; } - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); return geometry; @@ -327,6 +365,7 @@ THREE.STLLoader.prototype = { array_buffer[ i ] = buffer.charCodeAt( i ) & 0xff; // implicitly assumes little-endian } + return array_buffer.buffer || array_buffer; } else { @@ -345,4 +384,4 @@ THREE.STLLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/SVGLoader.js b/examples/js/loaders/SVGLoader.js index a55f621e9a84f0..4caea9c63a1c0e 100644 --- a/examples/js/loaders/SVGLoader.js +++ b/examples/js/loaders/SVGLoader.js @@ -6,11 +6,17 @@ THREE.SVGLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + + // Default dots per inch + this.defaultDPI = 90; + + // Accepted units: 'mm', 'cm', 'in', 'pt', 'pc', 'px' + this.defaultUnit = "px"; }; -THREE.SVGLoader.prototype = { +THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.SVGLoader, @@ -28,15 +34,10 @@ THREE.SVGLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( text ) { + var scope = this; + function parseNode( node, style ) { if ( node.nodeType !== 1 ) return; @@ -635,12 +636,12 @@ THREE.SVGLoader.prototype = { */ function parseRectNode( node ) { - var x = parseFloat( node.getAttribute( 'x' ) || 0 ); - var y = parseFloat( node.getAttribute( 'y' ) || 0 ); - var rx = parseFloat( node.getAttribute( 'rx' ) || 0 ); - var ry = parseFloat( node.getAttribute( 'ry' ) || 0 ); - var w = parseFloat( node.getAttribute( 'width' ) ); - var h = parseFloat( node.getAttribute( 'height' ) ); + var x = parseFloatWithUnits( node.getAttribute( 'x' ) || 0 ); + var y = parseFloatWithUnits( node.getAttribute( 'y' ) || 0 ); + var rx = parseFloatWithUnits( node.getAttribute( 'rx' ) || 0 ); + var ry = parseFloatWithUnits( node.getAttribute( 'ry' ) || 0 ); + var w = parseFloatWithUnits( node.getAttribute( 'width' ) ); + var h = parseFloatWithUnits( node.getAttribute( 'height' ) ); var path = new THREE.ShapePath(); path.moveTo( x + 2 * rx, y ); @@ -672,8 +673,8 @@ THREE.SVGLoader.prototype = { function iterator( match, a, b ) { - var x = parseFloat( a ); - var y = parseFloat( b ); + var x = parseFloatWithUnits( a ); + var y = parseFloatWithUnits( b ); if ( index === 0 ) { @@ -707,8 +708,8 @@ THREE.SVGLoader.prototype = { function iterator( match, a, b ) { - var x = parseFloat( a ); - var y = parseFloat( b ); + var x = parseFloatWithUnits( a ); + var y = parseFloatWithUnits( b ); if ( index === 0 ) { @@ -740,9 +741,9 @@ THREE.SVGLoader.prototype = { function parseCircleNode( node ) { - var x = parseFloat( node.getAttribute( 'cx' ) ); - var y = parseFloat( node.getAttribute( 'cy' ) ); - var r = parseFloat( node.getAttribute( 'r' ) ); + var x = parseFloatWithUnits( node.getAttribute( 'cx' ) ); + var y = parseFloatWithUnits( node.getAttribute( 'cy' ) ); + var r = parseFloatWithUnits( node.getAttribute( 'r' ) ); var subpath = new THREE.Path(); subpath.absarc( x, y, r, 0, Math.PI * 2 ); @@ -756,10 +757,10 @@ THREE.SVGLoader.prototype = { function parseEllipseNode( node ) { - var x = parseFloat( node.getAttribute( 'cx' ) ); - var y = parseFloat( node.getAttribute( 'cy' ) ); - var rx = parseFloat( node.getAttribute( 'rx' ) ); - var ry = parseFloat( node.getAttribute( 'ry' ) ); + var x = parseFloatWithUnits( node.getAttribute( 'cx' ) ); + var y = parseFloatWithUnits( node.getAttribute( 'cy' ) ); + var rx = parseFloatWithUnits( node.getAttribute( 'rx' ) ); + var ry = parseFloatWithUnits( node.getAttribute( 'ry' ) ); var subpath = new THREE.Path(); subpath.absellipse( x, y, rx, ry, 0, Math.PI * 2 ); @@ -773,10 +774,10 @@ THREE.SVGLoader.prototype = { function parseLineNode( node ) { - var x1 = parseFloat( node.getAttribute( 'x1' ) ); - var y1 = parseFloat( node.getAttribute( 'y1' ) ); - var x2 = parseFloat( node.getAttribute( 'x2' ) ); - var y2 = parseFloat( node.getAttribute( 'y2' ) ); + var x1 = parseFloatWithUnits( node.getAttribute( 'x1' ) ); + var y1 = parseFloatWithUnits( node.getAttribute( 'y1' ) ); + var x2 = parseFloatWithUnits( node.getAttribute( 'x2' ) ); + var y2 = parseFloatWithUnits( node.getAttribute( 'y2' ) ); var path = new THREE.ShapePath(); path.moveTo( x1, y1 ); @@ -802,19 +803,19 @@ THREE.SVGLoader.prototype = { }; if ( node.hasAttribute( svgName ) ) style[ jsName ] = adjustFunction( node.getAttribute( svgName ) ); - if ( node.style[ svgName ] !== '' ) style[ jsName ] = adjustFunction( node.style[ svgName ] ); + if ( node.style && node.style[ svgName ] !== '' ) style[ jsName ] = adjustFunction( node.style[ svgName ] ); } function clamp( v ) { - return Math.max( 0, Math.min( 1, v ) ); + return Math.max( 0, Math.min( 1, parseFloatWithUnits( v ) ) ); } function positive( v ) { - return Math.max( 0, v ); + return Math.max( 0, parseFloatWithUnits( v ) ); } @@ -862,7 +863,7 @@ THREE.SVGLoader.prototype = { } - array[ i ] = parseFloat( number ); + array[ i ] = parseFloatWithUnits( number ); } @@ -871,6 +872,109 @@ THREE.SVGLoader.prototype = { } + // Units + + var units = [ 'mm', 'cm', 'in', 'pt', 'pc', 'px' ]; + + // Conversion: [ fromUnit ][ toUnit ] (-1 means dpi dependent) + var unitConversion = { + + "mm": { + "mm": 1, + "cm": 0.1, + "in": 1 / 25.4, + "pt": 72 / 25.4, + "pc": 6 / 25.4, + "px": - 1 + }, + "cm": { + "mm": 10, + "cm": 1, + "in": 1 / 2.54, + "pt": 72 / 2.54, + "pc": 6 / 2.54, + "px": - 1 + }, + "in": { + "mm": 25.4, + "cm": 2.54, + "in": 1, + "pt": 72, + "pc": 6, + "px": - 1 + }, + "pt": { + "mm": 25.4 / 72, + "cm": 2.54 / 72, + "in": 1 / 72, + "pt": 1, + "pc": 6 / 72, + "px": - 1 + }, + "pc": { + "mm": 25.4 / 6, + "cm": 2.54 / 6, + "in": 1 / 6, + "pt": 72 / 6, + "pc": 1, + "px": - 1 + }, + "px": { + "px": 1 + } + + }; + + function parseFloatWithUnits( string ) { + + var theUnit = "px"; + + if ( typeof string === 'string' || string instanceof String ) { + + for ( var i = 0, n = units.length; i < n; i ++ ) { + + var u = units[ i ]; + + if ( string.endsWith( u ) ) { + + theUnit = u; + string = string.substring( 0, string.length - u.length ); + break; + + } + + } + + } + + var scale = undefined; + + if ( theUnit === "px" && scope.defaultUnit !== "px" ) { + + // Conversion scale from pixels to inches, then to default units + + scale = unitConversion[ "in" ][ scope.defaultUnit ] / scope.defaultDPI; + + } else { + + scale = unitConversion[ theUnit ][ scope.defaultUnit ]; + + if ( scale < 0 ) { + + // Conversion scale to pixels + + scale = unitConversion[ theUnit ][ "in" ] * scope.defaultDPI; + + } + + } + + return scale * parseFloat( string ); + + } + + // Transforms + function getNodeTransform( node ) { if ( ! node.hasAttribute( 'transform' ) ) { @@ -1128,8 +1232,6 @@ THREE.SVGLoader.prototype = { // - console.log( 'THREE.SVGLoader' ); - var paths = []; var transformStack = []; @@ -1143,14 +1245,8 @@ THREE.SVGLoader.prototype = { var currentTransform = new THREE.Matrix3(); - console.time( 'THREE.SVGLoader: DOMParser' ); - var xml = new DOMParser().parseFromString( text, 'image/svg+xml' ); // application/xml - console.timeEnd( 'THREE.SVGLoader: DOMParser' ); - - console.time( 'THREE.SVGLoader: Parse' ); - parseNode( xml.documentElement, { fill: '#000', fillOpacity: 1, @@ -1164,15 +1260,11 @@ THREE.SVGLoader.prototype = { var data = { paths: paths, xml: xml.documentElement }; // console.log( paths ); - - - console.timeEnd( 'THREE.SVGLoader: Parse' ); - return data; } -}; +} ); THREE.SVGLoader.getStrokeStyle = function ( width, color, lineJoin, lineCap, miterLimit ) { @@ -1220,9 +1312,9 @@ THREE.SVGLoader.pointsToStroke = function ( points, style, arcDivisions, minDist } var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); return geometry; @@ -1619,23 +1711,31 @@ THREE.SVGLoader.pointsToStrokeWithBuffers = function () { if ( joinIsOnLeftSide ) { - lastInner.toArray( vertices, 0 * 3 ); - lastInner.toArray( vertices, 3 * 3 ); + if ( isMiter || initialJoinIsOnLeftSide ) { + + lastInner.toArray( vertices, 0 * 3 ); + lastInner.toArray( vertices, 3 * 3 ); - if ( isMiter ) { + if ( isMiter ) { - lastOuter.toArray( vertices, 1 * 3 ); + lastOuter.toArray( vertices, 1 * 3 ); + + } } } else { - lastInner.toArray( vertices, 1 * 3 ); - lastInner.toArray( vertices, 3 * 3 ); + if ( isMiter || ! initialJoinIsOnLeftSide ) { - if ( isMiter ) { + lastInner.toArray( vertices, 1 * 3 ); + lastInner.toArray( vertices, 3 * 3 ); - lastOuter.toArray( vertices, 0 * 3 ); + if ( isMiter ) { + + lastOuter.toArray( vertices, 0 * 3 ); + + } } diff --git a/examples/js/loaders/TDSLoader.js b/examples/js/loaders/TDSLoader.js index b0306c781ff886..26fcdd88b632d6 100644 --- a/examples/js/loaders/TDSLoader.js +++ b/examples/js/loaders/TDSLoader.js @@ -11,7 +11,8 @@ THREE.TDSLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + this.debug = false; this.group = null; @@ -22,12 +23,10 @@ THREE.TDSLoader = function ( manager ) { }; -THREE.TDSLoader.prototype = { +THREE.TDSLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.TDSLoader, - crossOrigin: 'anonymous', - /** * Load 3ds file from url. * @@ -41,7 +40,7 @@ THREE.TDSLoader.prototype = { var scope = this; - var path = this.path !== undefined ? this.path : THREE.LoaderUtils.extractUrlBase( url ); + var path = ( scope.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; var loader = new THREE.FileLoader( this.manager ); loader.setPath( this.path ); @@ -273,6 +272,13 @@ THREE.TDSLoader.prototype = { material.shininess = shininess; this.debugMessage( ' Shininess : ' + shininess ); + } else if ( next === MAT_TRANSPARENCY ) { + + var opacity = this.readWord( data ); + material.opacity = opacity * 0.01; + this.debugMessage( ' Opacity : ' + opacity ); + material.transparent = opacity < 100 ? true : false; + } else if ( next === MAT_TEXMAP ) { this.debugMessage( ' ColorMap' ); @@ -352,7 +358,7 @@ THREE.TDSLoader.prototype = { } - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); } else if ( next === FACE_ARRAY ) { @@ -376,7 +382,7 @@ THREE.TDSLoader.prototype = { } - geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); } else if ( next === MESH_MATRIX ) { @@ -420,7 +426,7 @@ THREE.TDSLoader.prototype = { var inverse = new THREE.Matrix4(); inverse.getInverse( matrix, true ); - geometry.applyMatrix( inverse ); + geometry.applyMatrix4( inverse ); matrix.decompose( mesh.position, mesh.quaternion, mesh.scale ); @@ -845,52 +851,6 @@ THREE.TDSLoader.prototype = { }, - /** - * Set path to adjust the path to the original 3ds file. - * - * @method setPath - * @param {String} path Path to file. - * @return Self for chaining. - */ - setPath: function ( path ) { - - this.path = path; - - return this; - - }, - - /** - * Set resource path used to determine the path to attached resources like textures. - * - * @method setResourcePath - * @param {String} resourcePath Path to resources. - * @return Self for chaining. - */ - setResourcePath: function ( resourcePath ) { - - this.resourcePath = resourcePath; - - return this; - - }, - - /** - * Set crossOrigin value to configure CORS settings - * for the image loading process. - * - * @method setCrossOrigin - * @param {String} crossOrigin crossOrigin string. - * @return Self for chaining. - */ - setCrossOrigin: function ( crossOrigin ) { - - this.crossOrigin = crossOrigin; - - return this; - - }, - /** * Print debug message to the console. * @@ -908,7 +868,8 @@ THREE.TDSLoader.prototype = { } } -}; + +} ); // var NULL_CHUNK = 0x0000; var M3DMAGIC = 0x4D4D; @@ -958,7 +919,7 @@ var MAT_DIFFUSE = 0xA020; var MAT_SPECULAR = 0xA030; var MAT_SHININESS = 0xA040; // var MAT_SHIN2PCT = 0xA041; -// var MAT_TRANSPARENCY = 0xA050; +var MAT_TRANSPARENCY = 0xA050; // var MAT_XPFALL = 0xA052; // var MAT_USE_XPFALL = 0xA240; // var MAT_REFBLUR = 0xA053; diff --git a/examples/js/loaders/TGALoader.js b/examples/js/loaders/TGALoader.js index b84c95941fc5f8..368d9723edb120 100644 --- a/examples/js/loaders/TGALoader.js +++ b/examples/js/loaders/TGALoader.js @@ -6,11 +6,11 @@ THREE.TGALoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -THREE.TGALoader.prototype = { +THREE.TGALoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.TGALoader, @@ -60,7 +60,7 @@ THREE.TGALoader.prototype = { } break; - // check colormap type + // check colormap type case TGA_TYPE_RGB: case TGA_TYPE_GREY: @@ -73,12 +73,12 @@ THREE.TGALoader.prototype = { } break; - // What the need of a file without data ? + // What the need of a file without data ? case TGA_TYPE_NO_DATA: console.error( 'THREE.TGALoader: No data.' ); - // Invalid type ? + // Invalid type ? default: console.error( 'THREE.TGALoader: Invalid type "%s".', header.image_type ); @@ -471,7 +471,7 @@ THREE.TGALoader.prototype = { flags: content[ offset ++ ] }; - // check tga if it is valid format + // check tga if it is valid format tgaCheckHeader( header ); @@ -538,13 +538,6 @@ THREE.TGALoader.prototype = { return useOffscreen ? canvas.transferToImageBitmap() : canvas; - }, - - setPath: function ( value ) { - - this.path = value; - return this; - } -}; +} ); diff --git a/examples/js/loaders/TTFLoader.js b/examples/js/loaders/TTFLoader.js index c15c047acae612..b7842e2af88910 100644 --- a/examples/js/loaders/TTFLoader.js +++ b/examples/js/loaders/TTFLoader.js @@ -10,12 +10,14 @@ THREE.TTFLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + this.reversed = false; }; -THREE.TTFLoader.prototype = { + +THREE.TTFLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: THREE.TTFLoader, @@ -34,13 +36,6 @@ THREE.TTFLoader.prototype = { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( arraybuffer ) { function convert( font, reversed ) { @@ -49,7 +44,7 @@ THREE.TTFLoader.prototype = { var glyphs = {}; var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 ); - + var glyphIndexMap = font.encoding.cmap.glyphIndexMap; var unicodes = Object.keys( glyphIndexMap ); @@ -202,4 +197,4 @@ THREE.TTFLoader.prototype = { } -}; +} ); diff --git a/examples/js/loaders/VRMLLoader.js b/examples/js/loaders/VRMLLoader.js index 4c97474c310dd7..50198441943841 100644 --- a/examples/js/loaders/VRMLLoader.js +++ b/examples/js/loaders/VRMLLoader.js @@ -18,21 +18,19 @@ THREE.VRMLLoader = ( function () { function VRMLLoader( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); } - VRMLLoader.prototype = { + VRMLLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: VRMLLoader, - crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { var scope = this; - var path = ( scope.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; + var path = ( scope.path === '' ) ? THREE.LoaderUtils.extractUrlBase( url ) : scope.path; var loader = new THREE.FileLoader( this.manager ); loader.setPath( scope.path ); @@ -44,27 +42,6 @@ THREE.VRMLLoader = ( function () { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - parse: function ( data, path ) { var nodeMap = {}; @@ -169,6 +146,7 @@ THREE.VRMLLoader = ( function () { // var StringLiteral = createToken( { name: "StringLiteral", pattern: /"(:?[^\\"\n\r]+|\\(:?[bfnrtv"\\/]|u[0-9a-fA-F]{4}))*"/ } ); + var HexLiteral = createToken( { name: 'HexLiteral', pattern: /0[xX][0-9a-fA-F]+/ } ); var NumberLiteral = createToken( { name: 'NumberLiteral', pattern: /[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/ } ); var TrueLiteral = createToken( { name: 'TrueLiteral', pattern: /TRUE/ } ); var FalseLiteral = createToken( { name: 'FalseLiteral', pattern: /FALSE/ } ); @@ -207,6 +185,7 @@ THREE.VRMLLoader = ( function () { Identifier, RouteIdentifier, StringLiteral, + HexLiteral, NumberLiteral, LSquare, RSquare, @@ -448,6 +427,20 @@ THREE.VRMLLoader = ( function () { } + if ( ctx.HexLiteral ) { + + field.type = 'hex'; + + for ( var i = 0, l = ctx.HexLiteral.length; i < l; i ++ ) { + + var hexLiteral = ctx.HexLiteral[ i ]; + + field.values.push( hexLiteral.image ); + + } + + } + if ( ctx.TrueLiteral ) { field.type = 'boolean'; @@ -601,7 +594,7 @@ THREE.VRMLLoader = ( function () { break; case 'Appearance': - build = buildApperanceNode( node ); + build = buildAppearanceNode( node ); break; case 'Material': @@ -612,6 +605,10 @@ THREE.VRMLLoader = ( function () { build = buildImageTextureNode( node ); break; + case 'PixelTexture': + build = buildPixelTextureNode( node ); + break; + case 'TextureTransform': build = buildTextureTransformNode( node ); break; @@ -681,7 +678,6 @@ THREE.VRMLLoader = ( function () { case 'FontStyle': case 'MovieTexture': - case 'PixelTexture': case 'ColorInterpolator': case 'CoordinateInterpolator': @@ -833,19 +829,19 @@ THREE.VRMLLoader = ( function () { } + var radius = 10000; + // sky if ( skyColor ) { - var radius = 10000; - var skyGeometry = new THREE.SphereBufferGeometry( radius, 32, 16 ); var skyMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, depthWrite: false, depthTest: false } ); if ( skyColor.length > 3 ) { paintFaces( skyGeometry, radius, skyAngle, toColorArray( skyColor ), true ); - skyMaterial.vertexColors = THREE.VertexColors; + skyMaterial.vertexColors = true; } else { @@ -865,7 +861,7 @@ THREE.VRMLLoader = ( function () { if ( groundColor.length > 0 ) { var groundGeometry = new THREE.SphereBufferGeometry( radius, 32, 16, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI ); - var groundMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, vertexColors: THREE.VertexColors, depthWrite: false, depthTest: false } ); + var groundMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, vertexColors: true, depthWrite: false, depthTest: false } ); paintFaces( groundGeometry, radius, groundAngle, toColorArray( groundColor ), false ); @@ -939,7 +935,7 @@ THREE.VRMLLoader = ( function () { if ( geometry.attributes.color !== undefined ) { - pointsMaterial.vertexColors = THREE.VertexColors; + pointsMaterial.vertexColors = true; } else { @@ -961,7 +957,7 @@ THREE.VRMLLoader = ( function () { if ( geometry.attributes.color !== undefined ) { - lineMaterial.vertexColors = THREE.VertexColors; + lineMaterial.vertexColors = true; } else { @@ -991,7 +987,7 @@ THREE.VRMLLoader = ( function () { if ( geometry.attributes.color !== undefined ) { - material.vertexColors = THREE.VertexColors; + material.vertexColors = true; } @@ -1013,7 +1009,7 @@ THREE.VRMLLoader = ( function () { } - function buildApperanceNode( node ) { + function buildAppearanceNode( node ) { var material = new THREE.MeshPhongMaterial(); var transformData; @@ -1053,13 +1049,13 @@ THREE.VRMLLoader = ( function () { var textureNode = fieldValues[ 0 ]; if ( textureNode !== null ) { - if ( textureNode.name === 'ImageTexture' ) { + if ( textureNode.name === 'ImageTexture' || textureNode.name === 'PixelTexture' ) { material.map = getNode( textureNode ); } else { - // MovieTexture and PixelTexture not supported yet + // MovieTexture not supported yet } @@ -1084,12 +1080,45 @@ THREE.VRMLLoader = ( function () { // only apply texture transform data if a texture was defined - if ( material.map && transformData ) { + if ( material.map ) { + + // respect VRML lighting model + + if ( material.map.__type ) { + + switch ( material.map.__type ) { + + case TEXTURE_TYPE.INTENSITY_ALPHA: + material.opacity = 1; // ignore transparency + break; + + case TEXTURE_TYPE.RGB: + material.color.set( 0xffffff ); // ignore material color + break; - material.map.center.copy( transformData.center ); - material.map.rotation = transformData.rotation; - material.map.repeat.copy( transformData.scale ); - material.map.offset.copy( transformData.translation ); + case TEXTURE_TYPE.RGBA: + material.color.set( 0xffffff ); // ignore material color + material.opacity = 1; // ignore transparency + break; + + default: + + } + + delete material.map.__type; + + } + + // apply texture transform + + if ( transformData ) { + + material.map.center.copy( transformData.center ); + material.map.rotation = transformData.rotation; + material.map.repeat.copy( transformData.scale ); + material.map.offset.copy( transformData.translation ); + + } } @@ -1147,6 +1176,163 @@ THREE.VRMLLoader = ( function () { } + function parseHexColor( hex, textureType, color ) { + + switch ( textureType ) { + + case TEXTURE_TYPE.INTENSITY: + // Intensity texture: A one-component image specifies one-byte hexadecimal or integer values representing the intensity of the image + var value = parseInt( hex ); + color.r = value; + color.g = value; + color.b = value; + break; + + case TEXTURE_TYPE.INTENSITY_ALPHA: + // Intensity+Alpha texture: A two-component image specifies the intensity in the first (high) byte and the alpha opacity in the second (low) byte. + var value = parseInt( "0x" + hex.substring( 2, 4 ) ); + color.r = value; + color.g = value; + color.b = value; + color.a = parseInt( "0x" + hex.substring( 4, 6 ) ); + break; + + case TEXTURE_TYPE.RGB: + // RGB texture: Pixels in a three-component image specify the red component in the first (high) byte, followed by the green and blue components + color.r = parseInt( "0x" + hex.substring( 2, 4 ) ); + color.g = parseInt( "0x" + hex.substring( 4, 6 ) ); + color.b = parseInt( "0x" + hex.substring( 6, 8 ) ); + break; + + case TEXTURE_TYPE.RGBA: + // RGBA texture: Four-component images specify the alpha opacity byte after red/green/blue + color.r = parseInt( "0x" + hex.substring( 2, 4 ) ); + color.g = parseInt( "0x" + hex.substring( 4, 6 ) ); + color.b = parseInt( "0x" + hex.substring( 6, 8 ) ); + color.a = parseInt( "0x" + hex.substring( 8, 10 ) ); + break; + + default: + + } + + } + + function getTextureType( num_components ) { + + var type; + + switch ( num_components ) { + + case 1: + type = TEXTURE_TYPE.INTENSITY; + break; + + case 2: + type = TEXTURE_TYPE.INTENSITY_ALPHA; + break; + + case 3: + type = TEXTURE_TYPE.RGB; + break; + + case 4: + type = TEXTURE_TYPE.RGBA; + break; + + default: + + } + + return type; + + } + + function buildPixelTextureNode( node ) { + + var texture; + var wrapS = THREE.RepeatWrapping; + var wrapT = THREE.RepeatWrapping; + + var fields = node.fields; + + for ( var i = 0, l = fields.length; i < l; i ++ ) { + + var field = fields[ i ]; + var fieldName = field.name; + var fieldValues = field.values; + + switch ( fieldName ) { + + case 'image': + var width = fieldValues[ 0 ]; + var height = fieldValues[ 1 ]; + var num_components = fieldValues[ 2 ]; + + var useAlpha = ( num_components === 2 || num_components === 4 ); + var textureType = getTextureType( num_components ); + + var size = ( ( useAlpha === true ) ? 4 : 3 ) * ( width * height ); + var data = new Uint8Array( size ); + + var color = { r: 0, g: 0, b: 0, a: 0 }; + + for ( var j = 3, k = 0, jl = fieldValues.length; j < jl; j ++, k ++ ) { + + parseHexColor( fieldValues[ j ], textureType, color ); + + if ( useAlpha === true ) { + + var stride = k * 4; + + data[ stride + 0 ] = color.r; + data[ stride + 1 ] = color.g; + data[ stride + 2 ] = color.b; + data[ stride + 3 ] = color.a; + + } else { + + var stride = k * 3; + + data[ stride + 0 ] = color.r; + data[ stride + 1 ] = color.g; + data[ stride + 2 ] = color.b; + + } + + } + + texture = new THREE.DataTexture( data, width, height, ( useAlpha === true ) ? THREE.RGBAFormat : THREE.RGBFormat ); + texture.__type = textureType; // needed for material modifications + break; + + case 'repeatS': + if ( fieldValues[ 0 ] === false ) wrapS = THREE.ClampToEdgeWrapping; + break; + + case 'repeatT': + if ( fieldValues[ 0 ] === false ) wrapT = THREE.ClampToEdgeWrapping; + break; + + default: + console.warn( 'THREE.VRMLLoader: Unknown field:', fieldName ); + break; + + } + + } + + if ( texture ) { + + texture.wrapS = wrapS; + texture.wrapT = wrapT; + + } + + return texture; + + } + function buildImageTextureNode( node ) { var texture; @@ -1251,7 +1437,7 @@ THREE.VRMLLoader = ( function () { function buildIndexedFaceSetNode( node ) { var color, coord, normal, texCoord; - var ccw = true, solid = true, creaseAngle; + var ccw = true, solid = true, creaseAngle = 0; var colorIndex, coordIndex, normalIndex, texCoordIndex; var colorPerVertex = true, normalPerVertex = true; @@ -1488,13 +1674,13 @@ THREE.VRMLLoader = ( function () { var geometry = new THREE.BufferGeometry(); positionAttribute = toNonIndexedAttribute( triangulatedCoordIndex, new THREE.Float32BufferAttribute( coord, 3 ) ); - geometry.addAttribute( 'position', positionAttribute ); - geometry.addAttribute( 'normal', normalAttribute ); + geometry.setAttribute( 'position', positionAttribute ); + geometry.setAttribute( 'normal', normalAttribute ); // optional attributes - if ( colorAttribute ) geometry.addAttribute( 'color', colorAttribute ); - if ( uvAttribute ) geometry.addAttribute( 'uv', uvAttribute ); + if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute ); + if ( uvAttribute ) geometry.setAttribute( 'uv', uvAttribute ); // "solid" influences the material so let's store it for later use @@ -1615,9 +1801,9 @@ THREE.VRMLLoader = ( function () { var geometry = new THREE.BufferGeometry(); var positionAttribute = toNonIndexedAttribute( expandedLineIndex, new THREE.Float32BufferAttribute( coord, 3 ) ); - geometry.addAttribute( 'position', positionAttribute ); + geometry.setAttribute( 'position', positionAttribute ); - if ( colorAttribute ) geometry.addAttribute( 'color', colorAttribute ); + if ( colorAttribute ) geometry.setAttribute( 'color', colorAttribute ); geometry._type = 'line'; @@ -1671,8 +1857,8 @@ THREE.VRMLLoader = ( function () { var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( coord, 3 ) ); - if ( color ) geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( coord, 3 ) ); + if ( color ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( color, 3 ) ); geometry._type = 'points'; @@ -1849,7 +2035,7 @@ THREE.VRMLLoader = ( function () { // materials can be influenced by the geometry (e.g. vertex normals). cloning is necessary to avoid // any side effects - return ( build.isObject3D || build.isMaterial ) ? build.clone() : build; + return ( build.isObject3D || build.isMaterial ) ? build.clone() : build; } @@ -2184,13 +2370,21 @@ THREE.VRMLLoader = ( function () { function weightedNormal( normals, vector, creaseAngle ) { - var normal = vector.clone(); + var normal = new THREE.Vector3(); + + if ( creaseAngle === 0 ) { + + normal.copy( vector ); - for ( var i = 0, l = normals.length; i < l; i ++ ) { + } else { + + for ( var i = 0, l = normals.length; i < l; i ++ ) { + + if ( normals[ i ].angleTo( vector ) < creaseAngle ) { - if ( normals[ i ].angleTo( vector ) < creaseAngle ) { + normal.add( normals[ i ] ); - normal.add( normals[ i ] ); + } } @@ -2238,83 +2432,69 @@ THREE.VRMLLoader = ( function () { */ function paintFaces( geometry, radius, angles, colors, topDown ) { - var direction = ( topDown === true ) ? 1 : - 1; + // compute threshold values - var coord = [], A = {}, B = {}, applyColor = false; + var thresholds = []; + var startAngle = ( topDown === true ) ? 0 : Math.PI; - for ( var k = 0; k < angles.length; k ++ ) { + for ( var i = 0, l = colors.length; i < l; i ++ ) { - // push the vector at which the color changes + var angle = ( i === 0 ) ? 0 : angles[ i - 1 ]; + angle = ( topDown === true ) ? angle : ( startAngle - angle ); - var vec = { - x: direction * ( Math.cos( angles[ k ] ) * radius ), - y: direction * ( Math.sin( angles[ k ] ) * radius ) - }; + var point = new THREE.Vector3(); + point.setFromSphericalCoords( radius, angle, 0 ); - coord.push( vec ); + thresholds.push( point ); } - var index = geometry.index; + // generate vertex colors + + var indices = geometry.index; var positionAttribute = geometry.attributes.position; var colorAttribute = new THREE.BufferAttribute( new Float32Array( geometry.attributes.position.count * 3 ), 3 ); var position = new THREE.Vector3(); var color = new THREE.Color(); - for ( var i = 0; i < index.count; i ++ ) { + for ( var i = 0; i < indices.count; i ++ ) { - var vertexIndex = index.getX( i ); + var index = indices.getX( i ); + position.fromBufferAttribute( positionAttribute, index ); - position.fromBufferAttribute( positionAttribute, vertexIndex ); + var thresholdIndexA, thresholdIndexB; + var t = 1; - for ( var j = 0; j < colors.length; j ++ ) { + for ( var j = 1; j < thresholds.length; j ++ ) { - // linear interpolation between aColor and bColor, calculate proportion - // A is previous point (angle) + thresholdIndexA = j - 1; + thresholdIndexB = j; - if ( j === 0 ) { + var thresholdA = thresholds[ thresholdIndexA ]; + var thresholdB = thresholds[ thresholdIndexB ]; - A.x = 0; - A.y = ( topDown === true ) ? radius : - 1 * radius; - - } else { - - A.x = coord[ j - 1 ].x; - A.y = coord[ j - 1 ].y; - - } + if ( topDown === true ) { - // B is current point (angle) + // interpolation for sky color - B = coord[ j ]; + if ( position.y <= thresholdA.y && position.y > thresholdB.y ) { - if ( B !== undefined ) { + t = Math.abs( thresholdA.y - position.y ) / Math.abs( thresholdA.y - thresholdB.y ); - // p has to be between the points A and B which we interpolate + break; - applyColor = ( topDown === true ) ? ( position.y <= A.y && position.y > B.y ) : ( position.y >= A.y && position.y < B.y ); - - if ( applyColor === true ) { - - var aColor = colors[ j ]; - var bColor = colors[ j + 1 ]; - - // below is simple linear interpolation + } - var t = Math.abs( position.y - A.y ) / ( A.y - B.y ); + } else { - // to make it faster, you can only calculate this if the y coord changes, the color is the same for points with the same y + // interpolation for ground color - color.copy( aColor ).lerp( bColor, t ); + if ( position.y >= thresholdA.y && position.y < thresholdB.y ) { - colorAttribute.setXYZ( vertexIndex, color.r, color.g, color.b ); + t = Math.abs( thresholdA.y - position.y ) / Math.abs( thresholdA.y - thresholdB.y ); - } else { - - var colorIndex = ( topDown === true ) ? colors.length - 1 : 0; - var c = colors[ colorIndex ]; - colorAttribute.setXYZ( vertexIndex, c.r, c.g, c.b ); + break; } @@ -2322,9 +2502,16 @@ THREE.VRMLLoader = ( function () { } + var colorA = colors[ thresholdIndexA ]; + var colorB = colors[ thresholdIndexB ]; + + color.copy( colorA ).lerp( colorB, t ); + + colorAttribute.setXYZ( index, color.r, color.g, color.b ); + } - geometry.addAttribute( 'color', colorAttribute ); + geometry.setAttribute( 'color', colorAttribute ); } @@ -2353,7 +2540,7 @@ THREE.VRMLLoader = ( function () { } - }; + } ); function VRMLLexer( tokens ) { @@ -2397,6 +2584,7 @@ THREE.VRMLLoader = ( function () { var Identifier = tokenVocabulary[ 'Identifier' ]; var RouteIdentifier = tokenVocabulary[ 'RouteIdentifier' ]; var StringLiteral = tokenVocabulary[ 'StringLiteral' ]; + var HexLiteral = tokenVocabulary[ 'HexLiteral' ]; var NumberLiteral = tokenVocabulary[ 'NumberLiteral' ]; var TrueLiteral = tokenVocabulary[ 'TrueLiteral' ]; var FalseLiteral = tokenVocabulary[ 'FalseLiteral' ]; @@ -2500,6 +2688,11 @@ THREE.VRMLLoader = ( function () { $.CONSUME( StringLiteral ); + } }, + { ALT: function () { + + $.CONSUME( HexLiteral ); + } }, { ALT: function () { @@ -2548,6 +2741,11 @@ THREE.VRMLLoader = ( function () { $.CONSUME( StringLiteral ); + } }, + { ALT: function () { + + $.CONSUME( HexLiteral ); + } }, { ALT: function () { @@ -2591,6 +2789,13 @@ THREE.VRMLLoader = ( function () { } + var TEXTURE_TYPE = { + INTENSITY: 1, + INTENSITY_ALPHA: 2, + RGB: 3, + RGBA: 4 + }; + return VRMLLoader; } )(); diff --git a/examples/js/loaders/VRMLoader.js b/examples/js/loaders/VRMLoader.js index 024f6db51e6189..791cfb68a7a1ad 100644 --- a/examples/js/loaders/VRMLoader.js +++ b/examples/js/loaders/VRMLoader.js @@ -17,17 +17,16 @@ THREE.VRMLoader = ( function () { } - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); + this.gltfLoader = new THREE.GLTFLoader( this.manager ); } - VRMLoader.prototype = { + VRMLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { constructor: VRMLoader, - crossOrigin: 'anonymous', - load: function ( url, onLoad, onProgress, onError ) { var scope = this; @@ -40,27 +39,6 @@ THREE.VRMLoader = ( function () { }, - setCrossOrigin: function ( value ) { - - this.glTFLoader.setCrossOrigin( value ); - return this; - - }, - - setPath: function ( value ) { - - this.glTFLoader.setPath( value ); - return this; - - }, - - setResourcePath: function ( value ) { - - this.glTFLoader.setResourcePath( value ); - return this; - - }, - setDRACOLoader: function ( dracoLoader ) { this.glTFLoader.setDRACOLoader( dracoLoader ); @@ -80,7 +58,7 @@ THREE.VRMLoader = ( function () { } - }; + } ); return VRMLoader; diff --git a/examples/js/loaders/VTKLoader.js b/examples/js/loaders/VTKLoader.js index f7cd93a6ba9735..8757dd711f43cd 100644 --- a/examples/js/loaders/VTKLoader.js +++ b/examples/js/loaders/VTKLoader.js @@ -11,11 +11,13 @@ THREE.VTKLoader = function ( manager ) { - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + THREE.Loader.call( this, manager ); }; -Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { +THREE.VTKLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype ), { + + constructor: THREE.VTKLoader, load: function ( url, onLoad, onProgress, onError ) { @@ -32,13 +34,6 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { }, - setPath: function ( value ) { - - this.path = value; - return this; - - }, - parse: function ( data ) { function parseASCII( data ) { @@ -57,6 +52,9 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { var result; + // pattern for detecting the end of a number sequence + var patWord = /^[^\d.\s-]+/; + // pattern for reading vertices, 3 floats or integers var pat3Floats = /(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)\s+(\-?\d+\.?[\d\-\+e]*)/g; @@ -97,7 +95,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { for ( var i in lines ) { - var line = lines[ i ]; + var line = lines[ i ].trim(); if ( line.indexOf( 'DATASET' ) === 0 ) { @@ -110,6 +108,8 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { // get the vertices while ( ( result = pat3Floats.exec( line ) ) !== null ) { + if ( patWord.exec( line ) !== null ) break; + var x = parseFloat( result[ 1 ] ); var y = parseFloat( result[ 2 ] ); var z = parseFloat( result[ 3 ] ); @@ -188,6 +188,8 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { while ( ( result = pat3Floats.exec( line ) ) !== null ) { + if ( patWord.exec( line ) !== null ) break; + var r = parseFloat( result[ 1 ] ); var g = parseFloat( result[ 2 ] ); var b = parseFloat( result[ 3 ] ); @@ -201,6 +203,8 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { while ( ( result = pat3Floats.exec( line ) ) !== null ) { + if ( patWord.exec( line ) !== null ) break; + var nx = parseFloat( result[ 1 ] ); var ny = parseFloat( result[ 2 ] ); var nz = parseFloat( result[ 3 ] ); @@ -266,11 +270,11 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { var geometry = new THREE.BufferGeometry(); geometry.setIndex( indices ); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); if ( normals.length === positions.length ) { - geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); } @@ -280,7 +284,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { if ( colors.length === positions.length ) { - geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); + geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); } @@ -307,7 +311,7 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { } - geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( newColors, 3 ) ); + geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( newColors, 3 ) ); } @@ -513,11 +517,11 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { var geometry = new THREE.BufferGeometry(); geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( points, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( points, 3 ) ); if ( normals.length === points.length ) { - geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); } @@ -1117,11 +1121,11 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, { var geometry = new THREE.BufferGeometry(); geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( points, 3 ) ); + geometry.setAttribute( 'position', new THREE.BufferAttribute( points, 3 ) ); if ( normals.length === points.length ) { - geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); + geometry.setAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); } diff --git a/examples/js/loaders/XLoader.js b/examples/js/loaders/XLoader.js index 8f7157372da45a..4def9b25d813a6 100644 --- a/examples/js/loaders/XLoader.js +++ b/examples/js/loaders/XLoader.js @@ -201,10 +201,11 @@ THREE.XLoader = ( function () { function XLoader( manager ) { + THREE.Loader.call( this, manager ); + classCallCheck( this, XLoader ); this.debug = false; - this.manager = manager !== undefined ? manager : THREE.DefaultLoadingManager; this.texloader = new THREE.TextureLoader( this.manager ); this.url = ""; this._putMatLength = 0; @@ -228,9 +229,6 @@ THREE.XLoader = ( function () { } createClass( XLoader, [ { - key: 'crossOrigin', - value: 'anonymous' - }, { key: '_setArgOption', value: function _setArgOption( _arg ) { @@ -278,30 +276,6 @@ THREE.XLoader = ( function () { }, onProgress, onError ); - } - }, { - key: 'setCrossOrigin', - value: function setCrossOrigin( value ) { - - this.crossOrigin = value; - return this; - - } - }, { - key: 'setPath', - value: function setPath( value ) { - - this.path = value; - return this; - - } - }, { - key: 'setResourcePath', - value: function setResourcePath( value ) { - - this.resourcePath = value; - return this; - } }, { key: '_readLine', @@ -482,11 +456,11 @@ THREE.XLoader = ( function () { var path; - if ( this.resourcePath !== undefined ) { + if ( this.resourcePath !== '' ) { path = this.resourcePath; - } else if ( this.path !== undefined ) { + } else if ( this.path !== '' ) { path = this.path; @@ -825,7 +799,7 @@ THREE.XLoader = ( function () { } var b = new THREE.Bone(); b.name = this._currentFrame.name; - b.applyMatrix( this._currentFrame.FrameTransformMatrix ); + b.applyMatrix4( this._currentFrame.FrameTransformMatrix ); b.matrixWorld = b.matrix; b.FrameTransformMatrix = this._currentFrame.FrameTransformMatrix; this._currentFrame.putBone = b; @@ -998,11 +972,11 @@ THREE.XLoader = ( function () { // - bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); - bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - bufferGeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); - bufferGeometry.addAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); - bufferGeometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); + bufferGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); + bufferGeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + bufferGeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) ); + bufferGeometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) ); + bufferGeometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) ); this._computeGroups( bufferGeometry, data.materialIndices ); @@ -1288,7 +1262,7 @@ THREE.XLoader = ( function () { putting = true; var b = new THREE.Bone(); b.name = this.HieStack[ frame ].name; - b.applyMatrix( this.HieStack[ frame ].FrameTransformMatrix ); + b.applyMatrix4( this.HieStack[ frame ].FrameTransformMatrix ); b.matrixWorld = b.matrix; b.FrameTransformMatrix = this.HieStack[ frame ].FrameTransformMatrix; b.pos = new THREE.Vector3().setFromMatrixPosition( b.FrameTransformMatrix ).toArray(); @@ -1427,7 +1401,7 @@ THREE.XLoader = ( function () { } } - mesh.applyMatrix( worldBaseMx ); + mesh.applyMatrix4( worldBaseMx ); } this.Meshes.push( mesh ); diff --git a/examples/js/loaders/deprecated/LegacyGLTFLoader.js b/examples/js/loaders/deprecated/LegacyGLTFLoader.js deleted file mode 100644 index 7d8cb23b16e603..00000000000000 --- a/examples/js/loaders/deprecated/LegacyGLTFLoader.js +++ /dev/null @@ -1,2241 +0,0 @@ -/** - * @author Rich Tibbett / https://github.com/richtr - * @author mrdoob / http://mrdoob.com/ - * @author Tony Parisi / http://www.tonyparisi.com/ - * @author Takahiro / https://github.com/takahirox - */ - -THREE.LegacyGLTFLoader = ( function () { - - function LegacyGLTFLoader( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - - } - - LegacyGLTFLoader.prototype = { - - constructor: LegacyGLTFLoader, - - crossOrigin: 'anonymous', - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var resourcePath; - - if ( this.resourcePath !== undefined ) { - - resourcePath = this.resourcePath; - - } else if ( this.path !== undefined ) { - - resourcePath = this.path; - - } else { - - resourcePath = THREE.LoaderUtils.extractUrlBase( url ); - - } - - var loader = new THREE.FileLoader( scope.manager ); - - loader.setPath( this.path ); - loader.setResponseType( 'arraybuffer' ); - - loader.load( url, function ( data ) { - - scope.parse( data, resourcePath, onLoad ); - - }, onProgress, onError ); - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - setPath: function ( value ) { - - this.path = value; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - parse: function ( data, path, callback ) { - - var content; - var extensions = {}; - - var magic = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) ); - - if ( magic === BINARY_EXTENSION_HEADER_DEFAULTS.magic ) { - - extensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data ); - content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content; - - } else { - - content = THREE.LoaderUtils.decodeText( new Uint8Array( data ) ); - - } - - var json = JSON.parse( content ); - - if ( json.extensionsUsed && json.extensionsUsed.indexOf( EXTENSIONS.KHR_MATERIALS_COMMON ) >= 0 ) { - - extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] = new GLTFMaterialsCommonExtension( json ); - - } - - var parser = new GLTFParser( json, extensions, { - - crossOrigin: this.crossOrigin, - manager: this.manager, - path: path || this.resourcePath || '' - - } ); - - parser.parse( function ( scene, scenes, cameras, animations ) { - - var glTF = { - "scene": scene, - "scenes": scenes, - "cameras": cameras, - "animations": animations - }; - - callback( glTF ); - - } ); - - } - - }; - - /* GLTFREGISTRY */ - - function GLTFRegistry() { - - var objects = {}; - - return { - - get: function ( key ) { - - return objects[ key ]; - - }, - - add: function ( key, object ) { - - objects[ key ] = object; - - }, - - remove: function ( key ) { - - delete objects[ key ]; - - }, - - removeAll: function () { - - objects = {}; - - }, - - update: function ( scene, camera ) { - - for ( var name in objects ) { - - var object = objects[ name ]; - - if ( object.update ) { - - object.update( scene, camera ); - - } - - } - - } - - }; - - } - - /* GLTFSHADERS */ - - LegacyGLTFLoader.Shaders = { - - update: function () { - - console.warn( 'THREE.LegacyGLTFLoader.Shaders has been deprecated, and now updates automatically.' ); - - } - - }; - - /* GLTFSHADER */ - - function GLTFShader( targetNode, allNodes ) { - - var boundUniforms = {}; - - // bind each uniform to its source node - - var uniforms = targetNode.material.uniforms; - - for ( var uniformId in uniforms ) { - - var uniform = uniforms[ uniformId ]; - - if ( uniform.semantic ) { - - var sourceNodeRef = uniform.node; - - var sourceNode = targetNode; - - if ( sourceNodeRef ) { - - sourceNode = allNodes[ sourceNodeRef ]; - - } - - boundUniforms[ uniformId ] = { - semantic: uniform.semantic, - sourceNode: sourceNode, - targetNode: targetNode, - uniform: uniform - }; - - } - - } - - this.boundUniforms = boundUniforms; - this._m4 = new THREE.Matrix4(); - - } - - // Update - update all the uniform values - GLTFShader.prototype.update = function ( scene, camera ) { - - var boundUniforms = this.boundUniforms; - - for ( var name in boundUniforms ) { - - var boundUniform = boundUniforms[ name ]; - - switch ( boundUniform.semantic ) { - - case "MODELVIEW": - - var m4 = boundUniform.uniform.value; - m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld ); - break; - - case "MODELVIEWINVERSETRANSPOSE": - - var m3 = boundUniform.uniform.value; - this._m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld ); - m3.getNormalMatrix( this._m4 ); - break; - - case "PROJECTION": - - var m4 = boundUniform.uniform.value; - m4.copy( camera.projectionMatrix ); - break; - - case "JOINTMATRIX": - - var m4v = boundUniform.uniform.value; - - for ( var mi = 0; mi < m4v.length; mi ++ ) { - - // So it goes like this: - // SkinnedMesh world matrix is already baked into MODELVIEW; - // transform joints to local space, - // then transform using joint's inverse - m4v[ mi ] - .getInverse( boundUniform.sourceNode.matrixWorld ) - .multiply( boundUniform.targetNode.skeleton.bones[ mi ].matrixWorld ) - .multiply( boundUniform.targetNode.skeleton.boneInverses[ mi ] ) - .multiply( boundUniform.targetNode.bindMatrix ); - - } - - break; - - default : - - console.warn( "Unhandled shader semantic: " + boundUniform.semantic ); - break; - - } - - } - - }; - - - /* ANIMATION */ - - LegacyGLTFLoader.Animations = { - - update: function () { - - console.warn( 'THREE.LegacyGLTFLoader.Animation has been deprecated. Use THREE.AnimationMixer instead.' ); - - } - - }; - - /*********************************/ - /********** EXTENSIONS ***********/ - /*********************************/ - - var EXTENSIONS = { - KHR_BINARY_GLTF: 'KHR_binary_glTF', - KHR_MATERIALS_COMMON: 'KHR_materials_common' - }; - - /* MATERIALS COMMON EXTENSION */ - - function GLTFMaterialsCommonExtension( json ) { - - this.name = EXTENSIONS.KHR_MATERIALS_COMMON; - - this.lights = {}; - - var extension = ( json.extensions && json.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] ) || {}; - var lights = extension.lights || {}; - - for ( var lightId in lights ) { - - var light = lights[ lightId ]; - var lightNode; - - var lightParams = light[ light.type ]; - var color = new THREE.Color().fromArray( lightParams.color ); - - switch ( light.type ) { - - case "directional": - lightNode = new THREE.DirectionalLight( color ); - lightNode.position.set( 0, 0, 1 ); - break; - - case "point": - lightNode = new THREE.PointLight( color ); - break; - - case "spot": - lightNode = new THREE.SpotLight( color ); - lightNode.position.set( 0, 0, 1 ); - break; - - case "ambient": - lightNode = new THREE.AmbientLight( color ); - break; - - } - - if ( lightNode ) { - - this.lights[ lightId ] = lightNode; - - } - - } - - } - - /* BINARY EXTENSION */ - - var BINARY_EXTENSION_BUFFER_NAME = 'binary_glTF'; - - var BINARY_EXTENSION_HEADER_DEFAULTS = { magic: 'glTF', version: 1, contentFormat: 0 }; - - var BINARY_EXTENSION_HEADER_LENGTH = 20; - - function GLTFBinaryExtension( data ) { - - this.name = EXTENSIONS.KHR_BINARY_GLTF; - - var headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH ); - - var header = { - magic: THREE.LoaderUtils.decodeText( new Uint8Array( data.slice( 0, 4 ) ) ), - version: headerView.getUint32( 4, true ), - length: headerView.getUint32( 8, true ), - contentLength: headerView.getUint32( 12, true ), - contentFormat: headerView.getUint32( 16, true ) - }; - - for ( var key in BINARY_EXTENSION_HEADER_DEFAULTS ) { - - var value = BINARY_EXTENSION_HEADER_DEFAULTS[ key ]; - - if ( header[ key ] !== value ) { - - throw new Error( 'Unsupported glTF-Binary header: Expected "%s" to be "%s".', key, value ); - - } - - } - - var contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH, header.contentLength ); - - this.header = header; - this.content = THREE.LoaderUtils.decodeText( contentArray ); - this.body = data.slice( BINARY_EXTENSION_HEADER_LENGTH + header.contentLength, header.length ); - - } - - GLTFBinaryExtension.prototype.loadShader = function ( shader, bufferViews ) { - - var bufferView = bufferViews[ shader.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].bufferView ]; - var array = new Uint8Array( bufferView ); - - return THREE.LoaderUtils.decodeText( array ); - - }; - - /*********************************/ - /********** INTERNALS ************/ - /*********************************/ - - /* CONSTANTS */ - - var WEBGL_CONSTANTS = { - FLOAT: 5126, - //FLOAT_MAT2: 35674, - FLOAT_MAT3: 35675, - FLOAT_MAT4: 35676, - FLOAT_VEC2: 35664, - FLOAT_VEC3: 35665, - FLOAT_VEC4: 35666, - LINEAR: 9729, - REPEAT: 10497, - SAMPLER_2D: 35678, - TRIANGLES: 4, - LINES: 1, - UNSIGNED_BYTE: 5121, - UNSIGNED_SHORT: 5123, - - VERTEX_SHADER: 35633, - FRAGMENT_SHADER: 35632 - }; - - var WEBGL_TYPE = { - 5126: Number, - //35674: THREE.Matrix2, - 35675: THREE.Matrix3, - 35676: THREE.Matrix4, - 35664: THREE.Vector2, - 35665: THREE.Vector3, - 35666: THREE.Vector4, - 35678: THREE.Texture - }; - - var WEBGL_COMPONENT_TYPES = { - 5120: Int8Array, - 5121: Uint8Array, - 5122: Int16Array, - 5123: Uint16Array, - 5125: Uint32Array, - 5126: Float32Array - }; - - var WEBGL_FILTERS = { - 9728: THREE.NearestFilter, - 9729: THREE.LinearFilter, - 9984: THREE.NearestMipmapNearestFilter, - 9985: THREE.LinearMipmapNearestFilter, - 9986: THREE.NearestMipmapLinearFilter, - 9987: THREE.LinearMipmapLinearFilter - }; - - var WEBGL_WRAPPINGS = { - 33071: THREE.ClampToEdgeWrapping, - 33648: THREE.MirroredRepeatWrapping, - 10497: THREE.RepeatWrapping - }; - - var WEBGL_TEXTURE_FORMATS = { - 6406: THREE.AlphaFormat, - 6407: THREE.RGBFormat, - 6408: THREE.RGBAFormat, - 6409: THREE.LuminanceFormat, - 6410: THREE.LuminanceAlphaFormat - }; - - var WEBGL_TEXTURE_DATATYPES = { - 5121: THREE.UnsignedByteType, - 32819: THREE.UnsignedShort4444Type, - 32820: THREE.UnsignedShort5551Type, - 33635: THREE.UnsignedShort565Type - }; - - var WEBGL_SIDES = { - 1028: THREE.BackSide, // Culling front - 1029: THREE.FrontSide // Culling back - //1032: THREE.NoSide // Culling front and back, what to do? - }; - - var WEBGL_DEPTH_FUNCS = { - 512: THREE.NeverDepth, - 513: THREE.LessDepth, - 514: THREE.EqualDepth, - 515: THREE.LessEqualDepth, - 516: THREE.GreaterEqualDepth, - 517: THREE.NotEqualDepth, - 518: THREE.GreaterEqualDepth, - 519: THREE.AlwaysDepth - }; - - var WEBGL_BLEND_EQUATIONS = { - 32774: THREE.AddEquation, - 32778: THREE.SubtractEquation, - 32779: THREE.ReverseSubtractEquation - }; - - var WEBGL_BLEND_FUNCS = { - 0: THREE.ZeroFactor, - 1: THREE.OneFactor, - 768: THREE.SrcColorFactor, - 769: THREE.OneMinusSrcColorFactor, - 770: THREE.SrcAlphaFactor, - 771: THREE.OneMinusSrcAlphaFactor, - 772: THREE.DstAlphaFactor, - 773: THREE.OneMinusDstAlphaFactor, - 774: THREE.DstColorFactor, - 775: THREE.OneMinusDstColorFactor, - 776: THREE.SrcAlphaSaturateFactor - // The followings are not supported by Three.js yet - //32769: CONSTANT_COLOR, - //32770: ONE_MINUS_CONSTANT_COLOR, - //32771: CONSTANT_ALPHA, - //32772: ONE_MINUS_CONSTANT_COLOR - }; - - var WEBGL_TYPE_SIZES = { - 'SCALAR': 1, - 'VEC2': 2, - 'VEC3': 3, - 'VEC4': 4, - 'MAT2': 4, - 'MAT3': 9, - 'MAT4': 16 - }; - - var PATH_PROPERTIES = { - scale: 'scale', - translation: 'position', - rotation: 'quaternion' - }; - - var INTERPOLATION = { - LINEAR: THREE.InterpolateLinear, - STEP: THREE.InterpolateDiscrete - }; - - var STATES_ENABLES = { - 2884: 'CULL_FACE', - 2929: 'DEPTH_TEST', - 3042: 'BLEND', - 3089: 'SCISSOR_TEST', - 32823: 'POLYGON_OFFSET_FILL', - 32926: 'SAMPLE_ALPHA_TO_COVERAGE' - }; - - /* UTILITY FUNCTIONS */ - - function _each( object, callback, thisObj ) { - - if ( ! object ) { - - return Promise.resolve(); - - } - - var results; - var fns = []; - - if ( Object.prototype.toString.call( object ) === '[object Array]' ) { - - results = []; - - var length = object.length; - - for ( var idx = 0; idx < length; idx ++ ) { - - var value = callback.call( thisObj || this, object[ idx ], idx ); - - if ( value ) { - - fns.push( value ); - - if ( value instanceof Promise ) { - - value.then( function ( key, value ) { - - results[ key ] = value; - - }.bind( this, idx ) ); - - } else { - - results[ idx ] = value; - - } - - } - - } - - } else { - - results = {}; - - for ( var key in object ) { - - if ( object.hasOwnProperty( key ) ) { - - var value = callback.call( thisObj || this, object[ key ], key ); - - if ( value ) { - - fns.push( value ); - - if ( value instanceof Promise ) { - - value.then( function ( key, value ) { - - results[ key ] = value; - - }.bind( this, key ) ); - - } else { - - results[ key ] = value; - - } - - } - - } - - } - - } - - return Promise.all( fns ).then( function () { - - return results; - - } ); - - } - - function resolveURL( url, path ) { - - // Invalid URL - if ( typeof url !== 'string' || url === '' ) - return ''; - - // Absolute URL http://,https://,// - if ( /^(https?:)?\/\//i.test( url ) ) { - - return url; - - } - - // Data URI - if ( /^data:.*,.*$/i.test( url ) ) { - - return url; - - } - - // Blob URL - if ( /^blob:.*$/i.test( url ) ) { - - return url; - - } - - // Relative URL - return ( path || '' ) + url; - - } - - // Three.js seems too dependent on attribute names so globally - // replace those in the shader code - function replaceTHREEShaderAttributes( shaderText, technique ) { - - // Expected technique attributes - var attributes = {}; - - for ( var attributeId in technique.attributes ) { - - var pname = technique.attributes[ attributeId ]; - - var param = technique.parameters[ pname ]; - var atype = param.type; - var semantic = param.semantic; - - attributes[ attributeId ] = { - type: atype, - semantic: semantic - }; - - } - - // Figure out which attributes to change in technique - - var shaderParams = technique.parameters; - var shaderAttributes = technique.attributes; - var params = {}; - - for ( var attributeId in attributes ) { - - var pname = shaderAttributes[ attributeId ]; - var shaderParam = shaderParams[ pname ]; - var semantic = shaderParam.semantic; - if ( semantic ) { - - params[ attributeId ] = shaderParam; - - } - - } - - for ( var pname in params ) { - - var param = params[ pname ]; - var semantic = param.semantic; - - var regEx = new RegExp( "\\b" + pname + "\\b", "g" ); - - switch ( semantic ) { - - case "POSITION": - - shaderText = shaderText.replace( regEx, 'position' ); - break; - - case "NORMAL": - - shaderText = shaderText.replace( regEx, 'normal' ); - break; - - case 'TEXCOORD_0': - case 'TEXCOORD0': - case 'TEXCOORD': - - shaderText = shaderText.replace( regEx, 'uv' ); - break; - - case 'TEXCOORD_1': - - shaderText = shaderText.replace( regEx, 'uv2' ); - break; - - case 'COLOR_0': - case 'COLOR0': - case 'COLOR': - - shaderText = shaderText.replace( regEx, 'color' ); - break; - - case "WEIGHT": - - shaderText = shaderText.replace( regEx, 'skinWeight' ); - break; - - case "JOINT": - - shaderText = shaderText.replace( regEx, 'skinIndex' ); - break; - - } - - } - - return shaderText; - - } - - function createDefaultMaterial() { - - return new THREE.MeshPhongMaterial( { - color: 0x00000, - emissive: 0x888888, - specular: 0x000000, - shininess: 0, - transparent: false, - depthTest: true, - side: THREE.FrontSide - } ); - - } - - // Deferred constructor for RawShaderMaterial types - function DeferredShaderMaterial( params ) { - - this.isDeferredShaderMaterial = true; - - this.params = params; - - } - - DeferredShaderMaterial.prototype.create = function () { - - var uniforms = THREE.UniformsUtils.clone( this.params.uniforms ); - - for ( var uniformId in this.params.uniforms ) { - - var originalUniform = this.params.uniforms[ uniformId ]; - - if ( originalUniform.value instanceof THREE.Texture ) { - - uniforms[ uniformId ].value = originalUniform.value; - uniforms[ uniformId ].value.needsUpdate = true; - - } - - uniforms[ uniformId ].semantic = originalUniform.semantic; - uniforms[ uniformId ].node = originalUniform.node; - - } - - this.params.uniforms = uniforms; - - return new THREE.RawShaderMaterial( this.params ); - - }; - - /* GLTF PARSER */ - - function GLTFParser( json, extensions, options ) { - - this.json = json || {}; - this.extensions = extensions || {}; - this.options = options || {}; - - // loader object cache - this.cache = new GLTFRegistry(); - - } - - GLTFParser.prototype._withDependencies = function ( dependencies ) { - - var _dependencies = {}; - - for ( var i = 0; i < dependencies.length; i ++ ) { - - var dependency = dependencies[ i ]; - var fnName = "load" + dependency.charAt( 0 ).toUpperCase() + dependency.slice( 1 ); - - var cached = this.cache.get( dependency ); - - if ( cached !== undefined ) { - - _dependencies[ dependency ] = cached; - - } else if ( this[ fnName ] ) { - - var fn = this[ fnName ](); - this.cache.add( dependency, fn ); - - _dependencies[ dependency ] = fn; - - } - - } - - return _each( _dependencies, function ( dependency ) { - - return dependency; - - } ); - - }; - - GLTFParser.prototype.parse = function ( callback ) { - - var json = this.json; - - // Clear the loader cache - this.cache.removeAll(); - - // Fire the callback on complete - this._withDependencies( [ - - "scenes", - "cameras", - "animations" - - ] ).then( function ( dependencies ) { - - var scenes = []; - - for ( var name in dependencies.scenes ) { - - scenes.push( dependencies.scenes[ name ] ); - - } - - var scene = json.scene !== undefined ? dependencies.scenes[ json.scene ] : scenes[ 0 ]; - - var cameras = []; - - for ( var name in dependencies.cameras ) { - - var camera = dependencies.cameras[ name ]; - cameras.push( camera ); - - } - - var animations = []; - - for ( var name in dependencies.animations ) { - - animations.push( dependencies.animations[ name ] ); - - } - - callback( scene, scenes, cameras, animations ); - - } ); - - }; - - GLTFParser.prototype.loadShaders = function () { - - var json = this.json; - var extensions = this.extensions; - var options = this.options; - - return this._withDependencies( [ - - "bufferViews" - - ] ).then( function ( dependencies ) { - - return _each( json.shaders, function ( shader ) { - - if ( shader.extensions && shader.extensions[ EXTENSIONS.KHR_BINARY_GLTF ] ) { - - return extensions[ EXTENSIONS.KHR_BINARY_GLTF ].loadShader( shader, dependencies.bufferViews ); - - } - - return new Promise( function ( resolve ) { - - var loader = new THREE.FileLoader( options.manager ); - loader.setResponseType( 'text' ); - loader.load( resolveURL( shader.uri, options.path ), function ( shaderText ) { - - resolve( shaderText ); - - } ); - - } ); - - } ); - - } ); - - }; - - GLTFParser.prototype.loadBuffers = function () { - - var json = this.json; - var extensions = this.extensions; - var options = this.options; - - return _each( json.buffers, function ( buffer, name ) { - - if ( name === BINARY_EXTENSION_BUFFER_NAME ) { - - return extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body; - - } - - if ( buffer.type === 'arraybuffer' || buffer.type === undefined ) { - - return new Promise( function ( resolve ) { - - var loader = new THREE.FileLoader( options.manager ); - loader.setResponseType( 'arraybuffer' ); - loader.load( resolveURL( buffer.uri, options.path ), function ( buffer ) { - - resolve( buffer ); - - } ); - - } ); - - } else { - - console.warn( 'THREE.LegacyGLTFLoader: ' + buffer.type + ' buffer type is not supported' ); - - } - - } ); - - }; - - GLTFParser.prototype.loadBufferViews = function () { - - var json = this.json; - - return this._withDependencies( [ - - "buffers" - - ] ).then( function ( dependencies ) { - - return _each( json.bufferViews, function ( bufferView ) { - - var arraybuffer = dependencies.buffers[ bufferView.buffer ]; - - var byteLength = bufferView.byteLength !== undefined ? bufferView.byteLength : 0; - - return arraybuffer.slice( bufferView.byteOffset, bufferView.byteOffset + byteLength ); - - } ); - - } ); - - }; - - GLTFParser.prototype.loadAccessors = function () { - - var json = this.json; - - return this._withDependencies( [ - - "bufferViews" - - ] ).then( function ( dependencies ) { - - return _each( json.accessors, function ( accessor ) { - - var arraybuffer = dependencies.bufferViews[ accessor.bufferView ]; - var itemSize = WEBGL_TYPE_SIZES[ accessor.type ]; - var TypedArray = WEBGL_COMPONENT_TYPES[ accessor.componentType ]; - - // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12. - var elementBytes = TypedArray.BYTES_PER_ELEMENT; - var itemBytes = elementBytes * itemSize; - - // The buffer is not interleaved if the stride is the item size in bytes. - if ( accessor.byteStride && accessor.byteStride !== itemBytes ) { - - // Use the full buffer if it's interleaved. - var array = new TypedArray( arraybuffer ); - - // Integer parameters to IB/IBA are in array elements, not bytes. - var ib = new THREE.InterleavedBuffer( array, accessor.byteStride / elementBytes ); - - return new THREE.InterleavedBufferAttribute( ib, itemSize, accessor.byteOffset / elementBytes ); - - } else { - - array = new TypedArray( arraybuffer, accessor.byteOffset, accessor.count * itemSize ); - - return new THREE.BufferAttribute( array, itemSize ); - - } - - } ); - - } ); - - }; - - GLTFParser.prototype.loadTextures = function () { - - var json = this.json; - var options = this.options; - - return this._withDependencies( [ - - "bufferViews" - - ] ).then( function ( dependencies ) { - - return _each( json.textures, function ( texture ) { - - if ( texture.source ) { - - return new Promise( function ( resolve ) { - - var source = json.images[ texture.source ]; - var sourceUri = source.uri; - var isObjectURL = false; - - if ( source.extensions && source.extensions[ EXTENSIONS.KHR_BINARY_GLTF ] ) { - - var metadata = source.extensions[ EXTENSIONS.KHR_BINARY_GLTF ]; - var bufferView = dependencies.bufferViews[ metadata.bufferView ]; - var blob = new Blob( [ bufferView ], { type: metadata.mimeType } ); - sourceUri = URL.createObjectURL( blob ); - isObjectURL = true; - - } - - var textureLoader = THREE.Loader.Handlers.get( sourceUri ); - - if ( textureLoader === null ) { - - textureLoader = new THREE.TextureLoader( options.manager ); - - } - - textureLoader.setCrossOrigin( options.crossOrigin ); - - textureLoader.load( resolveURL( sourceUri, options.path ), function ( _texture ) { - - if ( isObjectURL ) URL.revokeObjectURL( sourceUri ); - - _texture.flipY = false; - - if ( texture.name !== undefined ) _texture.name = texture.name; - - _texture.format = texture.format !== undefined ? WEBGL_TEXTURE_FORMATS[ texture.format ] : THREE.RGBAFormat; - - if ( texture.internalFormat !== undefined && _texture.format !== WEBGL_TEXTURE_FORMATS[ texture.internalFormat ] ) { - - console.warn( 'THREE.LegacyGLTFLoader: Three.js doesn\'t support texture internalFormat which is different from texture format. ' + - 'internalFormat will be forced to be the same value as format.' ); - - } - - _texture.type = texture.type !== undefined ? WEBGL_TEXTURE_DATATYPES[ texture.type ] : THREE.UnsignedByteType; - - if ( texture.sampler ) { - - var sampler = json.samplers[ texture.sampler ]; - - _texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter; - _texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.NearestMipmapLinearFilter; - _texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping; - _texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping; - - } - - resolve( _texture ); - - }, undefined, function () { - - if ( isObjectURL ) URL.revokeObjectURL( sourceUri ); - - resolve(); - - } ); - - } ); - - } - - } ); - - } ); - - }; - - GLTFParser.prototype.loadMaterials = function () { - - var json = this.json; - - return this._withDependencies( [ - - "shaders", - "textures" - - ] ).then( function ( dependencies ) { - - return _each( json.materials, function ( material ) { - - var materialType; - var materialValues = {}; - var materialParams = {}; - - var khr_material; - - if ( material.extensions && material.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] ) { - - khr_material = material.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ]; - - } - - if ( khr_material ) { - - // don't copy over unused values to avoid material warning spam - var keys = [ 'ambient', 'emission', 'transparent', 'transparency', 'doubleSided' ]; - - switch ( khr_material.technique ) { - - case 'BLINN' : - case 'PHONG' : - materialType = THREE.MeshPhongMaterial; - keys.push( 'diffuse', 'specular', 'shininess' ); - break; - - case 'LAMBERT' : - materialType = THREE.MeshLambertMaterial; - keys.push( 'diffuse' ); - break; - - case 'CONSTANT' : - default : - materialType = THREE.MeshBasicMaterial; - break; - - } - - keys.forEach( function ( v ) { - - if ( khr_material.values[ v ] !== undefined ) materialValues[ v ] = khr_material.values[ v ]; - - } ); - - if ( khr_material.doubleSided || materialValues.doubleSided ) { - - materialParams.side = THREE.DoubleSide; - - } - - if ( khr_material.transparent || materialValues.transparent ) { - - materialParams.transparent = true; - materialParams.opacity = ( materialValues.transparency !== undefined ) ? materialValues.transparency : 1; - - } - - } else if ( material.technique === undefined ) { - - materialType = THREE.MeshPhongMaterial; - - Object.assign( materialValues, material.values ); - - } else { - - materialType = DeferredShaderMaterial; - - var technique = json.techniques[ material.technique ]; - - materialParams.uniforms = {}; - - var program = json.programs[ technique.program ]; - - if ( program ) { - - materialParams.fragmentShader = dependencies.shaders[ program.fragmentShader ]; - - if ( ! materialParams.fragmentShader ) { - - console.warn( "ERROR: Missing fragment shader definition:", program.fragmentShader ); - materialType = THREE.MeshPhongMaterial; - - } - - var vertexShader = dependencies.shaders[ program.vertexShader ]; - - if ( ! vertexShader ) { - - console.warn( "ERROR: Missing vertex shader definition:", program.vertexShader ); - materialType = THREE.MeshPhongMaterial; - - } - - // IMPORTANT: FIX VERTEX SHADER ATTRIBUTE DEFINITIONS - materialParams.vertexShader = replaceTHREEShaderAttributes( vertexShader, technique ); - - var uniforms = technique.uniforms; - - for ( var uniformId in uniforms ) { - - var pname = uniforms[ uniformId ]; - var shaderParam = technique.parameters[ pname ]; - - var ptype = shaderParam.type; - - if ( WEBGL_TYPE[ ptype ] ) { - - var pcount = shaderParam.count; - var value; - - if ( material.values !== undefined ) value = material.values[ pname ]; - - var uvalue = new WEBGL_TYPE[ ptype ](); - var usemantic = shaderParam.semantic; - var unode = shaderParam.node; - - switch ( ptype ) { - - case WEBGL_CONSTANTS.FLOAT: - - uvalue = shaderParam.value; - - if ( pname == "transparency" ) { - - materialParams.transparent = true; - - } - - if ( value !== undefined ) { - - uvalue = value; - - } - - break; - - case WEBGL_CONSTANTS.FLOAT_VEC2: - case WEBGL_CONSTANTS.FLOAT_VEC3: - case WEBGL_CONSTANTS.FLOAT_VEC4: - case WEBGL_CONSTANTS.FLOAT_MAT3: - - if ( shaderParam && shaderParam.value ) { - - uvalue.fromArray( shaderParam.value ); - - } - - if ( value ) { - - uvalue.fromArray( value ); - - } - - break; - - case WEBGL_CONSTANTS.FLOAT_MAT2: - - // what to do? - console.warn( "FLOAT_MAT2 is not a supported uniform type" ); - break; - - case WEBGL_CONSTANTS.FLOAT_MAT4: - - if ( pcount ) { - - uvalue = new Array( pcount ); - - for ( var mi = 0; mi < pcount; mi ++ ) { - - uvalue[ mi ] = new WEBGL_TYPE[ ptype ](); - - } - - if ( shaderParam && shaderParam.value ) { - - var m4v = shaderParam.value; - uvalue.fromArray( m4v ); - - } - - if ( value ) { - - uvalue.fromArray( value ); - - } - - } else { - - if ( shaderParam && shaderParam.value ) { - - var m4 = shaderParam.value; - uvalue.fromArray( m4 ); - - } - - if ( value ) { - - uvalue.fromArray( value ); - - } - - } - - break; - - case WEBGL_CONSTANTS.SAMPLER_2D: - - if ( value !== undefined ) { - - uvalue = dependencies.textures[ value ]; - - } else if ( shaderParam.value !== undefined ) { - - uvalue = dependencies.textures[ shaderParam.value ]; - - } else { - - uvalue = null; - - } - - break; - - } - - materialParams.uniforms[ uniformId ] = { - value: uvalue, - semantic: usemantic, - node: unode - }; - - } else { - - throw new Error( "Unknown shader uniform param type: " + ptype ); - - } - - } - - var states = technique.states || {}; - var enables = states.enable || []; - var functions = states.functions || {}; - - var enableCullFace = false; - var enableDepthTest = false; - var enableBlend = false; - - for ( var i = 0, il = enables.length; i < il; i ++ ) { - - var enable = enables[ i ]; - - switch ( STATES_ENABLES[ enable ] ) { - - case 'CULL_FACE': - - enableCullFace = true; - - break; - - case 'DEPTH_TEST': - - enableDepthTest = true; - - break; - - case 'BLEND': - - enableBlend = true; - - break; - - // TODO: implement - case 'SCISSOR_TEST': - case 'POLYGON_OFFSET_FILL': - case 'SAMPLE_ALPHA_TO_COVERAGE': - - break; - - default: - - throw new Error( "Unknown technique.states.enable: " + enable ); - - } - - } - - if ( enableCullFace ) { - - materialParams.side = functions.cullFace !== undefined ? WEBGL_SIDES[ functions.cullFace ] : THREE.FrontSide; - - } else { - - materialParams.side = THREE.DoubleSide; - - } - - materialParams.depthTest = enableDepthTest; - materialParams.depthFunc = functions.depthFunc !== undefined ? WEBGL_DEPTH_FUNCS[ functions.depthFunc ] : THREE.LessDepth; - materialParams.depthWrite = functions.depthMask !== undefined ? functions.depthMask[ 0 ] : true; - - materialParams.blending = enableBlend ? THREE.CustomBlending : THREE.NoBlending; - materialParams.transparent = enableBlend; - - var blendEquationSeparate = functions.blendEquationSeparate; - - if ( blendEquationSeparate !== undefined ) { - - materialParams.blendEquation = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 0 ] ]; - materialParams.blendEquationAlpha = WEBGL_BLEND_EQUATIONS[ blendEquationSeparate[ 1 ] ]; - - } else { - - materialParams.blendEquation = THREE.AddEquation; - materialParams.blendEquationAlpha = THREE.AddEquation; - - } - - var blendFuncSeparate = functions.blendFuncSeparate; - - if ( blendFuncSeparate !== undefined ) { - - materialParams.blendSrc = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 0 ] ]; - materialParams.blendDst = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 1 ] ]; - materialParams.blendSrcAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 2 ] ]; - materialParams.blendDstAlpha = WEBGL_BLEND_FUNCS[ blendFuncSeparate[ 3 ] ]; - - } else { - - materialParams.blendSrc = THREE.OneFactor; - materialParams.blendDst = THREE.ZeroFactor; - materialParams.blendSrcAlpha = THREE.OneFactor; - materialParams.blendDstAlpha = THREE.ZeroFactor; - - } - - } - - } - - if ( Array.isArray( materialValues.diffuse ) ) { - - materialParams.color = new THREE.Color().fromArray( materialValues.diffuse ); - - } else if ( typeof ( materialValues.diffuse ) === 'string' ) { - - materialParams.map = dependencies.textures[ materialValues.diffuse ]; - - } - - delete materialParams.diffuse; - - if ( typeof ( materialValues.reflective ) === 'string' ) { - - materialParams.envMap = dependencies.textures[ materialValues.reflective ]; - - } - - if ( typeof ( materialValues.bump ) === 'string' ) { - - materialParams.bumpMap = dependencies.textures[ materialValues.bump ]; - - } - - if ( Array.isArray( materialValues.emission ) ) { - - if ( materialType === THREE.MeshBasicMaterial ) { - - materialParams.color = new THREE.Color().fromArray( materialValues.emission ); - - } else { - - materialParams.emissive = new THREE.Color().fromArray( materialValues.emission ); - - } - - } else if ( typeof ( materialValues.emission ) === 'string' ) { - - if ( materialType === THREE.MeshBasicMaterial ) { - - materialParams.map = dependencies.textures[ materialValues.emission ]; - - } else { - - materialParams.emissiveMap = dependencies.textures[ materialValues.emission ]; - - } - - } - - if ( Array.isArray( materialValues.specular ) ) { - - materialParams.specular = new THREE.Color().fromArray( materialValues.specular ); - - } else if ( typeof ( materialValues.specular ) === 'string' ) { - - materialParams.specularMap = dependencies.textures[ materialValues.specular ]; - - } - - if ( materialValues.shininess !== undefined ) { - - materialParams.shininess = materialValues.shininess; - - } - - var _material = new materialType( materialParams ); - if ( material.name !== undefined ) _material.name = material.name; - - return _material; - - } ); - - } ); - - }; - - GLTFParser.prototype.loadMeshes = function () { - - var json = this.json; - - return this._withDependencies( [ - - "accessors", - "materials" - - ] ).then( function ( dependencies ) { - - return _each( json.meshes, function ( mesh ) { - - var group = new THREE.Group(); - if ( mesh.name !== undefined ) group.name = mesh.name; - - if ( mesh.extras ) group.userData = mesh.extras; - - var primitives = mesh.primitives || []; - - for ( var name in primitives ) { - - var primitive = primitives[ name ]; - - if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === undefined ) { - - var geometry = new THREE.BufferGeometry(); - - var attributes = primitive.attributes; - - for ( var attributeId in attributes ) { - - var attributeEntry = attributes[ attributeId ]; - - if ( ! attributeEntry ) return; - - var bufferAttribute = dependencies.accessors[ attributeEntry ]; - - switch ( attributeId ) { - - case 'POSITION': - geometry.addAttribute( 'position', bufferAttribute ); - break; - - case 'NORMAL': - geometry.addAttribute( 'normal', bufferAttribute ); - break; - - case 'TEXCOORD_0': - case 'TEXCOORD0': - case 'TEXCOORD': - geometry.addAttribute( 'uv', bufferAttribute ); - break; - - case 'TEXCOORD_1': - geometry.addAttribute( 'uv2', bufferAttribute ); - break; - - case 'COLOR_0': - case 'COLOR0': - case 'COLOR': - geometry.addAttribute( 'color', bufferAttribute ); - break; - - case 'WEIGHT': - geometry.addAttribute( 'skinWeight', bufferAttribute ); - break; - - case 'JOINT': - geometry.addAttribute( 'skinIndex', bufferAttribute ); - break; - - default: - - if ( ! primitive.material ) break; - - var material = json.materials[ primitive.material ]; - - if ( ! material.technique ) break; - - var parameters = json.techniques[ material.technique ].parameters || {}; - - for ( var attributeName in parameters ) { - - if ( parameters[ attributeName ][ 'semantic' ] === attributeId ) { - - geometry.addAttribute( attributeName, bufferAttribute ); - - } - - } - - } - - } - - if ( primitive.indices ) { - - geometry.setIndex( dependencies.accessors[ primitive.indices ] ); - - } - - var material = dependencies.materials !== undefined ? dependencies.materials[ primitive.material ] : createDefaultMaterial(); - - var meshNode = new THREE.Mesh( geometry, material ); - meshNode.castShadow = true; - meshNode.name = ( name === "0" ? group.name : group.name + name ); - - if ( primitive.extras ) meshNode.userData = primitive.extras; - - group.add( meshNode ); - - } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) { - - var geometry = new THREE.BufferGeometry(); - - var attributes = primitive.attributes; - - for ( var attributeId in attributes ) { - - var attributeEntry = attributes[ attributeId ]; - - if ( ! attributeEntry ) return; - - var bufferAttribute = dependencies.accessors[ attributeEntry ]; - - switch ( attributeId ) { - - case 'POSITION': - geometry.addAttribute( 'position', bufferAttribute ); - break; - - case 'COLOR_0': - case 'COLOR0': - case 'COLOR': - geometry.addAttribute( 'color', bufferAttribute ); - break; - - } - - } - - var material = dependencies.materials[ primitive.material ]; - - var meshNode; - - if ( primitive.indices ) { - - geometry.setIndex( dependencies.accessors[ primitive.indices ] ); - - meshNode = new THREE.LineSegments( geometry, material ); - - } else { - - meshNode = new THREE.Line( geometry, material ); - - } - - meshNode.name = ( name === "0" ? group.name : group.name + name ); - - if ( primitive.extras ) meshNode.userData = primitive.extras; - - group.add( meshNode ); - - } else { - - console.warn( "Only triangular and line primitives are supported" ); - - } - - } - - return group; - - } ); - - } ); - - }; - - GLTFParser.prototype.loadCameras = function () { - - var json = this.json; - - return _each( json.cameras, function ( camera ) { - - if ( camera.type == "perspective" && camera.perspective ) { - - var yfov = camera.perspective.yfov; - var aspectRatio = camera.perspective.aspectRatio !== undefined ? camera.perspective.aspectRatio : 1; - - // According to COLLADA spec... - // aspectRatio = xfov / yfov - var xfov = yfov * aspectRatio; - - var _camera = new THREE.PerspectiveCamera( THREE.Math.radToDeg( xfov ), aspectRatio, camera.perspective.znear || 1, camera.perspective.zfar || 2e6 ); - if ( camera.name !== undefined ) _camera.name = camera.name; - - if ( camera.extras ) _camera.userData = camera.extras; - - return _camera; - - } else if ( camera.type == "orthographic" && camera.orthographic ) { - - var _camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, camera.orthographic.znear, camera.orthographic.zfar ); - if ( camera.name !== undefined ) _camera.name = camera.name; - - if ( camera.extras ) _camera.userData = camera.extras; - - return _camera; - - } - - } ); - - }; - - GLTFParser.prototype.loadSkins = function () { - - var json = this.json; - - return this._withDependencies( [ - - "accessors" - - ] ).then( function ( dependencies ) { - - return _each( json.skins, function ( skin ) { - - var bindShapeMatrix = new THREE.Matrix4(); - - if ( skin.bindShapeMatrix !== undefined ) bindShapeMatrix.fromArray( skin.bindShapeMatrix ); - - var _skin = { - bindShapeMatrix: bindShapeMatrix, - jointNames: skin.jointNames, - inverseBindMatrices: dependencies.accessors[ skin.inverseBindMatrices ] - }; - - return _skin; - - } ); - - } ); - - }; - - GLTFParser.prototype.loadAnimations = function () { - - var json = this.json; - - return this._withDependencies( [ - - "accessors", - "nodes" - - ] ).then( function ( dependencies ) { - - return _each( json.animations, function ( animation, animationId ) { - - var tracks = []; - - for ( var channelId in animation.channels ) { - - var channel = animation.channels[ channelId ]; - var sampler = animation.samplers[ channel.sampler ]; - - if ( sampler ) { - - var target = channel.target; - var name = target.id; - var input = animation.parameters !== undefined ? animation.parameters[ sampler.input ] : sampler.input; - var output = animation.parameters !== undefined ? animation.parameters[ sampler.output ] : sampler.output; - - var inputAccessor = dependencies.accessors[ input ]; - var outputAccessor = dependencies.accessors[ output ]; - - var node = dependencies.nodes[ name ]; - - if ( node ) { - - node.updateMatrix(); - node.matrixAutoUpdate = true; - - var TypedKeyframeTrack = PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.rotation - ? THREE.QuaternionKeyframeTrack - : THREE.VectorKeyframeTrack; - - var targetName = node.name ? node.name : node.uuid; - var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear; - - // KeyframeTrack.optimize() will modify given 'times' and 'values' - // buffers before creating a truncated copy to keep. Because buffers may - // be reused by other tracks, make copies here. - tracks.push( new TypedKeyframeTrack( - targetName + '.' + PATH_PROPERTIES[ target.path ], - THREE.AnimationUtils.arraySlice( inputAccessor.array, 0 ), - THREE.AnimationUtils.arraySlice( outputAccessor.array, 0 ), - interpolation - ) ); - - } - - } - - } - - var name = animation.name !== undefined ? animation.name : "animation_" + animationId; - - return new THREE.AnimationClip( name, undefined, tracks ); - - } ); - - } ); - - }; - - GLTFParser.prototype.loadNodes = function () { - - var json = this.json; - var extensions = this.extensions; - var scope = this; - - return _each( json.nodes, function ( node ) { - - var matrix = new THREE.Matrix4(); - - var _node; - - if ( node.jointName ) { - - _node = new THREE.Bone(); - _node.name = node.name !== undefined ? node.name : node.jointName; - _node.jointName = node.jointName; - - } else { - - _node = new THREE.Object3D(); - if ( node.name !== undefined ) _node.name = node.name; - - } - - if ( node.extras ) _node.userData = node.extras; - - if ( node.matrix !== undefined ) { - - matrix.fromArray( node.matrix ); - _node.applyMatrix( matrix ); - - } else { - - if ( node.translation !== undefined ) { - - _node.position.fromArray( node.translation ); - - } - - if ( node.rotation !== undefined ) { - - _node.quaternion.fromArray( node.rotation ); - - } - - if ( node.scale !== undefined ) { - - _node.scale.fromArray( node.scale ); - - } - - } - - return _node; - - } ).then( function ( __nodes ) { - - return scope._withDependencies( [ - - "meshes", - "skins", - "cameras" - - ] ).then( function ( dependencies ) { - - return _each( __nodes, function ( _node, nodeId ) { - - var node = json.nodes[ nodeId ]; - - if ( node.meshes !== undefined ) { - - for ( var meshId in node.meshes ) { - - var mesh = node.meshes[ meshId ]; - var group = dependencies.meshes[ mesh ]; - - if ( group === undefined ) { - - console.warn( 'LegacyGLTFLoader: Couldn\'t find node "' + mesh + '".' ); - continue; - - } - - for ( var childrenId in group.children ) { - - var child = group.children[ childrenId ]; - - // clone Mesh to add to _node - - var originalMaterial = child.material; - var originalGeometry = child.geometry; - var originalUserData = child.userData; - var originalName = child.name; - - var material; - - if ( originalMaterial.isDeferredShaderMaterial ) { - - originalMaterial = material = originalMaterial.create(); - - } else { - - material = originalMaterial; - - } - - switch ( child.type ) { - - case 'LineSegments': - child = new THREE.LineSegments( originalGeometry, material ); - break; - - case 'LineLoop': - child = new THREE.LineLoop( originalGeometry, material ); - break; - - case 'Line': - child = new THREE.Line( originalGeometry, material ); - break; - - default: - child = new THREE.Mesh( originalGeometry, material ); - - } - - child.castShadow = true; - child.userData = originalUserData; - child.name = originalName; - - var skinEntry; - - if ( node.skin ) { - - skinEntry = dependencies.skins[ node.skin ]; - - } - - // Replace Mesh with SkinnedMesh in library - if ( skinEntry ) { - - var getJointNode = function ( jointId ) { - - var keys = Object.keys( __nodes ); - - for ( var i = 0, il = keys.length; i < il; i ++ ) { - - var n = __nodes[ keys[ i ] ]; - - if ( n.jointName === jointId ) return n; - - } - - return null; - - }; - - var geometry = originalGeometry; - var material = originalMaterial; - material.skinning = true; - - child = new THREE.SkinnedMesh( geometry, material ); - child.castShadow = true; - child.userData = originalUserData; - child.name = originalName; - - var bones = []; - var boneInverses = []; - - for ( var i = 0, l = skinEntry.jointNames.length; i < l; i ++ ) { - - var jointId = skinEntry.jointNames[ i ]; - var jointNode = getJointNode( jointId ); - - if ( jointNode ) { - - bones.push( jointNode ); - - var m = skinEntry.inverseBindMatrices.array; - var mat = new THREE.Matrix4().fromArray( m, i * 16 ); - boneInverses.push( mat ); - - } else { - - console.warn( "WARNING: joint: '" + jointId + "' could not be found" ); - - } - - } - - child.bind( new THREE.Skeleton( bones, boneInverses ), skinEntry.bindShapeMatrix ); - - var buildBoneGraph = function ( parentJson, parentObject, property ) { - - var children = parentJson[ property ]; - - if ( children === undefined ) return; - - for ( var i = 0, il = children.length; i < il; i ++ ) { - - var nodeId = children[ i ]; - var bone = __nodes[ nodeId ]; - var boneJson = json.nodes[ nodeId ]; - - if ( bone !== undefined && bone.isBone === true && boneJson !== undefined ) { - - parentObject.add( bone ); - buildBoneGraph( boneJson, bone, 'children' ); - - } - - } - - }; - - buildBoneGraph( node, child, 'skeletons' ); - - } - - _node.add( child ); - - } - - } - - } - - if ( node.camera !== undefined ) { - - var camera = dependencies.cameras[ node.camera ]; - - _node.add( camera ); - - } - - if ( node.extensions - && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ] - && node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].light ) { - - var extensionLights = extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].lights; - var light = extensionLights[ node.extensions[ EXTENSIONS.KHR_MATERIALS_COMMON ].light ]; - - _node.add( light ); - - } - - return _node; - - } ); - - } ); - - } ); - - }; - - GLTFParser.prototype.loadScenes = function () { - - var json = this.json; - - // scene node hierachy builder - - function buildNodeHierachy( nodeId, parentObject, allNodes ) { - - var _node = allNodes[ nodeId ]; - parentObject.add( _node ); - - var node = json.nodes[ nodeId ]; - - if ( node.children ) { - - var children = node.children; - - for ( var i = 0, l = children.length; i < l; i ++ ) { - - var child = children[ i ]; - buildNodeHierachy( child, _node, allNodes ); - - } - - } - - } - - return this._withDependencies( [ - - "nodes" - - ] ).then( function ( dependencies ) { - - return _each( json.scenes, function ( scene ) { - - var _scene = new THREE.Scene(); - if ( scene.name !== undefined ) _scene.name = scene.name; - - if ( scene.extras ) _scene.userData = scene.extras; - - var nodes = scene.nodes || []; - - for ( var i = 0, l = nodes.length; i < l; i ++ ) { - - var nodeId = nodes[ i ]; - buildNodeHierachy( nodeId, _scene, dependencies.nodes ); - - } - - _scene.traverse( function ( child ) { - - // Register raw material meshes with LegacyGLTFLoader.Shaders - if ( child.material && child.material.isRawShaderMaterial ) { - - child.gltfShader = new GLTFShader( child, dependencies.nodes ); - child.onBeforeRender = function ( renderer, scene, camera ) { - - this.gltfShader.update( scene, camera ); - - }; - - } - - } ); - - return _scene; - - } ); - - } ); - - }; - - return LegacyGLTFLoader; - -} )(); diff --git a/examples/js/loaders/deprecated/LegacyJSONLoader.js b/examples/js/loaders/deprecated/LegacyJSONLoader.js deleted file mode 100644 index 0746af1109c643..00000000000000 --- a/examples/js/loaders/deprecated/LegacyJSONLoader.js +++ /dev/null @@ -1,578 +0,0 @@ -/** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ - -THREE.LegacyJSONLoader = ( function () { - - function LegacyJSONLoader( manager ) { - - if ( typeof manager === 'boolean' ) { - - console.warn( 'THREE.JSONLoader: showStatus parameter has been removed from constructor.' ); - manager = undefined; - - } - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - - this.withCredentials = false; - - } - - Object.assign( LegacyJSONLoader.prototype, { - - crossOrigin: 'anonymous', - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var path = ( this.path === undefined ) ? THREE.LoaderUtils.extractUrlBase( url ) : this.path; - - var loader = new THREE.FileLoader( this.manager ); - loader.setPath( this.path ); - loader.setWithCredentials( this.withCredentials ); - loader.load( url, function ( text ) { - - var json = JSON.parse( text ); - var metadata = json.metadata; - - if ( metadata !== undefined ) { - - var type = metadata.type; - - if ( type !== undefined ) { - - if ( type.toLowerCase() === 'object' ) { - - console.error( 'THREE.JSONLoader: ' + url + ' should be loaded with THREE.ObjectLoader instead.' ); - return; - - } - - } - - } - - var object = scope.parse( json, path ); - onLoad( object.geometry, object.materials ); - - }, onProgress, onError ); - - }, - - setPath: function ( value ) { - - this.path = value; - return this; - - }, - - setResourcePath: function ( value ) { - - this.resourcePath = value; - return this; - - }, - - setCrossOrigin: function ( value ) { - - this.crossOrigin = value; - return this; - - }, - - parse: ( function () { - - function parseModel( json, geometry ) { - - function isBitSet( value, position ) { - - return value & ( 1 << position ); - - } - - var i, j, fi, - - offset, zLength, - - colorIndex, normalIndex, uvIndex, materialIndex, - - type, - isQuad, - hasMaterial, - hasFaceVertexUv, - hasFaceNormal, hasFaceVertexNormal, - hasFaceColor, hasFaceVertexColor, - - vertex, face, faceA, faceB, hex, normal, - - uvLayer, uv, u, v, - - faces = json.faces, - vertices = json.vertices, - normals = json.normals, - colors = json.colors, - - scale = json.scale, - - nUvLayers = 0; - - - if ( json.uvs !== undefined ) { - - // disregard empty arrays - - for ( i = 0; i < json.uvs.length; i ++ ) { - - if ( json.uvs[ i ].length ) nUvLayers ++; - - } - - for ( i = 0; i < nUvLayers; i ++ ) { - - geometry.faceVertexUvs[ i ] = []; - - } - - } - - offset = 0; - zLength = vertices.length; - - while ( offset < zLength ) { - - vertex = new THREE.Vector3(); - - vertex.x = vertices[ offset ++ ] * scale; - vertex.y = vertices[ offset ++ ] * scale; - vertex.z = vertices[ offset ++ ] * scale; - - geometry.vertices.push( vertex ); - - } - - offset = 0; - zLength = faces.length; - - while ( offset < zLength ) { - - type = faces[ offset ++ ]; - - isQuad = isBitSet( type, 0 ); - hasMaterial = isBitSet( type, 1 ); - hasFaceVertexUv = isBitSet( type, 3 ); - hasFaceNormal = isBitSet( type, 4 ); - hasFaceVertexNormal = isBitSet( type, 5 ); - hasFaceColor = isBitSet( type, 6 ); - hasFaceVertexColor = isBitSet( type, 7 ); - - // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor); - - if ( isQuad ) { - - faceA = new THREE.Face3(); - faceA.a = faces[ offset ]; - faceA.b = faces[ offset + 1 ]; - faceA.c = faces[ offset + 3 ]; - - faceB = new THREE.Face3(); - faceB.a = faces[ offset + 1 ]; - faceB.b = faces[ offset + 2 ]; - faceB.c = faces[ offset + 3 ]; - - offset += 4; - - if ( hasMaterial ) { - - materialIndex = faces[ offset ++ ]; - faceA.materialIndex = materialIndex; - faceB.materialIndex = materialIndex; - - } - - // to get face <=> uv index correspondence - - fi = geometry.faces.length; - - if ( hasFaceVertexUv ) { - - for ( i = 0; i < nUvLayers; i ++ ) { - - uvLayer = json.uvs[ i ]; - - geometry.faceVertexUvs[ i ][ fi ] = []; - geometry.faceVertexUvs[ i ][ fi + 1 ] = []; - - for ( j = 0; j < 4; j ++ ) { - - uvIndex = faces[ offset ++ ]; - - u = uvLayer[ uvIndex * 2 ]; - v = uvLayer[ uvIndex * 2 + 1 ]; - - uv = new THREE.Vector2( u, v ); - - if ( j !== 2 ) geometry.faceVertexUvs[ i ][ fi ].push( uv ); - if ( j !== 0 ) geometry.faceVertexUvs[ i ][ fi + 1 ].push( uv ); - - } - - } - - } - - if ( hasFaceNormal ) { - - normalIndex = faces[ offset ++ ] * 3; - - faceA.normal.set( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - faceB.normal.copy( faceA.normal ); - - } - - if ( hasFaceVertexNormal ) { - - for ( i = 0; i < 4; i ++ ) { - - normalIndex = faces[ offset ++ ] * 3; - - normal = new THREE.Vector3( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - - if ( i !== 2 ) faceA.vertexNormals.push( normal ); - if ( i !== 0 ) faceB.vertexNormals.push( normal ); - - } - - } - - - if ( hasFaceColor ) { - - colorIndex = faces[ offset ++ ]; - hex = colors[ colorIndex ]; - - faceA.color.setHex( hex ); - faceB.color.setHex( hex ); - - } - - - if ( hasFaceVertexColor ) { - - for ( i = 0; i < 4; i ++ ) { - - colorIndex = faces[ offset ++ ]; - hex = colors[ colorIndex ]; - - if ( i !== 2 ) faceA.vertexColors.push( new THREE.Color( hex ) ); - if ( i !== 0 ) faceB.vertexColors.push( new THREE.Color( hex ) ); - - } - - } - - geometry.faces.push( faceA ); - geometry.faces.push( faceB ); - - } else { - - face = new THREE.Face3(); - face.a = faces[ offset ++ ]; - face.b = faces[ offset ++ ]; - face.c = faces[ offset ++ ]; - - if ( hasMaterial ) { - - materialIndex = faces[ offset ++ ]; - face.materialIndex = materialIndex; - - } - - // to get face <=> uv index correspondence - - fi = geometry.faces.length; - - if ( hasFaceVertexUv ) { - - for ( i = 0; i < nUvLayers; i ++ ) { - - uvLayer = json.uvs[ i ]; - - geometry.faceVertexUvs[ i ][ fi ] = []; - - for ( j = 0; j < 3; j ++ ) { - - uvIndex = faces[ offset ++ ]; - - u = uvLayer[ uvIndex * 2 ]; - v = uvLayer[ uvIndex * 2 + 1 ]; - - uv = new THREE.Vector2( u, v ); - - geometry.faceVertexUvs[ i ][ fi ].push( uv ); - - } - - } - - } - - if ( hasFaceNormal ) { - - normalIndex = faces[ offset ++ ] * 3; - - face.normal.set( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - } - - if ( hasFaceVertexNormal ) { - - for ( i = 0; i < 3; i ++ ) { - - normalIndex = faces[ offset ++ ] * 3; - - normal = new THREE.Vector3( - normals[ normalIndex ++ ], - normals[ normalIndex ++ ], - normals[ normalIndex ] - ); - - face.vertexNormals.push( normal ); - - } - - } - - - if ( hasFaceColor ) { - - colorIndex = faces[ offset ++ ]; - face.color.setHex( colors[ colorIndex ] ); - - } - - - if ( hasFaceVertexColor ) { - - for ( i = 0; i < 3; i ++ ) { - - colorIndex = faces[ offset ++ ]; - face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) ); - - } - - } - - geometry.faces.push( face ); - - } - - } - - } - - function parseSkin( json, geometry ) { - - var influencesPerVertex = ( json.influencesPerVertex !== undefined ) ? json.influencesPerVertex : 2; - - if ( json.skinWeights ) { - - for ( var i = 0, l = json.skinWeights.length; i < l; i += influencesPerVertex ) { - - var x = json.skinWeights[ i ]; - var y = ( influencesPerVertex > 1 ) ? json.skinWeights[ i + 1 ] : 0; - var z = ( influencesPerVertex > 2 ) ? json.skinWeights[ i + 2 ] : 0; - var w = ( influencesPerVertex > 3 ) ? json.skinWeights[ i + 3 ] : 0; - - geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) ); - - } - - } - - if ( json.skinIndices ) { - - for ( var i = 0, l = json.skinIndices.length; i < l; i += influencesPerVertex ) { - - var a = json.skinIndices[ i ]; - var b = ( influencesPerVertex > 1 ) ? json.skinIndices[ i + 1 ] : 0; - var c = ( influencesPerVertex > 2 ) ? json.skinIndices[ i + 2 ] : 0; - var d = ( influencesPerVertex > 3 ) ? json.skinIndices[ i + 3 ] : 0; - - geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) ); - - } - - } - - geometry.bones = json.bones; - - if ( geometry.bones && geometry.bones.length > 0 && ( geometry.skinWeights.length !== geometry.skinIndices.length || geometry.skinIndices.length !== geometry.vertices.length ) ) { - - console.warn( 'When skinning, number of vertices (' + geometry.vertices.length + '), skinIndices (' + - geometry.skinIndices.length + '), and skinWeights (' + geometry.skinWeights.length + ') should match.' ); - - } - - } - - function parseMorphing( json, geometry ) { - - var scale = json.scale; - - if ( json.morphTargets !== undefined ) { - - for ( var i = 0, l = json.morphTargets.length; i < l; i ++ ) { - - geometry.morphTargets[ i ] = {}; - geometry.morphTargets[ i ].name = json.morphTargets[ i ].name; - geometry.morphTargets[ i ].vertices = []; - - var dstVertices = geometry.morphTargets[ i ].vertices; - var srcVertices = json.morphTargets[ i ].vertices; - - for ( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) { - - var vertex = new THREE.Vector3(); - vertex.x = srcVertices[ v ] * scale; - vertex.y = srcVertices[ v + 1 ] * scale; - vertex.z = srcVertices[ v + 2 ] * scale; - - dstVertices.push( vertex ); - - } - - } - - } - - if ( json.morphColors !== undefined && json.morphColors.length > 0 ) { - - console.warn( 'THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.' ); - - var faces = geometry.faces; - var morphColors = json.morphColors[ 0 ].colors; - - for ( var i = 0, l = faces.length; i < l; i ++ ) { - - faces[ i ].color.fromArray( morphColors, i * 3 ); - - } - - } - - } - - function parseAnimations( json, geometry ) { - - var outputAnimations = []; - - // parse old style Bone/Hierarchy animations - var animations = []; - - if ( json.animation !== undefined ) { - - animations.push( json.animation ); - - } - - if ( json.animations !== undefined ) { - - if ( json.animations.length ) { - - animations = animations.concat( json.animations ); - - } else { - - animations.push( json.animations ); - - } - - } - - for ( var i = 0; i < animations.length; i ++ ) { - - var clip = THREE.AnimationClip.parseAnimation( animations[ i ], geometry.bones ); - if ( clip ) outputAnimations.push( clip ); - - } - - // parse implicit morph animations - if ( geometry.morphTargets ) { - - // TODO: Figure out what an appropraite FPS is for morph target animations -- defaulting to 10, but really it is completely arbitrary. - var morphAnimationClips = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 ); - outputAnimations = outputAnimations.concat( morphAnimationClips ); - - } - - if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations; - - } - - return function parse( json, path ) { - - if ( json.data !== undefined ) { - - // Geometry 4.0 spec - json = json.data; - - } - - if ( json.scale !== undefined ) { - - json.scale = 1.0 / json.scale; - - } else { - - json.scale = 1.0; - - } - - var geometry = new THREE.Geometry(); - - parseModel( json, geometry ); - parseSkin( json, geometry ); - parseMorphing( json, geometry ); - parseAnimations( json, geometry ); - - geometry.computeFaceNormals(); - geometry.computeBoundingSphere(); - - if ( json.materials === undefined || json.materials.length === 0 ) { - - return { geometry: geometry }; - - } else { - - var materials = THREE.Loader.prototype.initMaterials( json.materials, this.resourcePath || path, this.crossOrigin ); - - return { geometry: geometry, materials: materials }; - - } - - }; - - } )() - - } ); - - return LegacyJSONLoader; - -} )(); diff --git a/examples/js/math/ColorConverter.js b/examples/js/math/ColorConverter.js index 556952e4be2ec0..69457ed3f6a155 100644 --- a/examples/js/math/ColorConverter.js +++ b/examples/js/math/ColorConverter.js @@ -9,9 +9,9 @@ THREE.ColorConverter = { // https://gist.github.com/xpansive/1337890#file-index-js - h = THREE.Math.euclideanModulo( h, 1 ); - s = THREE.Math.clamp( s, 0, 1 ); - v = THREE.Math.clamp( v, 0, 1 ); + h = THREE.MathUtils.euclideanModulo( h, 1 ); + s = THREE.MathUtils.clamp( s, 0, 1 ); + v = THREE.MathUtils.clamp( v, 0, 1 ); return color.setHSL( h, ( s * v ) / ( ( h = ( 2 - s ) * v ) < 1 ? h : ( 2 - h ) ), h * 0.5 ); diff --git a/examples/js/misc/CarControls.js b/examples/js/misc/CarControls.js deleted file mode 100644 index 9ae93506538b7d..00000000000000 --- a/examples/js/misc/CarControls.js +++ /dev/null @@ -1,305 +0,0 @@ -/** - * @author alteredq / http://alteredqualia.com/ - * @author Lewy Blue https://github.com/looeee - * - * The model is expected to follow real world car proportions. You can try unusual car types - * but your results may be unexpected. Scaled models are also not supported. - * - * Defaults are rough estimates for a real world scale car model - * - */ - -THREE.CarControls = ( function ( ) { - - // private variables - var steeringWheelSpeed = 1.5; - var maxSteeringRotation = 0.6; - - var acceleration = 0; - - var maxSpeedReverse, accelerationReverse, deceleration; - - var controlKeys = { LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, BRAKE: 32 }; - - var wheelOrientation = 0; - var carOrientation = 0; - - var root = null; - - var frontLeftWheelRoot = null; - var frontRightWheelRoot = null; - - var frontLeftWheel = new THREE.Group(); - var frontRightWheel = new THREE.Group(); - var backLeftWheel = null; - var backRightWheel = null; - - var steeringWheel = null; - - var wheelDiameter = 1; - var length = 1; - - var loaded = false; - - var controls = { - - brake: false, - moveForward: false, - moveBackward: false, - moveLeft: false, - moveRight: false - - }; - - function CarControls( maxSpeed, acceleration, brakePower, turningRadius, keys ) { - - this.enabled = true; - - this.elemNames = { - flWheel: 'wheel_fl', - frWheel: 'wheel_fr', - rlWheel: 'wheel_rl', - rrWheel: 'wheel_rr', - steeringWheel: 'steering_wheel', // set to null to disable - }; - - // km/hr - this.maxSpeed = maxSpeed || 180; - maxSpeedReverse = - this.maxSpeed * 0.25; - - // m/s - this.acceleration = acceleration || 10; - accelerationReverse = this.acceleration * 0.5; - - // metres - this.turningRadius = turningRadius || 6; - - // m/s - deceleration = this.acceleration * 2; - - // multiplied with deceleration, so breaking deceleration = ( acceleration * 2 * brakePower ) m/s - this.brakePower = brakePower || 10; - - // exposed so that a user can use this for various effect, e.g blur - this.speed = 0; - - // keys used to control car - by default the arrow keys and space to brake - controlKeys = keys || controlKeys; - - // local axes of rotation - these are likely to vary between models - this.wheelRotationAxis = 'x'; - this.wheelTurnAxis = 'z'; - this.steeringWheelTurnAxis = 'y'; - - document.addEventListener( 'keydown', this.onKeyDown, false ); - document.addEventListener( 'keyup', this.onKeyUp, false ); - - } - - CarControls.prototype = { - - constructor: CarControls, - - onKeyDown: function ( event ) { - - switch ( event.keyCode ) { - - case controlKeys.BRAKE: - controls.brake = true; - controls.moveForward = false; - controls.moveBackward = false; - break; - - case controlKeys.UP: controls.moveForward = true; break; - - case controlKeys.DOWN: controls.moveBackward = true; break; - - case controlKeys.LEFT: controls.moveLeft = true; break; - - case controlKeys.RIGHT: controls.moveRight = true; break; - - } - - }, - - onKeyUp: function ( event ) { - - switch ( event.keyCode ) { - - case controlKeys.BRAKE: controls.brake = false; break; - - case controlKeys.UP: controls.moveForward = false; break; - - case controlKeys.DOWN: controls.moveBackward = false; break; - - case controlKeys.LEFT: controls.moveLeft = false; break; - - case controlKeys.RIGHT: controls.moveRight = false; break; - - } - - }, - - dispose: function () { - - document.removeEventListener( 'keydown', this.onKeyDown, false ); - document.removeEventListener( 'keyup', this.onKeyUp, false ); - - }, - - update: function ( delta ) { - - if ( ! loaded || ! this.enabled ) return; - - var brakingDeceleration = 1; - - if ( controls.brake ) brakingDeceleration = this.brakePower; - - if ( controls.moveForward ) { - - this.speed = THREE.Math.clamp( this.speed + delta * this.acceleration, maxSpeedReverse, this.maxSpeed ); - acceleration = THREE.Math.clamp( acceleration + delta, - 1, 1 ); - - } - - if ( controls.moveBackward ) { - - this.speed = THREE.Math.clamp( this.speed - delta * accelerationReverse, maxSpeedReverse, this.maxSpeed ); - acceleration = THREE.Math.clamp( acceleration - delta, - 1, 1 ); - - } - - if ( controls.moveLeft ) { - - wheelOrientation = THREE.Math.clamp( wheelOrientation + delta * steeringWheelSpeed, - maxSteeringRotation, maxSteeringRotation ); - - } - - if ( controls.moveRight ) { - - wheelOrientation = THREE.Math.clamp( wheelOrientation - delta * steeringWheelSpeed, - maxSteeringRotation, maxSteeringRotation ); - - } - - // this.speed decay - if ( ! ( controls.moveForward || controls.moveBackward ) ) { - - if ( this.speed > 0 ) { - - var k = exponentialEaseOut( this.speed / this.maxSpeed ); - - this.speed = THREE.Math.clamp( this.speed - k * delta * deceleration * brakingDeceleration, 0, this.maxSpeed ); - acceleration = THREE.Math.clamp( acceleration - k * delta, 0, 1 ); - - } else { - - var k = exponentialEaseOut( this.speed / maxSpeedReverse ); - - this.speed = THREE.Math.clamp( this.speed + k * delta * accelerationReverse * brakingDeceleration, maxSpeedReverse, 0 ); - acceleration = THREE.Math.clamp( acceleration + k * delta, - 1, 0 ); - - } - - } - - // steering decay - if ( ! ( controls.moveLeft || controls.moveRight ) ) { - - if ( wheelOrientation > 0 ) { - - wheelOrientation = THREE.Math.clamp( wheelOrientation - delta * steeringWheelSpeed, 0, maxSteeringRotation ); - - } else { - - wheelOrientation = THREE.Math.clamp( wheelOrientation + delta * steeringWheelSpeed, - maxSteeringRotation, 0 ); - - } - - } - - var forwardDelta = - this.speed * delta; - - carOrientation -= ( forwardDelta * this.turningRadius * 0.02 ) * wheelOrientation; - - // movement of car - root.position.x += Math.sin( carOrientation ) * forwardDelta * length; - root.position.z += Math.cos( carOrientation ) * forwardDelta * length; - - // angle of car - root.rotation.y = carOrientation; - - // wheels rolling - var angularSpeedRatio = - 2 / wheelDiameter; - - var wheelDelta = forwardDelta * angularSpeedRatio * length; - - frontLeftWheel.rotation[ this.wheelRotationAxis ] -= wheelDelta; - frontRightWheel.rotation[ this.wheelRotationAxis ] -= wheelDelta; - backLeftWheel.rotation[ this.wheelRotationAxis ] -= wheelDelta; - backRightWheel.rotation[ this.wheelRotationAxis ] -= wheelDelta; - - // rotation while steering - frontLeftWheelRoot.rotation[ this.wheelTurnAxis ] = wheelOrientation; - frontRightWheelRoot.rotation[ this.wheelTurnAxis ] = wheelOrientation; - - steeringWheel.rotation[ this.steeringWheelTurnAxis ] = -wheelOrientation * 6; - - }, - - setModel: function ( model, elemNames ) { - - if ( elemNames ) this.elemNames = elemNames; - - root = model; - - this.setupWheels(); - this.computeDimensions(); - - loaded = true; - - }, - - setupWheels: function () { - - frontLeftWheelRoot = root.getObjectByName( this.elemNames.flWheel ); - frontRightWheelRoot = root.getObjectByName( this.elemNames.frWheel ); - backLeftWheel = root.getObjectByName( this.elemNames.rlWheel ); - backRightWheel = root.getObjectByName( this.elemNames.rrWheel ); - - if ( this.elemNames.steeringWheel !== null ) steeringWheel = root.getObjectByName( this.elemNames.steeringWheel ); - - while ( frontLeftWheelRoot.children.length > 0 ) frontLeftWheel.add( frontLeftWheelRoot.children[ 0 ] ); - while ( frontRightWheelRoot.children.length > 0 ) frontRightWheel.add( frontRightWheelRoot.children[ 0 ] ); - - frontLeftWheelRoot.add( frontLeftWheel ); - frontRightWheelRoot.add( frontRightWheel ); - - }, - - computeDimensions: function () { - - var bb = new THREE.Box3().setFromObject( frontLeftWheelRoot ); - - var size = new THREE.Vector3(); - bb.getSize( size ); - - wheelDiameter = Math.max( size.x, size.y, size.z ); - - bb.setFromObject( root ); - - size = bb.getSize( size ); - length = Math.max( size.x, size.y, size.z ); - - } - - }; - - function exponentialEaseOut( k ) { - - return k === 1 ? 1 : - Math.pow( 2, - 10 * k ) + 1; - - } - - return CarControls; - -} )(); diff --git a/examples/js/misc/GPUComputationRenderer.js b/examples/js/misc/GPUComputationRenderer.js index 350ee8f7ea62a6..0fc9c49779ae0d 100644 --- a/examples/js/misc/GPUComputationRenderer.js +++ b/examples/js/misc/GPUComputationRenderer.js @@ -148,8 +148,8 @@ THREE.GPUComputationRenderer = function ( sizeX, sizeY, renderer ) { this.init = function () { - if ( ! renderer.extensions.get( "OES_texture_float" ) && - ! renderer.capabilities.isWebGL2 ) { + if ( ! renderer.capabilities.isWebGL2 && + ! renderer.extensions.get( "OES_texture_float" ) ) { return "No OES_texture_float support for float textures."; @@ -318,11 +318,8 @@ THREE.GPUComputationRenderer = function ( sizeX, sizeY, renderer ) { this.createTexture = function () { - var a = new Float32Array( sizeX * sizeY * 4 ); - var texture = new THREE.DataTexture( a, sizeX, sizeY, THREE.RGBAFormat, THREE.FloatType ); - texture.needsUpdate = true; - - return texture; + var data = new Float32Array( sizeX * sizeY * 4 ); + return new THREE.DataTexture( data, sizeX, sizeY, THREE.RGBAFormat, THREE.FloatType ); }; diff --git a/examples/js/misc/MD2Character.js b/examples/js/misc/MD2Character.js index 3e63fae0b706d3..14819e04ff7b7c 100644 --- a/examples/js/misc/MD2Character.js +++ b/examples/js/misc/MD2Character.js @@ -221,6 +221,7 @@ THREE.MD2Character = function () { textures[ i ] = textureLoader.load( baseUrl + textureUrls[ i ], checkLoadingComplete ); textures[ i ].mapping = THREE.UVMapping; textures[ i ].name = textureUrls[ i ]; + textures[ i ].encoding = THREE.sRGBEncoding; } diff --git a/examples/js/misc/MD2CharacterComplex.js b/examples/js/misc/MD2CharacterComplex.js index 82b4c2ed60dd92..3d09900372c78c 100644 --- a/examples/js/misc/MD2CharacterComplex.js +++ b/examples/js/misc/MD2CharacterComplex.js @@ -451,8 +451,8 @@ THREE.MD2CharacterComplex = function () { this.maxReverseSpeed = - this.maxSpeed; - if ( controls.moveForward ) this.speed = THREE.Math.clamp( this.speed + delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); - if ( controls.moveBackward ) this.speed = THREE.Math.clamp( this.speed - delta * this.backAcceleration, this.maxReverseSpeed, this.maxSpeed ); + if ( controls.moveForward ) this.speed = THREE.MathUtils.clamp( this.speed + delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); + if ( controls.moveBackward ) this.speed = THREE.MathUtils.clamp( this.speed - delta * this.backAcceleration, this.maxReverseSpeed, this.maxSpeed ); // orientation based on controls // (don't just stand while turning) @@ -462,14 +462,14 @@ THREE.MD2CharacterComplex = function () { if ( controls.moveLeft ) { this.bodyOrientation += delta * this.angularSpeed; - this.speed = THREE.Math.clamp( this.speed + dir * delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); + this.speed = THREE.MathUtils.clamp( this.speed + dir * delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); } if ( controls.moveRight ) { this.bodyOrientation -= delta * this.angularSpeed; - this.speed = THREE.Math.clamp( this.speed + dir * delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); + this.speed = THREE.MathUtils.clamp( this.speed + dir * delta * this.frontAcceleration, this.maxReverseSpeed, this.maxSpeed ); } @@ -480,12 +480,12 @@ THREE.MD2CharacterComplex = function () { if ( this.speed > 0 ) { var k = exponentialEaseOut( this.speed / this.maxSpeed ); - this.speed = THREE.Math.clamp( this.speed - k * delta * this.frontDecceleration, 0, this.maxSpeed ); + this.speed = THREE.MathUtils.clamp( this.speed - k * delta * this.frontDecceleration, 0, this.maxSpeed ); } else { var k = exponentialEaseOut( this.speed / this.maxReverseSpeed ); - this.speed = THREE.Math.clamp( this.speed + k * delta * this.backAcceleration, this.maxReverseSpeed, 0 ); + this.speed = THREE.MathUtils.clamp( this.speed + k * delta * this.backAcceleration, this.maxReverseSpeed, 0 ); } @@ -516,6 +516,7 @@ THREE.MD2CharacterComplex = function () { textures[ i ] = textureLoader.load( baseUrl + textureUrls[ i ], checkLoadingComplete ); textures[ i ].mapping = THREE.UVMapping; textures[ i ].name = textureUrls[ i ]; + textures[ i ].encoding = THREE.sRGBEncoding; } diff --git a/examples/js/misc/MorphBlendMesh.js b/examples/js/misc/MorphBlendMesh.js index f37d69491613e4..0b2445223270ba 100644 --- a/examples/js/misc/MorphBlendMesh.js +++ b/examples/js/misc/MorphBlendMesh.js @@ -282,7 +282,7 @@ THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.protot } - var keyframe = animation.start + THREE.Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 ); + var keyframe = animation.start + THREE.MathUtils.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 ); var weight = animation.weight; if ( keyframe !== animation.currentFrame ) { diff --git a/examples/js/misc/Ocean.js b/examples/js/misc/Ocean.js index 655aae9f351a54..e91bab84da6310 100644 --- a/examples/js/misc/Ocean.js +++ b/examples/js/misc/Ocean.js @@ -255,7 +255,6 @@ THREE.Ocean.prototype.generateSeedPhaseTexture = function () { this.pingPhaseTexture.wrapS = THREE.ClampToEdgeWrapping; this.pingPhaseTexture.wrapT = THREE.ClampToEdgeWrapping; this.pingPhaseTexture.type = THREE.FloatType; - this.pingPhaseTexture.needsUpdate = true; }; diff --git a/examples/js/misc/RollerCoaster.js b/examples/js/misc/RollerCoaster.js index cca0e72be8e162..d774ee3a0910b6 100644 --- a/examples/js/misc/RollerCoaster.js +++ b/examples/js/misc/RollerCoaster.js @@ -206,9 +206,9 @@ THREE.RollerCoasterGeometry = function ( curve, divisions ) { // console.log( vertices.length ); - this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); - this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) ); - this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) ); + this.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); + this.setAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) ); + this.setAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) ); }; @@ -381,8 +381,8 @@ THREE.RollerCoasterLiftersGeometry = function ( curve, divisions ) { } - this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); - this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) ); + this.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); + this.setAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) ); }; @@ -452,7 +452,7 @@ THREE.RollerCoasterShadowGeometry = function ( curve, divisions ) { } - this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); + this.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); }; @@ -483,7 +483,7 @@ THREE.SkyGeometry = function () { } - this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); + this.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); }; @@ -536,8 +536,8 @@ THREE.TreesGeometry = function ( landscape ) { } - this.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); - this.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) ); + this.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) ); + this.setAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) ); }; diff --git a/examples/js/misc/VolumeSlice.js b/examples/js/misc/VolumeSlice.js index 37d726db1a7f0a..907fc7ad9b850f 100644 --- a/examples/js/misc/VolumeSlice.js +++ b/examples/js/misc/VolumeSlice.js @@ -206,7 +206,7 @@ THREE.VolumeSlice.prototype = { this.mesh.geometry = this.geometry; //reset mesh matrix this.mesh.matrix.identity(); - this.mesh.applyMatrix( this.matrix ); + this.mesh.applyMatrix4( this.matrix ); } diff --git a/examples/js/modifiers/SimplifyModifier.js b/examples/js/modifiers/SimplifyModifier.js index 3e20c8d036c78b..61abfa79c2ad2b 100644 --- a/examples/js/modifiers/SimplifyModifier.js +++ b/examples/js/modifiers/SimplifyModifier.js @@ -484,7 +484,7 @@ THREE.SimplifyModifier = function () {}; // - simplifiedGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); + simplifiedGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) ); simplifiedGeometry.setIndex( index ); return simplifiedGeometry; diff --git a/examples/js/modifiers/SubdivisionModifier.js b/examples/js/modifiers/SubdivisionModifier.js index 1af8b0e687d410..df3592c13f81c7 100644 --- a/examples/js/modifiers/SubdivisionModifier.js +++ b/examples/js/modifiers/SubdivisionModifier.js @@ -167,9 +167,19 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { oldVertices = geometry.vertices; // { x, y, z} oldFaces = geometry.faces; // { a: oldVertex1, b: oldVertex2, c: oldVertex3 } - oldUvs = geometry.faceVertexUvs[ 0 ]; + oldUvs = geometry.faceVertexUvs; - var hasUvs = oldUvs !== undefined && oldUvs.length > 0; + var hasUvs = oldUvs[ 0 ] !== undefined && oldUvs[ 0 ].length > 0; + + if ( hasUvs ) { + + for ( var j = 0; j < oldUvs.length; j ++ ) { + + newUVs.push( [] ); + + } + + } /****************************************************** * @@ -368,21 +378,25 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { if ( hasUvs ) { - uv = oldUvs[ i ]; + for ( var j = 0; j < oldUvs.length; j ++ ) { + + uv = oldUvs[ j ][ i ]; - x0 = uv[ 0 ]; - x1 = uv[ 1 ]; - x2 = uv[ 2 ]; + x0 = uv[ 0 ]; + x1 = uv[ 1 ]; + x2 = uv[ 2 ]; - x3.set( midpoint( x0.x, x1.x ), midpoint( x0.y, x1.y ) ); - x4.set( midpoint( x1.x, x2.x ), midpoint( x1.y, x2.y ) ); - x5.set( midpoint( x0.x, x2.x ), midpoint( x0.y, x2.y ) ); + x3.set( midpoint( x0.x, x1.x ), midpoint( x0.y, x1.y ) ); + x4.set( midpoint( x1.x, x2.x ), midpoint( x1.y, x2.y ) ); + x5.set( midpoint( x0.x, x2.x ), midpoint( x0.y, x2.y ) ); - newUv( newUVs, x3, x4, x5 ); - newUv( newUVs, x0, x3, x5 ); + newUv( newUVs[ j ], x3, x4, x5 ); + newUv( newUVs[ j ], x0, x3, x5 ); - newUv( newUVs, x1, x4, x3 ); - newUv( newUVs, x2, x5, x4 ); + newUv( newUVs[ j ], x1, x4, x3 ); + newUv( newUVs[ j ], x2, x5, x4 ); + + } } @@ -391,7 +405,7 @@ THREE.SubdivisionModifier.prototype.modify = function ( geometry ) { // Overwrite old arrays geometry.vertices = newVertices; geometry.faces = newFaces; - if ( hasUvs ) geometry.faceVertexUvs[ 0 ] = newUVs; + if ( hasUvs ) geometry.faceVertexUvs = newUVs; // console.log('done'); diff --git a/examples/js/objects/Fire.js b/examples/js/objects/Fire.js index 057a6bdf64c436..8e5e0c2c51a929 100644 --- a/examples/js/objects/Fire.js +++ b/examples/js/objects/Fire.js @@ -145,8 +145,8 @@ THREE.Fire = function ( geometry, options ) { this.field0.background = new THREE.Color( 0x000000 ); - if ( ! THREE.Math.isPowerOfTwo( textureWidth ) || - ! THREE.Math.isPowerOfTwo( textureHeight ) ) { + if ( ! THREE.MathUtils.isPowerOfTwo( textureWidth ) || + ! THREE.MathUtils.isPowerOfTwo( textureHeight ) ) { this.field0.texture.generateMipmaps = false; this.field1.texture.generateMipmaps = false; @@ -319,7 +319,7 @@ THREE.Fire = function ( geometry, options ) { this.saveRenderState = function ( renderer ) { this.savedRenderTarget = renderer.getRenderTarget(); - this.savedVrEnabled = renderer.vr.enabled; + this.savedXrEnabled = renderer.xr.enabled; this.savedShadowAutoUpdate = renderer.shadowMap.autoUpdate; this.savedAntialias = renderer.antialias; this.savedToneMapping = renderer.toneMapping; @@ -328,7 +328,7 @@ THREE.Fire = function ( geometry, options ) { this.restoreRenderState = function ( renderer ) { - renderer.vr.enabled = this.savedVrEnabled; + renderer.xr.enabled = this.savedXrEnabled; renderer.shadowMap.autoUpdate = this.savedShadowAutoUpdate; renderer.setRenderTarget( this.savedRenderTarget ); renderer.antialias = this.savedAntialias; @@ -445,7 +445,7 @@ THREE.Fire = function ( geometry, options ) { this.saveRenderState( renderer ); - renderer.vr.enabled = false; // Avoid camera modification and recursion + renderer.xr.enabled = false; // Avoid camera modification and recursion renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows renderer.antialias = false; renderer.toneMapping = THREE.NoToneMapping; diff --git a/examples/js/objects/Lensflare.js b/examples/js/objects/Lensflare.js index 57a92cd36779ce..b86d0c2850f011 100644 --- a/examples/js/objects/Lensflare.js +++ b/examples/js/objects/Lensflare.js @@ -23,14 +23,12 @@ THREE.Lensflare = function () { tempMap.magFilter = THREE.NearestFilter; tempMap.wrapS = THREE.ClampToEdgeWrapping; tempMap.wrapT = THREE.ClampToEdgeWrapping; - tempMap.needsUpdate = true; var occlusionMap = new THREE.DataTexture( new Uint8Array( 16 * 16 * 3 ), 16, 16, THREE.RGBFormat ); occlusionMap.minFilter = THREE.NearestFilter; occlusionMap.magFilter = THREE.NearestFilter; occlusionMap.wrapS = THREE.ClampToEdgeWrapping; occlusionMap.wrapT = THREE.ClampToEdgeWrapping; - occlusionMap.needsUpdate = true; // material @@ -371,8 +369,8 @@ THREE.Lensflare.Geometry = ( function () { var interleavedBuffer = new THREE.InterleavedBuffer( float32Array, 5 ); geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); - geometry.addAttribute( 'position', new THREE.InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); - geometry.addAttribute( 'uv', new THREE.InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + geometry.setAttribute( 'position', new THREE.InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); + geometry.setAttribute( 'uv', new THREE.InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); return geometry; diff --git a/examples/js/objects/LightningStorm.js b/examples/js/objects/LightningStorm.js index a6a22ebe5fa06c..9339e57cdfb847 100644 --- a/examples/js/objects/LightningStorm.js +++ b/examples/js/objects/LightningStorm.js @@ -84,7 +84,7 @@ THREE.LightningStorm = function ( stormParams ) { dest.set( ( Math.random() - 0.5 ) * stormParams.size, 0, ( Math.random() - 0.5 ) * stormParams.size ); - var height = THREE.Math.lerp( stormParams.minHeight, stormParams.maxHeight, Math.random() ); + var height = THREE.MathUtils.lerp( stormParams.minHeight, stormParams.maxHeight, Math.random() ); source.set( stormParams.maxSlope * ( 2 * Math.random() - 1 ), 1, stormParams.maxSlope * ( 2 * Math.random() - 1 ) ).multiplyScalar( height ).add( dest ); @@ -137,7 +137,7 @@ THREE.LightningStorm.prototype.update = function ( time ) { var lightningParams1 = THREE.LightningStrike.copyParameters( lightningMesh.geometry.rayParameters, this.lightningParameters ); lightningParams1.birthTime = time; - lightningParams1.deathTime = time + THREE.Math.lerp( this.stormParams.lightningMinDuration, this.stormParams.lightningMaxDuration, Math.random() ); + lightningParams1.deathTime = time + THREE.MathUtils.lerp( this.stormParams.lightningMinDuration, this.stormParams.lightningMaxDuration, Math.random() ); this.onRayPosition( lightningParams1.sourceOffset, lightningParams1.destOffset ); @@ -200,7 +200,7 @@ THREE.LightningStorm.prototype.update = function ( time ) { THREE.LightningStorm.prototype.getNextLightningTime = function ( currentTime ) { - return currentTime + THREE.Math.lerp( this.stormParams.lightningMinPeriod, this.stormParams.lightningMaxPeriod, Math.random() ) / ( this.stormParams.maxLightnings + 1 ); + return currentTime + THREE.MathUtils.lerp( this.stormParams.lightningMinPeriod, this.stormParams.lightningMaxPeriod, Math.random() ) / ( this.stormParams.maxLightnings + 1 ); }; diff --git a/examples/js/objects/MarchingCubes.js b/examples/js/objects/MarchingCubes.js index 8d3b6bf18ea040..bc8a4a2d0f068d 100644 --- a/examples/js/objects/MarchingCubes.js +++ b/examples/js/objects/MarchingCubes.js @@ -954,13 +954,13 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors ) this.render( geo_callback ); if ( this.hasPositions ) - geo.addAttribute( "position", new THREE.BufferAttribute( posArray, 3 ) ); + geo.setAttribute( "position", new THREE.BufferAttribute( posArray, 3 ) ); if ( this.hasNormals ) - geo.addAttribute( "normal", new THREE.BufferAttribute( normArray, 3 ) ); + geo.setAttribute( "normal", new THREE.BufferAttribute( normArray, 3 ) ); if ( this.hasColors ) - geo.addAttribute( "color", new THREE.BufferAttribute( colorArray, 3 ) ); + geo.setAttribute( "color", new THREE.BufferAttribute( colorArray, 3 ) ); if ( this.hasUvs ) - geo.addAttribute( "uv", new THREE.BufferAttribute( uvArray, 2 ) ); + geo.setAttribute( "uv", new THREE.BufferAttribute( uvArray, 2 ) ); return geo; diff --git a/examples/js/objects/Reflector.js b/examples/js/objects/Reflector.js index 47fdc2bd10fd75..ba593e347295b8 100644 --- a/examples/js/objects/Reflector.js +++ b/examples/js/objects/Reflector.js @@ -18,6 +18,7 @@ THREE.Reflector = function ( geometry, options ) { var clipBias = options.clipBias || 0; var shader = options.shader || THREE.Reflector.ReflectorShader; var recursion = options.recursion !== undefined ? options.recursion : 0; + var encoding = options.encoding !== undefined ? options.encoding : THREE.LinearEncoding; // @@ -40,12 +41,13 @@ THREE.Reflector = function ( geometry, options ) { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, - stencilBuffer: false + stencilBuffer: false, + encoding: encoding }; var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters ); - if ( ! THREE.Math.isPowerOfTwo( textureWidth ) || ! THREE.Math.isPowerOfTwo( textureHeight ) ) { + if ( ! THREE.MathUtils.isPowerOfTwo( textureWidth ) || ! THREE.MathUtils.isPowerOfTwo( textureHeight ) ) { renderTarget.texture.generateMipmaps = false; @@ -153,17 +155,17 @@ THREE.Reflector = function ( geometry, options ) { var currentRenderTarget = renderer.getRenderTarget(); - var currentVrEnabled = renderer.vr.enabled; + var currentXrEnabled = renderer.xr.enabled; var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; - renderer.vr.enabled = false; // Avoid camera modification and recursion + renderer.xr.enabled = false; // Avoid camera modification and recursion renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows renderer.setRenderTarget( renderTarget ); renderer.clear(); renderer.render( scene, virtualCamera ); - renderer.vr.enabled = currentVrEnabled; + renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; renderer.setRenderTarget( currentRenderTarget ); diff --git a/examples/js/objects/Refractor.js b/examples/js/objects/Refractor.js index 37bc9661fcc8c4..32ac0941bd68a6 100644 --- a/examples/js/objects/Refractor.js +++ b/examples/js/objects/Refractor.js @@ -18,6 +18,7 @@ THREE.Refractor = function ( geometry, options ) { var textureHeight = options.textureHeight || 512; var clipBias = options.clipBias || 0; var shader = options.shader || THREE.Refractor.RefractorShader; + var encoding = options.encoding !== undefined ? options.encoding : THREE.LinearEncoding; // @@ -36,12 +37,13 @@ THREE.Refractor = function ( geometry, options ) { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, - stencilBuffer: false + stencilBuffer: false, + encoding: encoding }; var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters ); - if ( ! THREE.Math.isPowerOfTwo( textureWidth ) || ! THREE.Math.isPowerOfTwo( textureHeight ) ) { + if ( ! THREE.MathUtils.isPowerOfTwo( textureWidth ) || ! THREE.MathUtils.isPowerOfTwo( textureHeight ) ) { renderTarget.texture.generateMipmaps = false; @@ -189,17 +191,17 @@ THREE.Refractor = function ( geometry, options ) { scope.visible = false; var currentRenderTarget = renderer.getRenderTarget(); - var currentVrEnabled = renderer.vr.enabled; + var currentXrEnabled = renderer.xr.enabled; var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; - renderer.vr.enabled = false; // avoid camera modification + renderer.xr.enabled = false; // avoid camera modification renderer.shadowMap.autoUpdate = false; // avoid re-computing shadows renderer.setRenderTarget( renderTarget ); renderer.clear(); renderer.render( scene, virtualCamera ); - renderer.vr.enabled = currentVrEnabled; + renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; renderer.setRenderTarget( currentRenderTarget ); diff --git a/examples/js/objects/Water.js b/examples/js/objects/Water.js index 9a298ec95932d6..336110d647e1f2 100644 --- a/examples/js/objects/Water.js +++ b/examples/js/objects/Water.js @@ -57,7 +57,7 @@ THREE.Water = function ( geometry, options ) { var renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight, parameters ); - if ( ! THREE.Math.isPowerOfTwo( textureWidth ) || ! THREE.Math.isPowerOfTwo( textureHeight ) ) { + if ( ! THREE.MathUtils.isPowerOfTwo( textureWidth ) || ! THREE.MathUtils.isPowerOfTwo( textureHeight ) ) { renderTarget.texture.generateMipmaps = false; @@ -184,7 +184,6 @@ THREE.Water = function ( geometry, options ) { fragmentShader: mirrorShader.fragmentShader, vertexShader: mirrorShader.vertexShader, uniforms: THREE.UniformsUtils.clone( mirrorShader.uniforms ), - transparent: true, lights: true, side: side, fog: fog @@ -283,12 +282,12 @@ THREE.Water = function ( geometry, options ) { var currentRenderTarget = renderer.getRenderTarget(); - var currentVrEnabled = renderer.vr.enabled; + var currentXrEnabled = renderer.xr.enabled; var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate; scope.visible = false; - renderer.vr.enabled = false; // Avoid camera modification and recursion + renderer.xr.enabled = false; // Avoid camera modification and recursion renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows renderer.setRenderTarget( renderTarget ); @@ -297,11 +296,21 @@ THREE.Water = function ( geometry, options ) { scope.visible = true; - renderer.vr.enabled = currentVrEnabled; + renderer.xr.enabled = currentXrEnabled; renderer.shadowMap.autoUpdate = currentShadowAutoUpdate; renderer.setRenderTarget( currentRenderTarget ); + // Restore viewport + + var viewport = camera.viewport; + + if ( viewport !== undefined ) { + + renderer.state.viewport( viewport ); + + } + }; }; diff --git a/examples/js/offscreen/jank.js b/examples/js/offscreen/jank.js deleted file mode 100644 index e2a0528f2008c1..00000000000000 --- a/examples/js/offscreen/jank.js +++ /dev/null @@ -1,38 +0,0 @@ -var interval = null; - -var button = document.getElementById( 'button' ); -button.addEventListener( 'click', function () { - - if ( interval === null ) { - - interval = setInterval( jank, 1000 / 60 ); - - button.textContent = 'STOP JANK'; - - } else { - - clearInterval( interval ); - interval = null; - - button.textContent = 'START JANK'; - result.textContent = ''; - - } - -} ); - -var result = document.getElementById( 'result' ); - -function jank() { - - var number = 0; - - for ( var i = 0; i < 10000000; i ++ ) { - - number += Math.random(); - - } - - result.textContent = number; - -} diff --git a/examples/js/pmrem/PMREMCubeUVPacker.js b/examples/js/pmrem/PMREMCubeUVPacker.js deleted file mode 100644 index 1fe2523fa032d7..00000000000000 --- a/examples/js/pmrem/PMREMCubeUVPacker.js +++ /dev/null @@ -1,233 +0,0 @@ -/** - * @author Prashant Sharma / spidersharma03 - * @author Ben Houston / bhouston, https://clara.io - * - * This class takes the cube lods(corresponding to different roughness values), and creates a single cubeUV - * Texture. The format for a given roughness set of faces is simply:: - * +X+Y+Z - * -X-Y-Z - * For every roughness a mip map chain is also saved, which is essential to remove the texture artifacts due to - * minification. - * Right now for every face a PlaneMesh is drawn, which leads to a lot of geometry draw calls, but can be replaced - * later by drawing a single buffer and by sending the appropriate faceIndex via vertex attributes. - * The arrangement of the faces is fixed, as assuming this arrangement, the sampling function has been written. - */ - -THREE.PMREMCubeUVPacker = ( function () { - - var camera = new THREE.OrthographicCamera(); - var scene = new THREE.Scene(); - var shader = getShader(); - - var PMREMCubeUVPacker = function ( cubeTextureLods ) { - - this.cubeLods = cubeTextureLods; - var size = cubeTextureLods[ 0 ].width * 4; - - var sourceTexture = cubeTextureLods[ 0 ].texture; - var params = { - format: sourceTexture.format, - magFilter: sourceTexture.magFilter, - minFilter: sourceTexture.minFilter, - type: sourceTexture.type, - generateMipmaps: sourceTexture.generateMipmaps, - anisotropy: sourceTexture.anisotropy, - encoding: ( sourceTexture.encoding === THREE.RGBEEncoding ) ? THREE.RGBM16Encoding : sourceTexture.encoding - }; - - if ( params.encoding === THREE.RGBM16Encoding ) { - - params.magFilter = THREE.LinearFilter; - params.minFilter = THREE.LinearFilter; - - } - - this.CubeUVRenderTarget = new THREE.WebGLRenderTarget( size, size, params ); - this.CubeUVRenderTarget.texture.name = "PMREMCubeUVPacker.cubeUv"; - this.CubeUVRenderTarget.texture.mapping = THREE.CubeUVReflectionMapping; - - this.objects = []; - - var geometry = new THREE.PlaneBufferGeometry( 1, 1 ); - - var faceOffsets = []; - faceOffsets.push( new THREE.Vector2( 0, 0 ) ); - faceOffsets.push( new THREE.Vector2( 1, 0 ) ); - faceOffsets.push( new THREE.Vector2( 2, 0 ) ); - faceOffsets.push( new THREE.Vector2( 0, 1 ) ); - faceOffsets.push( new THREE.Vector2( 1, 1 ) ); - faceOffsets.push( new THREE.Vector2( 2, 1 ) ); - - var textureResolution = size; - size = cubeTextureLods[ 0 ].width; - - var offset2 = 0; - var c = 4.0; - this.numLods = Math.log( cubeTextureLods[ 0 ].width ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2 - for ( var i = 0; i < this.numLods; i ++ ) { - - var offset1 = ( textureResolution - textureResolution / c ) * 0.5; - if ( size > 16 ) c *= 2; - var nMips = size > 16 ? 6 : 1; - var mipOffsetX = 0; - var mipOffsetY = 0; - var mipSize = size; - - for ( var j = 0; j < nMips; j ++ ) { - - // Mip Maps - for ( var k = 0; k < 6; k ++ ) { - - // 6 Cube Faces - var material = shader.clone(); - material.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture; - material.envMap = this.cubeLods[ i ].texture; - material.uniforms[ 'faceIndex' ].value = k; - material.uniforms[ 'mapSize' ].value = mipSize; - - var planeMesh = new THREE.Mesh( geometry, material ); - planeMesh.position.x = faceOffsets[ k ].x * mipSize - offset1 + mipOffsetX; - planeMesh.position.y = faceOffsets[ k ].y * mipSize - offset1 + offset2 + mipOffsetY; - planeMesh.material.side = THREE.BackSide; - planeMesh.scale.setScalar( mipSize ); - this.objects.push( planeMesh ); - - } - mipOffsetY += 1.75 * mipSize; - mipOffsetX += 1.25 * mipSize; - mipSize /= 2; - - } - offset2 += 2 * size; - if ( size > 16 ) size /= 2; - - } - - }; - - PMREMCubeUVPacker.prototype = { - - constructor: PMREMCubeUVPacker, - - update: function ( renderer ) { - - var size = this.cubeLods[ 0 ].width * 4; - // top and bottom are swapped for some reason? - camera.left = - size * 0.5; - camera.right = size * 0.5; - camera.top = - size * 0.5; - camera.bottom = size * 0.5; - camera.near = 0; - camera.far = 1; - camera.updateProjectionMatrix(); - - for ( var i = 0; i < this.objects.length; i ++ ) { - - scene.add( this.objects[ i ] ); - - } - - var gammaInput = renderer.gammaInput; - var gammaOutput = renderer.gammaOutput; - var toneMapping = renderer.toneMapping; - var toneMappingExposure = renderer.toneMappingExposure; - var currentRenderTarget = renderer.getRenderTarget(); - - renderer.gammaInput = false; - renderer.gammaOutput = false; - renderer.toneMapping = THREE.LinearToneMapping; - renderer.toneMappingExposure = 1.0; - renderer.setRenderTarget( this.CubeUVRenderTarget ); - renderer.render( scene, camera ); - - renderer.setRenderTarget( currentRenderTarget ); - renderer.toneMapping = toneMapping; - renderer.toneMappingExposure = toneMappingExposure; - renderer.gammaInput = gammaInput; - renderer.gammaOutput = gammaOutput; - - for ( var i = 0; i < this.objects.length; i ++ ) { - - scene.remove( this.objects[ i ] ); - - } - - }, - - dispose: function () { - - for ( var i = 0, l = this.objects.length; i < l; i ++ ) { - - this.objects[ i ].material.dispose(); - - } - - this.objects[ 0 ].geometry.dispose(); - - } - - }; - - function getShader() { - - var shaderMaterial = new THREE.ShaderMaterial( { - - uniforms: { - "faceIndex": { value: 0 }, - "mapSize": { value: 0 }, - "envMap": { value: null }, - "testColor": { value: new THREE.Vector3( 1, 1, 1 ) } - }, - - vertexShader: - "precision highp float;\ - varying vec2 vUv;\ - void main() {\ - vUv = uv;\ - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\ - }", - - fragmentShader: - "precision highp float;\ - varying vec2 vUv;\ - uniform samplerCube envMap;\ - uniform float mapSize;\ - uniform vec3 testColor;\ - uniform int faceIndex;\ - \ - void main() {\ - vec3 sampleDirection;\ - vec2 uv = vUv;\ - uv = uv * 2.0 - 1.0;\ - uv.y *= -1.0;\ - if(faceIndex == 0) {\ - sampleDirection = normalize(vec3(1.0, uv.y, -uv.x));\ - } else if(faceIndex == 1) {\ - sampleDirection = normalize(vec3(uv.x, 1.0, uv.y));\ - } else if(faceIndex == 2) {\ - sampleDirection = normalize(vec3(uv.x, uv.y, 1.0));\ - } else if(faceIndex == 3) {\ - sampleDirection = normalize(vec3(-1.0, uv.y, uv.x));\ - } else if(faceIndex == 4) {\ - sampleDirection = normalize(vec3(uv.x, -1.0, -uv.y));\ - } else {\ - sampleDirection = normalize(vec3(-uv.x, uv.y, -1.0));\ - }\ - vec4 color = envMapTexelToLinear( textureCube( envMap, sampleDirection ) );\ - gl_FragColor = linearToOutputTexel( color );\ - }", - - blending: THREE.NoBlending - - } ); - - shaderMaterial.type = 'PMREMCubeUVPacker'; - - return shaderMaterial; - - } - - - return PMREMCubeUVPacker; - -} )(); diff --git a/examples/js/pmrem/PMREMGenerator.js b/examples/js/pmrem/PMREMGenerator.js deleted file mode 100644 index 8fcc3a41280124..00000000000000 --- a/examples/js/pmrem/PMREMGenerator.js +++ /dev/null @@ -1,291 +0,0 @@ -/** - * @author Prashant Sharma / spidersharma03 - * @author Ben Houston / bhouston, https://clara.io - * - * To avoid cube map seams, I create an extra pixel around each face. This way when the cube map is - * sampled by an application later(with a little care by sampling the centre of the texel), the extra 1 border - * of pixels makes sure that there is no seams artifacts present. This works perfectly for cubeUV format as - * well where the 6 faces can be arranged in any manner whatsoever. - * Code in the beginning of fragment shader's main function does this job for a given resolution. - * Run Scene_PMREM_Test.html in the examples directory to see the sampling from the cube lods generated - * by this class. - */ - -THREE.PMREMGenerator = ( function () { - - var shader = getShader(); - var camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0.0, 1000 ); - var scene = new THREE.Scene(); - var planeMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2, 0 ), shader ); - planeMesh.material.side = THREE.DoubleSide; - scene.add( planeMesh ); - scene.add( camera ); - - var PMREMGenerator = function ( sourceTexture, samplesPerLevel, resolution ) { - - this.sourceTexture = sourceTexture; - this.resolution = ( resolution !== undefined ) ? resolution : 256; // NODE: 256 is currently hard coded in the glsl code for performance reasons - this.samplesPerLevel = ( samplesPerLevel !== undefined ) ? samplesPerLevel : 32; - - var monotonicEncoding = ( this.sourceTexture.encoding === THREE.LinearEncoding ) || - ( this.sourceTexture.encoding === THREE.GammaEncoding ) || ( this.sourceTexture.encoding === THREE.sRGBEncoding ); - - this.sourceTexture.minFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter; - this.sourceTexture.magFilter = ( monotonicEncoding ) ? THREE.LinearFilter : THREE.NearestFilter; - this.sourceTexture.generateMipmaps = this.sourceTexture.generateMipmaps && monotonicEncoding; - - this.cubeLods = []; - - var size = this.resolution; - var params = { - format: this.sourceTexture.format, - magFilter: this.sourceTexture.magFilter, - minFilter: this.sourceTexture.minFilter, - type: this.sourceTexture.type, - generateMipmaps: this.sourceTexture.generateMipmaps, - anisotropy: this.sourceTexture.anisotropy, - encoding: this.sourceTexture.encoding - }; - - // how many LODs fit in the given CubeUV Texture. - this.numLods = Math.log( size ) / Math.log( 2 ) - 2; // IE11 doesn't support Math.log2 - - for ( var i = 0; i < this.numLods; i ++ ) { - - var renderTarget = new THREE.WebGLRenderTargetCube( size, size, params ); - renderTarget.texture.name = "PMREMGenerator.cube" + i; - this.cubeLods.push( renderTarget ); - size = Math.max( 16, size / 2 ); - - } - - }; - - PMREMGenerator.prototype = { - - constructor: PMREMGenerator, - - /* - * Prashant Sharma / spidersharma03: More thought and work is needed here. - * Right now it's a kind of a hack to use the previously convolved map to convolve the current one. - * I tried to use the original map to convolve all the lods, but for many textures(specially the high frequency) - * even a high number of samples(1024) dosen't lead to satisfactory results. - * By using the previous convolved maps, a lower number of samples are generally sufficient(right now 32, which - * gives okay results unless we see the reflection very carefully, or zoom in too much), however the math - * goes wrong as the distribution function tries to sample a larger area than what it should be. So I simply scaled - * the roughness by 0.9(totally empirical) to try to visually match the original result. - * The condition "if(i <5)" is also an attemt to make the result match the original result. - * This method requires the most amount of thinking I guess. Here is a paper which we could try to implement in future:: - * https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html - */ - update: function ( renderer ) { - - // Texture should only be flipped for CubeTexture, not for - // a Texture created via THREE.WebGLRenderTargetCube. - var tFlip = ( this.sourceTexture.isCubeTexture ) ? - 1 : 1; - - shader.defines[ 'SAMPLES_PER_LEVEL' ] = this.samplesPerLevel; - shader.uniforms[ 'faceIndex' ].value = 0; - shader.uniforms[ 'envMap' ].value = this.sourceTexture; - shader.envMap = this.sourceTexture; - shader.needsUpdate = true; - - var gammaInput = renderer.gammaInput; - var gammaOutput = renderer.gammaOutput; - var toneMapping = renderer.toneMapping; - var toneMappingExposure = renderer.toneMappingExposure; - var currentRenderTarget = renderer.getRenderTarget(); - - renderer.toneMapping = THREE.LinearToneMapping; - renderer.toneMappingExposure = 1.0; - renderer.gammaInput = false; - renderer.gammaOutput = false; - - for ( var i = 0; i < this.numLods; i ++ ) { - - var r = i / ( this.numLods - 1 ); - shader.uniforms[ 'roughness' ].value = r * 0.9; // see comment above, pragmatic choice - // Only apply the tFlip for the first LOD - shader.uniforms[ 'tFlip' ].value = ( i == 0 ) ? tFlip : 1; - var size = this.cubeLods[ i ].width; - shader.uniforms[ 'mapSize' ].value = size; - this.renderToCubeMapTarget( renderer, this.cubeLods[ i ] ); - - if ( i < 5 ) shader.uniforms[ 'envMap' ].value = this.cubeLods[ i ].texture; - - } - - renderer.setRenderTarget( currentRenderTarget ); - renderer.toneMapping = toneMapping; - renderer.toneMappingExposure = toneMappingExposure; - renderer.gammaInput = gammaInput; - renderer.gammaOutput = gammaOutput; - - }, - - renderToCubeMapTarget: function ( renderer, renderTarget ) { - - for ( var i = 0; i < 6; i ++ ) { - - this.renderToCubeMapTargetFace( renderer, renderTarget, i ); - - } - - }, - - renderToCubeMapTargetFace: function ( renderer, renderTarget, faceIndex ) { - - shader.uniforms[ 'faceIndex' ].value = faceIndex; - renderer.setRenderTarget( renderTarget, faceIndex ); - renderer.clear(); - renderer.render( scene, camera ); - - }, - - dispose: function () { - - for ( var i = 0, l = this.cubeLods.length; i < l; i ++ ) { - - this.cubeLods[ i ].dispose(); - - } - - }, - - }; - - function getShader() { - - var shaderMaterial = new THREE.ShaderMaterial( { - - defines: { - "SAMPLES_PER_LEVEL": 20, - }, - - uniforms: { - "faceIndex": { value: 0 }, - "roughness": { value: 0.5 }, - "mapSize": { value: 0.5 }, - "envMap": { value: null }, - "tFlip": { value: - 1 }, - }, - - vertexShader: - "varying vec2 vUv;\n\ - void main() {\n\ - vUv = uv;\n\ - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\ - }", - - fragmentShader: - "#include \n\ - varying vec2 vUv;\n\ - uniform int faceIndex;\n\ - uniform float roughness;\n\ - uniform samplerCube envMap;\n\ - uniform float mapSize;\n\ - uniform float tFlip;\n\ - \n\ - float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\ - float a = ggxRoughness + 0.0001;\n\ - a *= a;\n\ - return ( 2.0 / a - 2.0 );\n\ - }\n\ - vec3 ImportanceSamplePhong(vec2 uv, mat3 vecSpace, float specPow) {\n\ - float phi = uv.y * 2.0 * PI;\n\ - float cosTheta = pow(1.0 - uv.x, 1.0 / (specPow + 1.0));\n\ - float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n\ - vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);\n\ - return vecSpace * sampleDir;\n\ - }\n\ - vec3 ImportanceSampleGGX( vec2 uv, mat3 vecSpace, float Roughness )\n\ - {\n\ - float a = Roughness * Roughness;\n\ - float Phi = 2.0 * PI * uv.x;\n\ - float CosTheta = sqrt( (1.0 - uv.y) / ( 1.0 + (a*a - 1.0) * uv.y ) );\n\ - float SinTheta = sqrt( 1.0 - CosTheta * CosTheta );\n\ - return vecSpace * vec3(SinTheta * cos( Phi ), SinTheta * sin( Phi ), CosTheta);\n\ - }\n\ - mat3 matrixFromVector(vec3 n) {\n\ - float a = 1.0 / (1.0 + n.z);\n\ - float b = -n.x * n.y * a;\n\ - vec3 b1 = vec3(1.0 - n.x * n.x * a, b, -n.x);\n\ - vec3 b2 = vec3(b, 1.0 - n.y * n.y * a, -n.y);\n\ - return mat3(b1, b2, n);\n\ - }\n\ - \n\ - vec4 testColorMap(float Roughness) {\n\ - vec4 color;\n\ - if(faceIndex == 0)\n\ - color = vec4(1.0,0.0,0.0,1.0);\n\ - else if(faceIndex == 1)\n\ - color = vec4(0.0,1.0,0.0,1.0);\n\ - else if(faceIndex == 2)\n\ - color = vec4(0.0,0.0,1.0,1.0);\n\ - else if(faceIndex == 3)\n\ - color = vec4(1.0,1.0,0.0,1.0);\n\ - else if(faceIndex == 4)\n\ - color = vec4(0.0,1.0,1.0,1.0);\n\ - else\n\ - color = vec4(1.0,0.0,1.0,1.0);\n\ - color *= ( 1.0 - Roughness );\n\ - return color;\n\ - }\n\ - void main() {\n\ - vec3 sampleDirection;\n\ - vec2 uv = vUv*2.0 - 1.0;\n\ - float offset = -1.0/mapSize;\n\ - const float a = -1.0;\n\ - const float b = 1.0;\n\ - float c = -1.0 + offset;\n\ - float d = 1.0 - offset;\n\ - float bminusa = b - a;\n\ - uv.x = (uv.x - a)/bminusa * d - (uv.x - b)/bminusa * c;\n\ - uv.y = (uv.y - a)/bminusa * d - (uv.y - b)/bminusa * c;\n\ - if (faceIndex==0) {\n\ - sampleDirection = vec3(1.0, -uv.y, -uv.x);\n\ - } else if (faceIndex==1) {\n\ - sampleDirection = vec3(-1.0, -uv.y, uv.x);\n\ - } else if (faceIndex==2) {\n\ - sampleDirection = vec3(uv.x, 1.0, uv.y);\n\ - } else if (faceIndex==3) {\n\ - sampleDirection = vec3(uv.x, -1.0, -uv.y);\n\ - } else if (faceIndex==4) {\n\ - sampleDirection = vec3(uv.x, -uv.y, 1.0);\n\ - } else {\n\ - sampleDirection = vec3(-uv.x, -uv.y, -1.0);\n\ - }\n\ - vec3 correctedDirection = vec3( tFlip * sampleDirection.x, sampleDirection.yz );\n\ - mat3 vecSpace = matrixFromVector( normalize( correctedDirection ) );\n\ - vec3 rgbColor = vec3(0.0);\n\ - const int NumSamples = SAMPLES_PER_LEVEL;\n\ - vec3 vect;\n\ - float weight = 0.0;\n\ - for( int i = 0; i < NumSamples; i ++ ) {\n\ - float sini = sin(float(i));\n\ - float cosi = cos(float(i));\n\ - float r = rand(vec2(sini, cosi));\n\ - vect = ImportanceSampleGGX(vec2(float(i) / float(NumSamples), r), vecSpace, roughness);\n\ - float dotProd = dot(vect, normalize(sampleDirection));\n\ - weight += dotProd;\n\ - vec3 color = envMapTexelToLinear(textureCube(envMap, vect)).rgb;\n\ - rgbColor.rgb += color;\n\ - }\n\ - rgbColor /= float(NumSamples);\n\ - //rgbColor = testColorMap( roughness ).rgb;\n\ - gl_FragColor = linearToOutputTexel( vec4( rgbColor, 1.0 ) );\n\ - }", - - blending: THREE.NoBlending - - } ); - - shaderMaterial.type = 'PMREMGenerator'; - - return shaderMaterial; - - } - - return PMREMGenerator; - -} )(); diff --git a/examples/js/postprocessing/BokehPass.js b/examples/js/postprocessing/BokehPass.js index ec4917a2ee6dea..7702afe1e5b779 100644 --- a/examples/js/postprocessing/BokehPass.js +++ b/examples/js/postprocessing/BokehPass.js @@ -19,14 +19,12 @@ THREE.BokehPass = function ( scene, camera, params ) { var width = params.width || window.innerWidth || 1; var height = params.height || window.innerHeight || 1; - this.renderTargetColor = new THREE.WebGLRenderTarget( width, height, { - minFilter: THREE.LinearFilter, - magFilter: THREE.LinearFilter, - format: THREE.RGBFormat + this.renderTargetDepth = new THREE.WebGLRenderTarget( width, height, { + minFilter: THREE.NearestFilter, + magFilter: THREE.NearestFilter, + stencilBuffer: false } ); - this.renderTargetColor.texture.name = "BokehPass.color"; - this.renderTargetDepth = this.renderTargetColor.clone(); this.renderTargetDepth.texture.name = "BokehPass.depth"; // depth material diff --git a/examples/js/postprocessing/CubeTexturePass.js b/examples/js/postprocessing/CubeTexturePass.js index 0f16e2f20fc211..628cf9b7dd6cf7 100644 --- a/examples/js/postprocessing/CubeTexturePass.js +++ b/examples/js/postprocessing/CubeTexturePass.js @@ -23,6 +23,16 @@ THREE.CubeTexturePass = function ( camera, envMap, opacity ) { } ) ); + Object.defineProperty( this.cubeMesh.material, 'envMap', { + + get: function () { + + return this.uniforms.envMap.value; + + } + + } ); + this.envMap = envMap; this.opacity = ( opacity !== undefined ) ? opacity : 1.0; @@ -44,8 +54,8 @@ THREE.CubeTexturePass.prototype = Object.assign( Object.create( THREE.Pass.proto this.cubeCamera.projectionMatrix.copy( this.camera.projectionMatrix ); this.cubeCamera.quaternion.setFromRotationMatrix( this.camera.matrixWorld ); - this.cubeMesh.material.uniforms[ "tCube" ].value = this.envMap; - this.cubeMesh.material.uniforms[ "opacity" ].value = this.opacity; + this.cubeMesh.material.uniforms.envMap.value = this.envMap; + this.cubeMesh.material.uniforms.opacity.value = this.opacity; this.cubeMesh.material.transparent = ( this.opacity < 1.0 ); renderer.setRenderTarget( this.renderToScreen ? null : readBuffer ); diff --git a/examples/js/postprocessing/EffectComposer.js b/examples/js/postprocessing/EffectComposer.js index 9bde2dc68f7b18..7bd74d98688f1e 100644 --- a/examples/js/postprocessing/EffectComposer.js +++ b/examples/js/postprocessing/EffectComposer.js @@ -279,6 +279,12 @@ THREE.Pass.FullScreenQuad = ( function () { Object.assign( FullScreenQuad.prototype, { + dispose: function () { + + this._mesh.geometry.dispose(); + + }, + render: function ( renderer ) { renderer.render( this._mesh, camera ); diff --git a/examples/js/postprocessing/GlitchPass.js b/examples/js/postprocessing/GlitchPass.js index 7d10e2265f7b46..c5770582fe2b11 100644 --- a/examples/js/postprocessing/GlitchPass.js +++ b/examples/js/postprocessing/GlitchPass.js @@ -44,22 +44,22 @@ THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype if ( this.curF % this.randX == 0 || this.goWild == true ) { this.uniforms[ 'amount' ].value = Math.random() / 30; - this.uniforms[ 'angle' ].value = THREE.Math.randFloat( - Math.PI, Math.PI ); - this.uniforms[ 'seed_x' ].value = THREE.Math.randFloat( - 1, 1 ); - this.uniforms[ 'seed_y' ].value = THREE.Math.randFloat( - 1, 1 ); - this.uniforms[ 'distortion_x' ].value = THREE.Math.randFloat( 0, 1 ); - this.uniforms[ 'distortion_y' ].value = THREE.Math.randFloat( 0, 1 ); + this.uniforms[ 'angle' ].value = THREE.MathUtils.randFloat( - Math.PI, Math.PI ); + this.uniforms[ 'seed_x' ].value = THREE.MathUtils.randFloat( - 1, 1 ); + this.uniforms[ 'seed_y' ].value = THREE.MathUtils.randFloat( - 1, 1 ); + this.uniforms[ 'distortion_x' ].value = THREE.MathUtils.randFloat( 0, 1 ); + this.uniforms[ 'distortion_y' ].value = THREE.MathUtils.randFloat( 0, 1 ); this.curF = 0; this.generateTrigger(); } else if ( this.curF % this.randX < this.randX / 5 ) { this.uniforms[ 'amount' ].value = Math.random() / 90; - this.uniforms[ 'angle' ].value = THREE.Math.randFloat( - Math.PI, Math.PI ); - this.uniforms[ 'distortion_x' ].value = THREE.Math.randFloat( 0, 1 ); - this.uniforms[ 'distortion_y' ].value = THREE.Math.randFloat( 0, 1 ); - this.uniforms[ 'seed_x' ].value = THREE.Math.randFloat( - 0.3, 0.3 ); - this.uniforms[ 'seed_y' ].value = THREE.Math.randFloat( - 0.3, 0.3 ); + this.uniforms[ 'angle' ].value = THREE.MathUtils.randFloat( - Math.PI, Math.PI ); + this.uniforms[ 'distortion_x' ].value = THREE.MathUtils.randFloat( 0, 1 ); + this.uniforms[ 'distortion_y' ].value = THREE.MathUtils.randFloat( 0, 1 ); + this.uniforms[ 'seed_x' ].value = THREE.MathUtils.randFloat( - 0.3, 0.3 ); + this.uniforms[ 'seed_y' ].value = THREE.MathUtils.randFloat( - 0.3, 0.3 ); } else if ( this.goWild == false ) { @@ -86,7 +86,7 @@ THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype generateTrigger: function () { - this.randX = THREE.Math.randInt( 120, 240 ); + this.randX = THREE.MathUtils.randInt( 120, 240 ); }, @@ -97,16 +97,14 @@ THREE.GlitchPass.prototype = Object.assign( Object.create( THREE.Pass.prototype for ( var i = 0; i < length; i ++ ) { - var val = THREE.Math.randFloat( 0, 1 ); + var val = THREE.MathUtils.randFloat( 0, 1 ); data_arr[ i * 3 + 0 ] = val; data_arr[ i * 3 + 1 ] = val; data_arr[ i * 3 + 2 ] = val; } - var texture = new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType ); - texture.needsUpdate = true; - return texture; + return new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType ); } diff --git a/examples/js/postprocessing/OutlinePass.js b/examples/js/postprocessing/OutlinePass.js index 8c9fd452c7de37..31d95760c7a316 100644 --- a/examples/js/postprocessing/OutlinePass.js +++ b/examples/js/postprocessing/OutlinePass.js @@ -67,10 +67,10 @@ THREE.OutlinePass = function ( resolution, scene, camera, selectedObjects ) { var MAX_EDGE_GLOW = 4; this.separableBlurMaterial1 = this.getSeperableBlurMaterial( MAX_EDGE_THICKNESS ); - this.separableBlurMaterial1.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy ); + this.separableBlurMaterial1.uniforms[ "texSize" ].value.set( resx, resy ); this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = 1; this.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW ); - this.separableBlurMaterial2.uniforms[ "texSize" ].value = new THREE.Vector2( Math.round( resx / 2 ), Math.round( resy / 2 ) ); + this.separableBlurMaterial2.uniforms[ "texSize" ].value.set( Math.round( resx / 2 ), Math.round( resy / 2 ) ); this.separableBlurMaterial2.uniforms[ "kernelRadius" ].value = MAX_EDGE_GLOW; // Overlay material @@ -142,7 +142,7 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype this.renderTargetMaskDownSampleBuffer.setSize( resx, resy ); this.renderTargetBlurBuffer1.setSize( resx, resy ); this.renderTargetEdgeBuffer1.setSize( resx, resy ); - this.separableBlurMaterial1.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy ); + this.separableBlurMaterial1.uniforms[ "texSize" ].value.set( resx, resy ); resx = Math.round( resx / 2 ); resy = Math.round( resy / 2 ); @@ -150,7 +150,7 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype this.renderTargetBlurBuffer2.setSize( resx, resy ); this.renderTargetEdgeBuffer2.setSize( resx, resy ); - this.separableBlurMaterial2.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy ); + this.separableBlurMaterial2.uniforms[ "texSize" ].value.set( resx, resy ); }, @@ -285,7 +285,7 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype // Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects this.changeVisibilityOfNonSelectedObjects( false ); this.renderScene.overrideMaterial = this.prepareMaskMaterial; - this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value = new THREE.Vector2( this.renderCamera.near, this.renderCamera.far ); + this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value.set( this.renderCamera.near, this.renderCamera.far ); this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture; this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix; renderer.setRenderTarget( this.renderTargetMaskBuffer ); @@ -317,7 +317,7 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype // 3. Apply Edge Detection Pass this.fsQuad.material = this.edgeDetectionMaterial; this.edgeDetectionMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskDownSampleBuffer.texture; - this.edgeDetectionMaterial.uniforms[ "texSize" ].value = new THREE.Vector2( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height ); + this.edgeDetectionMaterial.uniforms[ "texSize" ].value.set( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height ); this.edgeDetectionMaterial.uniforms[ "visibleEdgeColor" ].value = this.tempPulseColor1; this.edgeDetectionMaterial.uniforms[ "hiddenEdgeColor" ].value = this.tempPulseColor2; renderer.setRenderTarget( this.renderTargetEdgeBuffer1 ); @@ -390,20 +390,28 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype uniforms: { "depthTexture": { value: null }, "cameraNearFar": { value: new THREE.Vector2( 0.5, 0.5 ) }, - "textureMatrix": { value: new THREE.Matrix4() } + "textureMatrix": { value: null } }, vertexShader: [ + '#include ', + '#include ', + 'varying vec4 projTexCoord;', 'varying vec4 vPosition;', 'uniform mat4 textureMatrix;', 'void main() {', - ' vPosition = modelViewMatrix * vec4( position, 1.0 );', + ' #include ', + ' #include ', + ' #include ', + ' #include ', + ' #include ', + + ' vPosition = mvPosition;', ' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', ' projTexCoord = textureMatrix * worldPosition;', - ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}' ].join( '\n' ), @@ -510,18 +518,18 @@ THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype void main() {\ vec2 invSize = 1.0 / texSize;\ float weightSum = gaussianPdf(0.0, kernelRadius);\ - vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;\ + vec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;\ vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);\ vec2 uvOffset = delta;\ for( int i = 1; i <= MAX_RADIUS; i ++ ) {\ float w = gaussianPdf(uvOffset.x, kernelRadius);\ - vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;\ - vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;\ + vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);\ + vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);\ diffuseSum += ((sample1 + sample2) * w);\ weightSum += (2.0 * w);\ uvOffset += delta;\ }\ - gl_FragColor = vec4(diffuseSum/weightSum, 1.0);\ + gl_FragColor = diffuseSum/weightSum;\ }" } ); diff --git a/examples/js/postprocessing/RenderPass.js b/examples/js/postprocessing/RenderPass.js index e159aaecf5a7df..921824e775d275 100644 --- a/examples/js/postprocessing/RenderPass.js +++ b/examples/js/postprocessing/RenderPass.js @@ -29,9 +29,15 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype var oldAutoClear = renderer.autoClear; renderer.autoClear = false; - this.scene.overrideMaterial = this.overrideMaterial; + var oldClearColor, oldClearAlpha, oldOverrideMaterial; - var oldClearColor, oldClearAlpha; + if ( this.overrideMaterial !== undefined ) { + + oldOverrideMaterial = this.scene.overrideMaterial; + + this.scene.overrideMaterial = this.overrideMaterial; + + } if ( this.clearColor ) { @@ -60,7 +66,12 @@ THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype } - this.scene.overrideMaterial = null; + if ( this.overrideMaterial !== undefined ) { + + this.scene.overrideMaterial = oldOverrideMaterial; + + } + renderer.autoClear = oldAutoClear; } diff --git a/examples/js/postprocessing/SSAOPass.js b/examples/js/postprocessing/SSAOPass.js index 116051cfa1ec17..155f22df3d6a1e 100644 --- a/examples/js/postprocessing/SSAOPass.js +++ b/examples/js/postprocessing/SSAOPass.js @@ -153,10 +153,6 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), this.ssaoRenderTarget.dispose(); this.blurRenderTarget.dispose(); - // dispose geometry - - this.quad.geometry.dispose(); - // dispose materials this.normalMaterial.dispose(); @@ -164,6 +160,10 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), this.copyMaterial.dispose(); this.depthRenderMaterial.dispose(); + // dipsose full screen quad + + this.fsQuad.dispose(); + }, render: function ( renderer, writeBuffer /*, readBuffer, deltaTime, maskActive */ ) { @@ -344,7 +344,7 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), sample.normalize(); var scale = i / kernelSize; - scale = THREE.Math.lerp( 0.1, 1, scale * scale ); + scale = THREE.MathUtils.lerp( 0.1, 1, scale * scale ); sample.multiplyScalar( scale ); kernel.push( sample ); @@ -388,7 +388,6 @@ THREE.SSAOPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), this.noiseTexture = new THREE.DataTexture( data, width, height, THREE.RGBAFormat, THREE.FloatType ); this.noiseTexture.wrapS = THREE.RepeatWrapping; this.noiseTexture.wrapT = THREE.RepeatWrapping; - this.noiseTexture.needsUpdate = true; } diff --git a/examples/js/postprocessing/UnrealBloomPass.js b/examples/js/postprocessing/UnrealBloomPass.js index 11a59b691735d8..00e46fc859918b 100644 --- a/examples/js/postprocessing/UnrealBloomPass.js +++ b/examples/js/postprocessing/UnrealBloomPass.js @@ -1,10 +1,16 @@ /** * @author spidersharma / http://eduperiment.com/ - * - * Inspired from Unreal Engine - * https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/ */ +/** + * UnrealBloomPass is inspired by the bloom pass of Unreal Engine. It creates a + * mip map chain of bloom textures and blurs them with different radii. Because + * of the weighted combination of mips, and because larger blurs are done on + * higher mips, this effect provides good quality and performance. + * + * Reference: + * - https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/ + */ THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) { THREE.Pass.call( this ); diff --git a/examples/js/renderers/CSS2DRenderer.js b/examples/js/renderers/CSS2DRenderer.js index 23568c190f69d3..111861ac3b2761 100644 --- a/examples/js/renderers/CSS2DRenderer.js +++ b/examples/js/renderers/CSS2DRenderer.js @@ -11,11 +11,15 @@ THREE.CSS2DObject = function ( element ) { this.addEventListener( 'removed', function () { - if ( this.element.parentNode !== null ) { + this.traverse( function ( object ) { - this.element.parentNode.removeChild( this.element ); + if ( object.element instanceof Element && object.element.parentNode !== null ) { - } + object.element.parentNode.removeChild( object.element ); + + } + + } ); } ); @@ -28,7 +32,7 @@ THREE.CSS2DObject.prototype.constructor = THREE.CSS2DObject; THREE.CSS2DRenderer = function () { - console.log( 'THREE.CSS2DRenderer', THREE.REVISION ); + var _this = this; var _width, _height; var _widthHalf, _heightHalf; @@ -68,10 +72,12 @@ THREE.CSS2DRenderer = function () { }; - var renderObject = function ( object, camera ) { + var renderObject = function ( object, scene, camera ) { if ( object instanceof THREE.CSS2DObject ) { + object.onBeforeRender( _this, scene, camera ); + vector.setFromMatrixPosition( object.matrixWorld ); vector.applyMatrix4( viewProjectionMatrix ); @@ -97,11 +103,13 @@ THREE.CSS2DRenderer = function () { } + object.onAfterRender( _this, scene, camera ); + } for ( var i = 0, l = object.children.length; i < l; i ++ ) { - renderObject( object.children[ i ], camera ); + renderObject( object.children[ i ], scene, camera ); } @@ -160,14 +168,13 @@ THREE.CSS2DRenderer = function () { this.render = function ( scene, camera ) { - scene.updateMatrixWorld(); - + if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); if ( camera.parent === null ) camera.updateMatrixWorld(); viewMatrix.copy( camera.matrixWorldInverse ); viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix ); - renderObject( scene, camera ); + renderObject( scene, scene, camera ); zOrder( scene ); }; diff --git a/examples/js/renderers/CSS3DRenderer.js b/examples/js/renderers/CSS3DRenderer.js index 40c06828c06ea4..04059675131075 100644 --- a/examples/js/renderers/CSS3DRenderer.js +++ b/examples/js/renderers/CSS3DRenderer.js @@ -10,14 +10,19 @@ THREE.CSS3DObject = function ( element ) { this.element = element; this.element.style.position = 'absolute'; + this.element.style.pointerEvents = 'auto'; this.addEventListener( 'removed', function () { - if ( this.element.parentNode !== null ) { + this.traverse( function ( object ) { - this.element.parentNode.removeChild( this.element ); + if ( object.element instanceof Element && object.element.parentNode !== null ) { - } + object.element.parentNode.removeChild( object.element ); + + } + + } ); } ); @@ -39,7 +44,7 @@ THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite; THREE.CSS3DRenderer = function () { - console.log( 'THREE.CSS3DRenderer', THREE.REVISION ); + var _this = this; var _width, _height; var _widthHalf, _heightHalf; @@ -60,6 +65,7 @@ THREE.CSS3DRenderer = function () { cameraElement.style.WebkitTransformStyle = 'preserve-3d'; cameraElement.style.transformStyle = 'preserve-3d'; + cameraElement.style.pointerEvents = 'none'; domElement.appendChild( cameraElement ); @@ -155,10 +161,12 @@ THREE.CSS3DRenderer = function () { } - function renderObject( object, camera, cameraCSSMatrix ) { + function renderObject( object, scene, camera, cameraCSSMatrix ) { if ( object instanceof THREE.CSS3DObject ) { + object.onBeforeRender( _this, scene, camera ); + var style; if ( object instanceof THREE.CSS3DSprite ) { @@ -209,11 +217,13 @@ THREE.CSS3DRenderer = function () { } + object.onAfterRender( _this, scene, camera ); + } for ( var i = 0, l = object.children.length; i < l; i ++ ) { - renderObject( object.children[ i ], camera, cameraCSSMatrix ); + renderObject( object.children[ i ], scene, camera, cameraCSSMatrix ); } @@ -281,14 +291,18 @@ THREE.CSS3DRenderer = function () { domElement.style.WebkitPerspective = fov + 'px'; domElement.style.perspective = fov + 'px'; + } else { + + domElement.style.WebkitPerspective = ''; + domElement.style.perspective = ''; + } cache.camera.fov = fov; } - scene.updateMatrixWorld(); - + if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); if ( camera.parent === null ) camera.updateMatrixWorld(); if ( camera.isOrthographicCamera ) { @@ -314,7 +328,7 @@ THREE.CSS3DRenderer = function () { } - renderObject( scene, camera, cameraCSSMatrix ); + renderObject( scene, scene, camera, cameraCSSMatrix ); if ( isIE ) { diff --git a/examples/js/renderers/Projector.js b/examples/js/renderers/Projector.js index 41a41c16657929..802079c2890ac8 100644 --- a/examples/js/renderers/Projector.js +++ b/examples/js/renderers/Projector.js @@ -157,14 +157,12 @@ THREE.Projector = function () { var uvs = []; var object = null; - var material = null; var normalMatrix = new THREE.Matrix3(); function setObject( value ) { object = value; - material = object.material; normalMatrix.getNormalMatrix( object.matrixWorld ); @@ -268,7 +266,7 @@ THREE.Projector = function () { _line.material = object.material; - if ( object.material.vertexColors === THREE.VertexColors ) { + if ( object.material.vertexColors ) { _line.vertexColors[ 0 ].fromArray( colors, a * 3 ); _line.vertexColors[ 1 ].fromArray( colors, b * 3 ); @@ -322,7 +320,7 @@ THREE.Projector = function () { _face.material = material; - if ( material.vertexColors === THREE.FaceColors || material.vertexColors === THREE.VertexColors ) { + if ( material.vertexColors ) { _face.color.fromArray( colors, a * 3 ); @@ -414,7 +412,7 @@ THREE.Projector = function () { _viewMatrix.copy( camera.matrixWorldInverse ); _viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix ); - _frustum.setFromMatrix( _viewProjectionMatrix ); + _frustum.setFromProjectionMatrix( _viewProjectionMatrix ); // @@ -470,6 +468,7 @@ THREE.Projector = function () { if ( material.morphTargets === true ) { var morphTargets = geometry.morphAttributes.position; + var morphTargetsRelative = geometry.morphTargetsRelative; var morphInfluences = object.morphTargetInfluences; for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { @@ -480,9 +479,19 @@ THREE.Projector = function () { var target = morphTargets[ t ]; - x += ( target.getX( i / 3 ) - positions[ i ] ) * influence; - y += ( target.getY( i / 3 ) - positions[ i + 1 ] ) * influence; - z += ( target.getZ( i / 3 ) - positions[ i + 2 ] ) * influence; + if ( morphTargetsRelative ) { + + x += target.getX( i / 3 ) * influence; + y += target.getY( i / 3 ) * influence; + z += target.getZ( i / 3 ) * influence; + + } else { + + x += ( target.getX( i / 3 ) - positions[ i ] ) * influence; + y += ( target.getY( i / 3 ) - positions[ i + 1 ] ) * influence; + z += ( target.getZ( i / 3 ) - positions[ i + 2 ] ) * influence; + + } } @@ -821,7 +830,7 @@ THREE.Projector = function () { _line.material = object.material; - if ( object.material.vertexColors === THREE.VertexColors ) { + if ( object.material.vertexColors ) { _line.vertexColors[ 0 ].copy( object.geometry.colors[ v ] ); _line.vertexColors[ 1 ].copy( object.geometry.colors[ v - 1 ] ); diff --git a/examples/js/renderers/RaytracingRenderer.js b/examples/js/renderers/RaytracingRenderer.js deleted file mode 100644 index ff215cdf015c24..00000000000000 --- a/examples/js/renderers/RaytracingRenderer.js +++ /dev/null @@ -1,286 +0,0 @@ -/** - * RaytracingRenderer renders by raytracing it's scene. However, it does not - * compute the pixels itself but it hands off and coordinates the tasks for workers. - * The workers compute the pixel values and this renderer simply paints it to the Canvas. - * - * @author zz85 / http://github.com/zz85 - */ - -THREE.RaytracingRenderer = function ( parameters ) { - - console.log( 'THREE.RaytracingRenderer', THREE.REVISION ); - - parameters = parameters || {}; - - var scope = this; - var pool = []; - var renderering = false; - - var canvas = document.createElement( 'canvas' ); - var context = canvas.getContext( '2d', { - alpha: parameters.alpha === true - } ); - - var canvasWidth, canvasHeight; - - var clearColor = new THREE.Color( 0x000000 ); - - this.domElement = canvas; - - this.autoClear = true; - - var workers = parameters.workers; - var blockSize = parameters.blockSize || 64; - this.randomize = parameters.randomize; - - var toRender = [], workerId = 0, sceneId = 0; - - console.log( '%cSpinning off ' + workers + ' Workers ', 'font-size: 20px; background: black; color: white; font-family: monospace;' ); - - this.setWorkers = function ( w ) { - - workers = w || navigator.hardwareConcurrency || 4; - - while ( pool.length < workers ) { - - var worker = new Worker( parameters.workerPath ); - worker.id = workerId ++; - - worker.onmessage = function ( e ) { - - var data = e.data; - - if ( ! data ) return; - - if ( data.blockSize && sceneId == data.sceneId ) { // we match sceneId here to be sure - - var imagedata = new ImageData( new Uint8ClampedArray( data.data ), data.blockSize, data.blockSize ); - context.putImageData( imagedata, data.blockX, data.blockY ); - - // completed - - console.log( 'Worker ' + this.id, data.time / 1000, ( Date.now() - reallyThen ) / 1000 + ' s' ); - - if ( pool.length > workers ) { - - pool.splice( pool.indexOf( this ), 1 ); - return this.terminate(); - - } - - renderNext( this ); - - } - - }; - - worker.color = new THREE.Color().setHSL( Math.random(), 0.8, 0.8 ).getHexString(); - pool.push( worker ); - - updateSettings( worker ); - - if ( renderering ) { - - worker.postMessage( { - scene: sceneJSON, - camera: cameraJSON, - annex: materials, - sceneId: sceneId - } ); - - renderNext( worker ); - - } - - } - - if ( ! renderering ) { - - while ( pool.length > workers ) { - - pool.pop().terminate(); - - } - - } - - }; - - this.setWorkers( workers ); - - this.setClearColor = function ( color /*, alpha */ ) { - - clearColor.set( color ); - - }; - - this.setPixelRatio = function () {}; - - this.setSize = function ( width, height ) { - - canvas.width = width; - canvas.height = height; - - canvasWidth = canvas.width; - canvasHeight = canvas.height; - - pool.forEach( updateSettings ); - - }; - - this.setSize( canvas.width, canvas.height ); - - this.clear = function () { - - }; - - // - - var totalBlocks, xblocks, yblocks; - - function updateSettings( worker ) { - - worker.postMessage( { - - init: [ canvasWidth, canvasHeight ], - worker: worker.id, - // workers: pool.length, - blockSize: blockSize - - } ); - - } - - function renderNext( worker ) { - - if ( ! toRender.length ) { - - renderering = false; - return scope.dispatchEvent( { type: "complete" } ); - - } - - var current = toRender.pop(); - - var blockX = ( current % xblocks ) * blockSize; - var blockY = ( current / xblocks | 0 ) * blockSize; - - worker.postMessage( { - render: true, - x: blockX, - y: blockY, - sceneId: sceneId - } ); - - context.fillStyle = '#' + worker.color; - context.fillRect( blockX, blockY, blockSize, blockSize ); - - } - - var materials = {}; - - var sceneJSON, cameraJSON, reallyThen; - - // additional properties that were not serialize automatically - - var _annex = { - - mirror: 1, - reflectivity: 1, - refractionRatio: 1, - glass: 1 - - }; - - function serializeObject( o ) { - - var mat = o.material; - - if ( ! mat || mat.uuid in materials ) return; - - var props = {}; - for ( var m in _annex ) { - - if ( mat[ m ] !== undefined ) { - - props[ m ] = mat[ m ]; - - } - - } - - materials[ mat.uuid ] = props; - - } - - this.render = function ( scene, camera ) { - - renderering = true; - - // update scene graph - - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - - // update camera matrices - - if ( camera.parent === null ) camera.updateMatrixWorld(); - - - sceneJSON = scene.toJSON(); - cameraJSON = camera.toJSON(); - ++ sceneId; - - scene.traverse( serializeObject ); - - pool.forEach( function ( worker ) { - - worker.postMessage( { - scene: sceneJSON, - camera: cameraJSON, - annex: materials, - sceneId: sceneId - } ); - - } ); - - context.fillStyle = clearColor.getStyle(); - context.fillRect( 0, 0, canvasWidth, canvasHeight ); - - reallyThen = Date.now(); - - xblocks = Math.ceil( canvasWidth / blockSize ); - yblocks = Math.ceil( canvasHeight / blockSize ); - totalBlocks = xblocks * yblocks; - - toRender = []; - - for ( var i = 0; i < totalBlocks; i ++ ) { - - toRender.push( i ); - - } - - - // Randomize painting :) - - if ( scope.randomize ) { - - for ( var i = 0; i < totalBlocks; i ++ ) { - - var swap = Math.random() * totalBlocks | 0; - var tmp = toRender[ swap ]; - toRender[ swap ] = toRender[ i ]; - toRender[ i ] = tmp; - - } - - } - - - pool.forEach( renderNext ); - - }; - -}; - -Object.assign( THREE.RaytracingRenderer.prototype, THREE.EventDispatcher.prototype ); diff --git a/examples/js/renderers/RaytracingWorker.js b/examples/js/renderers/RaytracingWorker.js deleted file mode 100644 index 831e02dc61ca36..00000000000000 --- a/examples/js/renderers/RaytracingWorker.js +++ /dev/null @@ -1,546 +0,0 @@ -var BLOCK = 128; -var startX, startY; - -var scene, camera, renderer, loader, sceneId; - -importScripts( '../../../build/three.js' ); - - -self.onmessage = function ( e ) { - - var data = e.data; - if ( ! data ) return; - - if ( data.init ) { - - var - width = data.init[ 0 ], - height = data.init[ 1 ]; - - BLOCK = data.blockSize; - - if ( ! renderer ) renderer = new THREE.RaytracingRendererWorker(); - if ( ! loader ) loader = new THREE.ObjectLoader(); - - renderer.setSize( width, height ); - - // TODO fix passing maxRecursionDepth as parameter. - // if (data.maxRecursionDepth) maxRecursionDepth = data.maxRecursionDepth; - - } - - if ( data.scene ) { - - scene = loader.parse( data.scene ); - camera = loader.parse( data.camera ); - - var meta = data.annex; - scene.traverse( function ( o ) { - - if ( o.isPointLight ) { - - o.physicalAttenuation = true; - - } - - var mat = o.material; - - if ( ! mat ) return; - - var material = meta[ mat.uuid ]; - - for ( var m in material ) { - - mat[ m ] = material[ m ]; - - } - - } ); - - sceneId = data.sceneId; - - } - - if ( data.render && scene && camera ) { - - startX = data.x; - startY = data.y; - renderer.render( scene, camera ); - - } - -}; - -/** - * DOM-less version of Raytracing Renderer - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author zz95 / http://github.com/zz85 - */ - -THREE.RaytracingRendererWorker = function () { - - console.log( 'THREE.RaytracingRendererWorker', THREE.REVISION ); - - var maxRecursionDepth = 3; - - var canvasWidth, canvasHeight; - var canvasWidthHalf, canvasHeightHalf; - var origin = new THREE.Vector3(); - var direction = new THREE.Vector3(); - - var cameraPosition = new THREE.Vector3(); - - var raycaster = new THREE.Raycaster( origin, direction ); - var ray = raycaster.ray; - - var raycasterLight = new THREE.Raycaster(); - var rayLight = raycasterLight.ray; - - var perspective; - var cameraNormalMatrix = new THREE.Matrix3(); - - var objects; - var lights = []; - var cache = {}; - - this.setSize = function ( width, height ) { - - canvasWidth = width; - canvasHeight = height; - - canvasWidthHalf = Math.floor( canvasWidth / 2 ); - canvasHeightHalf = Math.floor( canvasHeight / 2 ); - - }; - - // - - var spawnRay = ( function () { - - var diffuseColor = new THREE.Color(); - var specularColor = new THREE.Color(); - var lightColor = new THREE.Color(); - var schlick = new THREE.Color(); - - var lightContribution = new THREE.Color(); - - var eyeVector = new THREE.Vector3(); - var lightVector = new THREE.Vector3(); - var normalVector = new THREE.Vector3(); - var halfVector = new THREE.Vector3(); - - var localPoint = new THREE.Vector3(); - var reflectionVector = new THREE.Vector3(); - - var tmpVec = new THREE.Vector3(); - - var tmpColor = []; - - for ( var i = 0; i < maxRecursionDepth; i ++ ) { - - tmpColor[ i ] = new THREE.Color(); - - } - - return function spawnRay( rayOrigin, rayDirection, outputColor, recursionDepth ) { - - outputColor.setRGB( 0, 0, 0 ); - - // - - ray.origin = rayOrigin; - ray.direction = rayDirection; - - var intersections = raycaster.intersectObjects( objects, true ); - - // ray didn't find anything - // (here should come setting of background color?) - - if ( intersections.length === 0 ) return; - - // ray hit - - var intersection = intersections[ 0 ]; - - var point = intersection.point; - var object = intersection.object; - var material = object.material; - var face = intersection.face; - - var geometry = object.geometry; - - // - - var _object = cache[ object.id ]; - - eyeVector.subVectors( ray.origin, point ).normalize(); - - // resolve pixel diffuse color - - if ( material.isMeshLambertMaterial || - material.isMeshPhongMaterial || - material.isMeshBasicMaterial ) { - - diffuseColor.copyGammaToLinear( material.color ); - - } else { - - diffuseColor.setRGB( 1, 1, 1 ); - - } - - if ( material.vertexColors === THREE.FaceColors ) { - - diffuseColor.multiply( face.color ); - - } - - // compute light shading - - rayLight.origin.copy( point ); - - if ( material.isMeshBasicMaterial ) { - - for ( var i = 0, l = lights.length; i < l; i ++ ) { - - var light = lights[ i ]; - - lightVector.setFromMatrixPosition( light.matrixWorld ); - lightVector.sub( point ); - - rayLight.direction.copy( lightVector ).normalize(); - - var intersections = raycasterLight.intersectObjects( objects, true ); - - // point in shadow - - if ( intersections.length > 0 ) continue; - - // point visible - - outputColor.add( diffuseColor ); - - } - - } else if ( material.isMeshLambertMaterial || material.isMeshPhongMaterial ) { - - var normalComputed = false; - - for ( var i = 0, l = lights.length; i < l; i ++ ) { - - var light = lights[ i ]; - - lightVector.setFromMatrixPosition( light.matrixWorld ); - lightVector.sub( point ); - - rayLight.direction.copy( lightVector ).normalize(); - - var intersections = raycasterLight.intersectObjects( objects, true ); - - // point in shadow - - if ( intersections.length > 0 ) continue; - - // point lit - - if ( normalComputed === false ) { - - // the same normal can be reused for all lights - // (should be possible to cache even more) - - localPoint.copy( point ).applyMatrix4( _object.inverseMatrix ); - computePixelNormal( normalVector, localPoint, material.flatShading, face, geometry ); - normalVector.applyMatrix3( _object.normalMatrix ).normalize(); - - normalComputed = true; - - } - - lightColor.copyGammaToLinear( light.color ); - - // compute attenuation - - var attenuation = 1.0; - - if ( light.physicalAttenuation === true ) { - - attenuation = lightVector.length(); - attenuation = 1.0 / ( attenuation * attenuation ); - - } - - lightVector.normalize(); - - // compute diffuse - - var dot = Math.max( normalVector.dot( lightVector ), 0 ); - var diffuseIntensity = dot * light.intensity; - - lightContribution.copy( diffuseColor ); - lightContribution.multiply( lightColor ); - lightContribution.multiplyScalar( diffuseIntensity * attenuation ); - - outputColor.add( lightContribution ); - - // compute specular - - if ( material.isMeshPhongMaterial ) { - - halfVector.addVectors( lightVector, eyeVector ).normalize(); - - var dotNormalHalf = Math.max( normalVector.dot( halfVector ), 0.0 ); - var specularIntensity = Math.max( Math.pow( dotNormalHalf, material.shininess ), 0.0 ) * diffuseIntensity; - - var specularNormalization = ( material.shininess + 2.0 ) / 8.0; - - specularColor.copyGammaToLinear( material.specular ); - - var alpha = Math.pow( Math.max( 1.0 - lightVector.dot( halfVector ), 0.0 ), 5.0 ); - - schlick.r = specularColor.r + ( 1.0 - specularColor.r ) * alpha; - schlick.g = specularColor.g + ( 1.0 - specularColor.g ) * alpha; - schlick.b = specularColor.b + ( 1.0 - specularColor.b ) * alpha; - - lightContribution.copy( schlick ); - lightContribution.multiply( lightColor ); - lightContribution.multiplyScalar( specularNormalization * specularIntensity * attenuation ); - - outputColor.add( lightContribution ); - - } - - } - - } - - // reflection / refraction - - var reflectivity = material.reflectivity; - - if ( ( material.mirror || material.glass ) && reflectivity > 0 && recursionDepth < maxRecursionDepth ) { - - if ( material.mirror ) { - - reflectionVector.copy( rayDirection ); - reflectionVector.reflect( normalVector ); - - } else if ( material.glass ) { - - var eta = material.refractionRatio; - - var dotNI = rayDirection.dot( normalVector ); - var k = 1.0 - eta * eta * ( 1.0 - dotNI * dotNI ); - - if ( k < 0.0 ) { - - reflectionVector.set( 0, 0, 0 ); - - } else { - - reflectionVector.copy( rayDirection ); - reflectionVector.multiplyScalar( eta ); - - var alpha = eta * dotNI + Math.sqrt( k ); - tmpVec.copy( normalVector ); - tmpVec.multiplyScalar( alpha ); - reflectionVector.sub( tmpVec ); - - } - - } - - var theta = Math.max( eyeVector.dot( normalVector ), 0.0 ); - var rf0 = reflectivity; - var fresnel = rf0 + ( 1.0 - rf0 ) * Math.pow( ( 1.0 - theta ), 5.0 ); - - var weight = fresnel; - - var zColor = tmpColor[ recursionDepth ]; - - spawnRay( point, reflectionVector, zColor, recursionDepth + 1 ); - - if ( material.specular !== undefined ) { - - zColor.multiply( material.specular ); - - } - - zColor.multiplyScalar( weight ); - outputColor.multiplyScalar( 1 - weight ); - outputColor.add( zColor ); - - } - - }; - - }() ); - - var computePixelNormal = ( function () { - - var vA = new THREE.Vector3(); - var vB = new THREE.Vector3(); - var vC = new THREE.Vector3(); - - var tmpVec1 = new THREE.Vector3(); - var tmpVec2 = new THREE.Vector3(); - var tmpVec3 = new THREE.Vector3(); - - return function computePixelNormal( outputVector, point, flatShading, face, geometry ) { - - var faceNormal = face.normal; - - if ( flatShading === true ) { - - outputVector.copy( faceNormal ); - - } else { - - var positions = geometry.attributes.position; - var normals = geometry.attributes.normal; - - vA.fromBufferAttribute( positions, face.a ); - vB.fromBufferAttribute( positions, face.b ); - vC.fromBufferAttribute( positions, face.c ); - - // compute barycentric coordinates - - tmpVec3.crossVectors( tmpVec1.subVectors( vB, vA ), tmpVec2.subVectors( vC, vA ) ); - var areaABC = faceNormal.dot( tmpVec3 ); - - tmpVec3.crossVectors( tmpVec1.subVectors( vB, point ), tmpVec2.subVectors( vC, point ) ); - var areaPBC = faceNormal.dot( tmpVec3 ); - var a = areaPBC / areaABC; - - tmpVec3.crossVectors( tmpVec1.subVectors( vC, point ), tmpVec2.subVectors( vA, point ) ); - var areaPCA = faceNormal.dot( tmpVec3 ); - var b = areaPCA / areaABC; - - var c = 1.0 - a - b; - - // compute interpolated vertex normal - - tmpVec1.fromBufferAttribute( normals, face.a ); - tmpVec2.fromBufferAttribute( normals, face.b ); - tmpVec3.fromBufferAttribute( normals, face.c ); - - tmpVec1.multiplyScalar( a ); - tmpVec2.multiplyScalar( b ); - tmpVec3.multiplyScalar( c ); - - outputVector.addVectors( tmpVec1, tmpVec2 ); - outputVector.add( tmpVec3 ); - - } - - }; - - }() ); - - var renderBlock = ( function () { - - var blockSize = BLOCK; - - var data = new Uint8ClampedArray( blockSize * blockSize * 4 ); - - var pixelColor = new THREE.Color(); - - return function renderBlock( blockX, blockY ) { - - var index = 0; - - for ( var y = 0; y < blockSize; y ++ ) { - - for ( var x = 0; x < blockSize; x ++, index += 4 ) { - - // spawn primary ray at pixel position - - origin.copy( cameraPosition ); - - direction.set( x + blockX - canvasWidthHalf, - ( y + blockY - canvasHeightHalf ), - perspective ); - direction.applyMatrix3( cameraNormalMatrix ).normalize(); - - spawnRay( origin, direction, pixelColor, 0 ); - - // convert from linear to gamma - - data[ index + 0 ] = Math.sqrt( pixelColor.r ) * 255; - data[ index + 1 ] = Math.sqrt( pixelColor.g ) * 255; - data[ index + 2 ] = Math.sqrt( pixelColor.b ) * 255; - data[ index + 3 ] = 255; - - } - - } - - // Use transferable objects! :) - self.postMessage( { - data: data.buffer, - blockX: blockX, - blockY: blockY, - blockSize: blockSize, - sceneId: sceneId, - time: Date.now(), // time for this renderer - }, [ data.buffer ] ); - - data = new Uint8ClampedArray( blockSize * blockSize * 4 ); - - }; - - }() ); - - this.render = function ( scene, camera ) { - - // update scene graph - - if ( scene.autoUpdate === true ) scene.updateMatrixWorld(); - - // update camera matrices - - if ( camera.parent === null ) camera.updateMatrixWorld(); - - cameraPosition.setFromMatrixPosition( camera.matrixWorld ); - - // - - cameraNormalMatrix.getNormalMatrix( camera.matrixWorld ); - - perspective = 0.5 / Math.tan( THREE.Math.degToRad( camera.fov * 0.5 ) ) * canvasHeight; - - objects = scene.children; - - // collect lights and set up object matrices - - lights.length = 0; - - scene.traverse( function ( object ) { - - if ( object.isPointLight ) { - - lights.push( object ); - - } - - if ( cache[ object.id ] === undefined ) { - - cache[ object.id ] = { - normalMatrix: new THREE.Matrix3(), - inverseMatrix: new THREE.Matrix4() - }; - - } - - var _object = cache[ object.id ]; - - _object.normalMatrix.getNormalMatrix( object.matrixWorld ); - _object.inverseMatrix.getInverse( object.matrixWorld ); - - } ); - - renderBlock( startX, startY ); - - }; - -}; - -Object.assign( THREE.RaytracingRendererWorker.prototype, THREE.EventDispatcher.prototype ); diff --git a/examples/js/renderers/SVGRenderer.js b/examples/js/renderers/SVGRenderer.js index 5d95837d50f778..6ff603857fe17e 100644 --- a/examples/js/renderers/SVGRenderer.js +++ b/examples/js/renderers/SVGRenderer.js @@ -15,8 +15,6 @@ THREE.SVGObject.prototype.constructor = THREE.SVGObject; THREE.SVGRenderer = function () { - console.log( 'THREE.SVGRenderer', THREE.REVISION ); - var _this = this, _renderData, _elements, _lights, _projector = new THREE.Projector(), @@ -34,7 +32,6 @@ THREE.SVGRenderer = function () { _directionalLights = new THREE.Color(), _pointLights = new THREE.Color(), _clearColor = new THREE.Color(), - _clearAlpha = 1, _vector3 = new THREE.Vector3(), // Needed for PointLight _centroid = new THREE.Vector3(), @@ -81,10 +78,9 @@ THREE.SVGRenderer = function () { }; - this.setClearColor = function ( color, alpha ) { + this.setClearColor = function ( color ) { _clearColor.set( color ); - _clearAlpha = alpha !== undefined ? alpha : 1; }; @@ -122,16 +118,6 @@ THREE.SVGRenderer = function () { } - function getSvgColor( color, opacity ) { - - var arg = Math.floor( color.r * 255 ) + ',' + Math.floor( color.g * 255 ) + ',' + Math.floor( color.b * 255 ); - - if ( opacity === undefined || opacity === 1 ) return 'rgb(' + arg + ')'; - - return 'rgb(' + arg + '); fill-opacity: ' + opacity; - - } - function convert( c ) { return _precision !== null ? c.toFixed( _precision ) : c; @@ -141,7 +127,7 @@ THREE.SVGRenderer = function () { this.clear = function () { removeChildNodes(); - _svg.style.backgroundColor = getSvgColor( _clearColor, _clearAlpha ); + _svg.style.backgroundColor = _clearColor.getStyle(); }; @@ -159,7 +145,7 @@ THREE.SVGRenderer = function () { if ( background && background.isColor ) { removeChildNodes(); - _svg.style.backgroundColor = getSvgColor( background ); + _svg.style.backgroundColor = background.getStyle(); } else if ( this.autoClear === true ) { @@ -375,7 +361,7 @@ THREE.SVGRenderer = function () { if ( material.isSpriteMaterial || material.isPointsMaterial ) { - style = 'fill:' + getSvgColor( material.color, material.opacity ); + style = 'fill:' + material.color.getStyle() + ';fill-opacity:' + material.opacity; } @@ -389,7 +375,7 @@ THREE.SVGRenderer = function () { if ( material.isLineBasicMaterial ) { - var style = 'fill:none;stroke:' + getSvgColor( material.color, material.opacity ) + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap; + var style = 'fill:none;stroke:' + material.color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap; if ( material.isLineDashedMaterial ) { @@ -415,7 +401,7 @@ THREE.SVGRenderer = function () { _color.copy( material.color ); - if ( material.vertexColors === THREE.FaceColors || material.vertexColors === THREE.VertexColors ) { + if ( material.vertexColors ) { _color.multiply( element.color ); @@ -425,7 +411,7 @@ THREE.SVGRenderer = function () { _diffuseColor.copy( material.color ); - if ( material.vertexColors === THREE.FaceColors || material.vertexColors === THREE.VertexColors ) { + if ( material.vertexColors ) { _diffuseColor.multiply( element.color ); @@ -441,7 +427,7 @@ THREE.SVGRenderer = function () { } else if ( material.isMeshNormalMaterial ) { - _normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ); + _normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize(); _color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 ); @@ -449,11 +435,11 @@ THREE.SVGRenderer = function () { if ( material.wireframe ) { - style = 'fill:none;stroke:' + getSvgColor( _color, material.opacity ) + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin; + style = 'fill:none;stroke:' + _color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin; } else { - style = 'fill:' + getSvgColor( _color, material.opacity ); + style = 'fill:' + _color.getStyle() + ';fill-opacity:' + material.opacity; } diff --git a/examples/js/renderers/SoftwareRenderer.js b/examples/js/renderers/SoftwareRenderer.js deleted file mode 100644 index aed927cc3c7276..00000000000000 --- a/examples/js/renderers/SoftwareRenderer.js +++ /dev/null @@ -1,1556 +0,0 @@ -/** - * @author mrdoob / http://mrdoob.com/ - * @author ryg / http://farbrausch.de/~fg - * @author mraleph / http://mrale.ph/ - * @author daoshengmu / http://dsmu.me/ - */ - -THREE.SoftwareRenderer = function ( parameters ) { - - console.log( 'THREE.SoftwareRenderer', THREE.REVISION ); - - parameters = parameters || {}; - - var canvas = parameters.canvas !== undefined - ? parameters.canvas - : document.createElement( 'canvas' ); - - var context = canvas.getContext( '2d', { - alpha: parameters.alpha === true - } ); - - var shaders = {}; - var textures = {}; - - var canvasWidth, canvasHeight; - var canvasWBlocks, canvasHBlocks; - var viewportXScale, viewportYScale, viewportZScale; - var viewportXOffs, viewportYOffs, viewportZOffs; - - var clearColor = new THREE.Color( 0x000000 ); - var clearAlpha = parameters.alpha === true ? 0 : 1; - - var imagedata, data, zbuffer; - var numBlocks, blockMaxZ, blockFlags; - - var BLOCK_ISCLEAR = ( 1 << 0 ); - var BLOCK_NEEDCLEAR = ( 1 << 1 ); - - var subpixelBits = 4; - var subpixelBias = ( 1 << subpixelBits ) - 1; - var blockShift = 3; - var blockSize = 1 << blockShift; - var maxZVal = ( 1 << 24 ); // Note: You want to size this so you don't get overflows. - var lineMode = false; - var lookVector = new THREE.Vector3( 0, 0, 1 ); - var crossVector = new THREE.Vector3(); - - var rectx1 = Infinity, recty1 = Infinity; - var rectx2 = 0, recty2 = 0; - - var prevrectx1 = Infinity, prevrecty1 = Infinity; - var prevrectx2 = 0, prevrecty2 = 0; - - var projector = new THREE.Projector(); - - var spriteV1 = new THREE.Vector4(); - var spriteV2 = new THREE.Vector4(); - var spriteV3 = new THREE.Vector4(); - - var spriteUV1 = new THREE.Vector2(); - var spriteUV2 = new THREE.Vector2(); - var spriteUV3 = new THREE.Vector2(); - - var mpVPool = []; - var mpVPoolCount = 0; - var mpNPool = []; - var mpNPoolCount = 0; - var mpUVPool = []; - var mpUVPoolCount = 0; - - var _this = this; - - this.domElement = canvas; - - this.autoClear = true; - - this.setClearColor = function ( color, alpha ) { - - clearColor.set( color ); - clearAlpha = alpha; - clearColorBuffer( clearColor ); - - }; - - this.setPixelRatio = function () {}; - - this.setSize = function ( width, height ) { - - canvasWBlocks = Math.floor( width / blockSize ); - canvasHBlocks = Math.floor( height / blockSize ); - canvasWidth = canvasWBlocks * blockSize; - canvasHeight = canvasHBlocks * blockSize; - - var fixScale = 1 << subpixelBits; - - viewportXScale = fixScale * canvasWidth / 2; - viewportYScale = - fixScale * canvasHeight / 2; - viewportZScale = maxZVal / 2; - - viewportXOffs = fixScale * canvasWidth / 2 + 0.5; - viewportYOffs = fixScale * canvasHeight / 2 + 0.5; - viewportZOffs = maxZVal / 2 + 0.5; - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - - imagedata = context.getImageData( 0, 0, canvasWidth, canvasHeight ); - data = imagedata.data; - - zbuffer = new Int32Array( data.length / 4 ); - - numBlocks = canvasWBlocks * canvasHBlocks; - blockMaxZ = new Int32Array( numBlocks ); - blockFlags = new Uint8Array( numBlocks ); - - for ( var i = 0, l = zbuffer.length; i < l; i ++ ) { - - zbuffer[ i ] = maxZVal; - - } - - for ( var i = 0; i < numBlocks; i ++ ) { - - blockFlags[ i ] = BLOCK_ISCLEAR; - - } - - clearColorBuffer( clearColor ); - - }; - - this.clear = function () { - - rectx1 = Infinity; - recty1 = Infinity; - rectx2 = 0; - recty2 = 0; - mpVPoolCount = 0; - mpNPoolCount = 0; - mpUVPoolCount = 0; - - for ( var i = 0; i < numBlocks; i ++ ) { - - blockMaxZ[ i ] = maxZVal; - blockFlags[ i ] = ( blockFlags[ i ] & BLOCK_ISCLEAR ) ? BLOCK_ISCLEAR : BLOCK_NEEDCLEAR; - - } - - }; - - - this.render = function ( scene, camera ) { - - // TODO: Check why autoClear can't be false. - this.clear(); - - var background = scene.background; - - if ( background && background.isColor ) { - - clearColorBuffer( background ); - - } - - var renderData = projector.projectScene( scene, camera, false, false ); - var elements = renderData.elements; - - for ( var e = 0, el = elements.length; e < el; e ++ ) { - - var element = elements[ e ]; - var material = element.material; - var shader = getMaterialShader( material ); - - if ( ! shader ) continue; - - if ( element instanceof THREE.RenderableFace ) { - - if ( ! element.uvs ) { - - drawTriangle( - element.v1.positionScreen, - element.v2.positionScreen, - element.v3.positionScreen, - null, null, null, - shader, element, material - ); - - } else { - - drawTriangle( - element.v1.positionScreen, - element.v2.positionScreen, - element.v3.positionScreen, - element.uvs[ 0 ], element.uvs[ 1 ], element.uvs[ 2 ], - shader, element, material - ); - - } - - - } else if ( element instanceof THREE.RenderableSprite ) { - - var scaleX = element.scale.x * 0.5; - var scaleY = element.scale.y * 0.5; - - spriteV1.copy( element ); - spriteV1.x -= scaleX; - spriteV1.y += scaleY; - - spriteV2.copy( element ); - spriteV2.x -= scaleX; - spriteV2.y -= scaleY; - - spriteV3.copy( element ); - spriteV3.x += scaleX; - spriteV3.y += scaleY; - - if ( material.map ) { - - spriteUV1.set( 0, 1 ); - spriteUV2.set( 0, 0 ); - spriteUV3.set( 1, 1 ); - - drawTriangle( - spriteV1, spriteV2, spriteV3, - spriteUV1, spriteUV2, spriteUV3, - shader, element, material - ); - - } else { - - drawTriangle( - spriteV1, spriteV2, spriteV3, - null, null, null, - shader, element, material - ); - - } - - spriteV1.copy( element ); - spriteV1.x += scaleX; - spriteV1.y += scaleY; - - spriteV2.copy( element ); - spriteV2.x -= scaleX; - spriteV2.y -= scaleY; - - spriteV3.copy( element ); - spriteV3.x += scaleX; - spriteV3.y -= scaleY; - - if ( material.map ) { - - spriteUV1.set( 1, 1 ); - spriteUV2.set( 0, 0 ); - spriteUV3.set( 1, 0 ); - - drawTriangle( - spriteV1, spriteV2, spriteV3, - spriteUV1, spriteUV2, spriteUV3, - shader, element, material - ); - - } else { - - drawTriangle( - spriteV1, spriteV2, spriteV3, - null, null, null, - shader, element, material - ); - - } - - } else if ( element instanceof THREE.RenderableLine ) { - - var shader = getMaterialShader( material ); - - drawLine( - element.v1.positionScreen, - element.v2.positionScreen, - element.vertexColors[ 0 ], - element.vertexColors[ 1 ], - shader, - material - ); - - } - - } - - finishClear(); - - var x = Math.min( rectx1, prevrectx1 ); - var y = Math.min( recty1, prevrecty1 ); - var width = Math.max( rectx2, prevrectx2 ) - x; - var height = Math.max( recty2, prevrecty2 ) - y; - - /* - // debug; draw zbuffer - - for ( var i = 0, l = zbuffer.length; i < l; i++ ) { - - var o = i * 4; - var v = (65535 - zbuffer[ i ]) >> 3; - data[ o + 0 ] = v; - data[ o + 1 ] = v; - data[ o + 2 ] = v; - data[ o + 3 ] = 255; - } - */ - - if ( x !== Infinity ) { - - context.putImageData( imagedata, 0, 0, x, y, width, height ); - - } - - prevrectx1 = rectx1; prevrecty1 = recty1; - prevrectx2 = rectx2; prevrecty2 = recty2; - - }; - - function getAlpha() { - - return parameters.alpha === true ? clearAlpha : 1; - - } - - function clearColorBuffer( color ) { - - var size = canvasWidth * canvasHeight * 4; - - for ( var i = 0; i < size; i += 4 ) { - - data[ i ] = color.r * 255 | 0; - data[ i + 1 ] = color.g * 255 | 0; - data[ i + 2 ] = color.b * 255 | 0; - data[ i + 3 ] = getAlpha() * 255 | 0; - - } - - context.fillStyle = 'rgba(' + ( ( clearColor.r * 255 ) | 0 ) + ',' + ( ( clearColor.g * 255 ) | 0 ) + ',' + ( ( clearColor.b * 255 ) | 0 ) + ',' + getAlpha() + ')'; - context.fillRect( 0, 0, canvasWidth, canvasHeight ); - - } - - function getPalette( material, bSimulateSpecular ) { - - var i = 0, j = 0; - var diffuseR = material.color.r * 255; - var diffuseG = material.color.g * 255; - var diffuseB = material.color.b * 255; - var palette = new Uint8Array( 256 * 3 ); - - if ( bSimulateSpecular ) { - - while ( i < 204 ) { - - palette[ j ++ ] = Math.min( i * diffuseR / 204, 255 ); - palette[ j ++ ] = Math.min( i * diffuseG / 204, 255 ); - palette[ j ++ ] = Math.min( i * diffuseB / 204, 255 ); - ++ i; - - } - - while ( i < 256 ) { - - // plus specular highlight - palette[ j ++ ] = Math.min( diffuseR + ( i - 204 ) * ( 255 - diffuseR ) / 82, 255 ); - palette[ j ++ ] = Math.min( diffuseG + ( i - 204 ) * ( 255 - diffuseG ) / 82, 255 ); - palette[ j ++ ] = Math.min( diffuseB + ( i - 204 ) * ( 255 - diffuseB ) / 82, 255 ); - ++ i; - - } - - } else { - - while ( i < 256 ) { - - palette[ j ++ ] = Math.min( i * diffuseR / 255, 255 ); - palette[ j ++ ] = Math.min( i * diffuseG / 255, 255 ); - palette[ j ++ ] = Math.min( i * diffuseB / 255, 255 ); - ++ i; - - } - - } - - return palette; - - } - - function basicMaterialShader( buffer, depthBuf, offset, depth, u, v, n, face, material ) { - - var colorOffset = offset * 4; - - var texture = textures[ material.map.id ]; - - if ( ! texture.data ) return; - - var tdim = texture.width; - var isTransparent = material.transparent; - var tbound = tdim - 1; - var tdata = texture.data; - var tIndex = ( ( ( v * tdim ) & tbound ) * tdim + ( ( u * tdim ) & tbound ) ) * 4; - - if ( ! isTransparent ) { - - buffer[ colorOffset ] = tdata[ tIndex ]; - buffer[ colorOffset + 1 ] = tdata[ tIndex + 1 ]; - buffer[ colorOffset + 2 ] = tdata[ tIndex + 2 ]; - buffer[ colorOffset + 3 ] = ( material.opacity << 8 ) - 1; - depthBuf[ offset ] = depth; - - } else { - - var srcR = tdata[ tIndex ]; - var srcG = tdata[ tIndex + 1 ]; - var srcB = tdata[ tIndex + 2 ]; - var opaci = tdata[ tIndex + 3 ] * material.opacity / 255; - var destR = buffer[ colorOffset ]; - var destG = buffer[ colorOffset + 1 ]; - var destB = buffer[ colorOffset + 2 ]; - - buffer[ colorOffset ] = ( srcR * opaci + destR * ( 1 - opaci ) ); - buffer[ colorOffset + 1 ] = ( srcG * opaci + destG * ( 1 - opaci ) ); - buffer[ colorOffset + 2 ] = ( srcB * opaci + destB * ( 1 - opaci ) ); - buffer[ colorOffset + 3 ] = ( material.opacity << 8 ) - 1; - - // Only opaue pixls write to the depth buffer - - if ( buffer[ colorOffset + 3 ] == 255 ) depthBuf[ offset ] = depth; - - } - - } - - function lightingMaterialShader( buffer, depthBuf, offset, depth, u, v, n, face, material ) { - - var colorOffset = offset * 4; - - var texture = textures[ material.map.id ]; - - if ( ! texture.data ) return; - - var tdim = texture.width; - var isTransparent = material.transparent; - var cIndex = ( n > 0 ? ( ~ ~ n ) : 0 ) * 3; - var tbound = tdim - 1; - var tdata = texture.data; - var tIndex = ( ( ( v * tdim ) & tbound ) * tdim + ( ( u * tdim ) & tbound ) ) * 4; - - if ( ! isTransparent ) { - - buffer[ colorOffset ] = ( material.palette[ cIndex ] * tdata[ tIndex ] ) >> 8; - buffer[ colorOffset + 1 ] = ( material.palette[ cIndex + 1 ] * tdata[ tIndex + 1 ] ) >> 8; - buffer[ colorOffset + 2 ] = ( material.palette[ cIndex + 2 ] * tdata[ tIndex + 2 ] ) >> 8; - buffer[ colorOffset + 3 ] = ( material.opacity << 8 ) - 1; - depthBuf[ offset ] = depth; - - } else { - - var foreColorR = material.palette[ cIndex ] * tdata[ tIndex ]; - var foreColorG = material.palette[ cIndex + 1 ] * tdata[ tIndex + 1 ]; - var foreColorB = material.palette[ cIndex + 2 ] * tdata[ tIndex + 2 ]; - var opaci = tdata[ tIndex + 3 ] * material.opacity / 256; - var destR = buffer[ colorOffset ]; - var destG = buffer[ colorOffset + 1 ]; - var destB = buffer[ colorOffset + 2 ]; - - buffer[ colorOffset ] = foreColorR * opaci + destR * ( 1 - opaci ); - buffer[ colorOffset + 1 ] = foreColorG * opaci + destG * ( 1 - opaci ); - buffer[ colorOffset + 2 ] = foreColorB * opaci + destB * ( 1 - opaci ); - buffer[ colorOffset + 3 ] = ( material.opacity << 8 ) - 1; - - // Only opaue pixls write to the depth buffer - - if ( buffer[ colorOffset + 3 ] == 255 ) depthBuf[ offset ] = depth; - - } - - } - - function getMaterialShader( material ) { - - var id = material.id; - var shader = shaders[ id ]; - - if ( shader && material.map && ! textures[ material.map.id ] ) delete shaders[ id ]; - - if ( shaders[ id ] === undefined || material.needsUpdate === true ) { - - if ( material instanceof THREE.MeshBasicMaterial || - material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.SpriteMaterial ) { - - if ( material instanceof THREE.MeshLambertMaterial ) { - - // Generate color palette - if ( ! material.palette ) { - - material.palette = getPalette( material, false ); - - } - - } else if ( material instanceof THREE.MeshPhongMaterial ) { - - // Generate color palette - if ( ! material.palette ) { - - material.palette = getPalette( material, true ); - - } - - } - - var string; - - if ( material.map ) { - - var texture = new THREE.SoftwareRenderer.Texture(); - texture.fromImage( material.map.image ); - - if ( ! texture.data ) return; - - textures[ material.map.id ] = texture; - - if ( material instanceof THREE.MeshBasicMaterial - || material instanceof THREE.SpriteMaterial ) { - - shader = basicMaterialShader; - - } else { - - shader = lightingMaterialShader; - - } - - - } else { - - if ( material.vertexColors === THREE.FaceColors || material.vertexColors === THREE.VertexColors ) { - - string = [ - 'var colorOffset = offset * 4;', - 'buffer[ colorOffset ] = face.color.r * 255;', - 'buffer[ colorOffset + 1 ] = face.color.g * 255;', - 'buffer[ colorOffset + 2 ] = face.color.b * 255;', - 'buffer[ colorOffset + 3 ] = material.opacity * 255;', - 'depthBuf[ offset ] = depth;' - ].join( '\n' ); - - } else { - - string = [ - 'var colorOffset = offset * 4;', - 'buffer[ colorOffset ] = material.color.r * 255;', - 'buffer[ colorOffset + 1 ] = material.color.g * 255;', - 'buffer[ colorOffset + 2 ] = material.color.b * 255;', - 'buffer[ colorOffset + 3 ] = material.opacity * 255;', - 'depthBuf[ offset ] = depth;' - ].join( '\n' ); - - } - - shader = new Function( 'buffer, depthBuf, offset, depth, u, v, n, face, material', string ); - - } - - } else if ( material instanceof THREE.LineBasicMaterial ) { - - var string = [ - 'var colorOffset = offset * 4;', - 'buffer[ colorOffset ] = material.color.r * (color1.r+color2.r) * 0.5 * 255;', - 'buffer[ colorOffset + 1 ] = material.color.g * (color1.g+color2.g) * 0.5 * 255;', - 'buffer[ colorOffset + 2 ] = material.color.b * (color1.b+color2.b) * 0.5 * 255;', - 'buffer[ colorOffset + 3 ] = 255;', - 'depthBuf[ offset ] = depth;' - ].join( '\n' ); - - shader = new Function( 'buffer, depthBuf, offset, depth, color1, color2, material', string ); - - } else { - - var string = [ - 'var colorOffset = offset * 4;', - 'buffer[ colorOffset ] = u * 255;', - 'buffer[ colorOffset + 1 ] = v * 255;', - 'buffer[ colorOffset + 2 ] = 0;', - 'buffer[ colorOffset + 3 ] = 255;', - 'depthBuf[ offset ] = depth;' - ].join( '\n' ); - - shader = new Function( 'buffer, depthBuf, offset, depth, u, v, n, face, material', string ); - - } - - shaders[ id ] = shader; - - material.needsUpdate = false; - - } - - return shader; - - } - - /* - function clearRectangle( x1, y1, x2, y2 ) { - - var xmin = Math.max( Math.min( x1, x2 ), 0 ); - var xmax = Math.min( Math.max( x1, x2 ), canvasWidth ); - var ymin = Math.max( Math.min( y1, y2 ), 0 ); - var ymax = Math.min( Math.max( y1, y2 ), canvasHeight ); - - var offset = ( xmin + ymin * canvasWidth ) * 4 + 3; - var linestep = ( canvasWidth - ( xmax - xmin ) ) * 4; - - for ( var y = ymin; y < ymax; y ++ ) { - - for ( var x = xmin; x < xmax; x ++ ) { - - data[ offset += 4 ] = 0; - - } - - offset += linestep; - - } - - } - */ - - function drawTriangle( v1, v2, v3, uv1, uv2, uv3, shader, face, material ) { - - // TODO: Implement per-pixel z-clipping - - if ( v1.z < - 1 || v1.z > 1 || v2.z < - 1 || v2.z > 1 || v3.z < - 1 || v3.z > 1 ) return; - - // https://gist.github.com/2486101 - // explanation: http://pouet.net/topic.php?which=8760&page=1 - - var fixscale = ( 1 << subpixelBits ); - - // 28.4 fixed-point coordinates - - var x1 = ( v1.x * viewportXScale + viewportXOffs ) | 0; - var x2 = ( v2.x * viewportXScale + viewportXOffs ) | 0; - var x3 = ( v3.x * viewportXScale + viewportXOffs ) | 0; - - var y1 = ( v1.y * viewportYScale + viewportYOffs ) | 0; - var y2 = ( v2.y * viewportYScale + viewportYOffs ) | 0; - var y3 = ( v3.y * viewportYScale + viewportYOffs ) | 0; - - var bHasNormal = face.vertexNormalsModel && face.vertexNormalsModel.length; - var bHasUV = uv1 && uv2 && uv3; - - var longestSide = Math.max( - Math.sqrt( ( x1 - x2 ) * ( x1 - x2 ) + ( y1 - y2 ) * ( y1 - y2 ) ), - Math.sqrt( ( x2 - x3 ) * ( x2 - x3 ) + ( y2 - y3 ) * ( y2 - y3 ) ), - Math.sqrt( ( x3 - x1 ) * ( x3 - x1 ) + ( y3 - y1 ) * ( y3 - y1 ) ) - ); - - if ( ! ( face instanceof THREE.RenderableSprite ) && ( longestSide > 100 * fixscale ) ) { - - // 1 - // |\ - // |a\ - // |__\ - // |\c|\ - // |b\|d\ - // |__\__\ - // 2 3 - var tempFace = { vertexNormalsModel: [], color: face.color }; - var mpUV12, mpUV23, mpUV31; - - if ( bHasUV ) { - - if ( mpUVPoolCount === mpUVPool.length ) { - - mpUV12 = new THREE.Vector2(); - mpUVPool.push( mpUV12 ); - ++ mpUVPoolCount; - - mpUV23 = new THREE.Vector2(); - mpUVPool.push( mpUV23 ); - ++ mpUVPoolCount; - - mpUV31 = new THREE.Vector2(); - mpUVPool.push( mpUV31 ); - ++ mpUVPoolCount; - - } else { - - mpUV12 = mpUVPool[ mpUVPoolCount ]; - ++ mpUVPoolCount; - - mpUV23 = mpUVPool[ mpUVPoolCount ]; - ++ mpUVPoolCount; - - mpUV31 = mpUVPool[ mpUVPoolCount ]; - ++ mpUVPoolCount; - - } - - var weight; - - weight = ( 1 + v2.z ) * ( v2.w / v1.w ) / ( 1 + v1.z ); - mpUV12.copy( uv1 ).multiplyScalar( weight ).add( uv2 ).multiplyScalar( 1 / ( weight + 1 ) ); - - weight = ( 1 + v3.z ) * ( v3.w / v2.w ) / ( 1 + v2.z ); - mpUV23.copy( uv2 ).multiplyScalar( weight ).add( uv3 ).multiplyScalar( 1 / ( weight + 1 ) ); - - weight = ( 1 + v1.z ) * ( v1.w / v3.w ) / ( 1 + v3.z ); - mpUV31.copy( uv3 ).multiplyScalar( weight ).add( uv1 ).multiplyScalar( 1 / ( weight + 1 ) ); - - } - - var mpV12, mpV23, mpV31; - - if ( mpVPoolCount === mpVPool.length ) { - - mpV12 = new THREE.Vector4(); - mpVPool.push( mpV12 ); - ++ mpVPoolCount; - - mpV23 = new THREE.Vector4(); - mpVPool.push( mpV23 ); - ++ mpVPoolCount; - - mpV31 = new THREE.Vector4(); - mpVPool.push( mpV31 ); - ++ mpVPoolCount; - - } else { - - mpV12 = mpVPool[ mpVPoolCount ]; - ++ mpVPoolCount; - - mpV23 = mpVPool[ mpVPoolCount ]; - ++ mpVPoolCount; - - mpV31 = mpVPool[ mpVPoolCount ]; - ++ mpVPoolCount; - - } - - mpV12.copy( v1 ).add( v2 ).multiplyScalar( 0.5 ); - mpV23.copy( v2 ).add( v3 ).multiplyScalar( 0.5 ); - mpV31.copy( v3 ).add( v1 ).multiplyScalar( 0.5 ); - - var mpN12, mpN23, mpN31; - - if ( bHasNormal ) { - - if ( mpNPoolCount === mpNPool.length ) { - - mpN12 = new THREE.Vector3(); - mpNPool.push( mpN12 ); - ++ mpNPoolCount; - - mpN23 = new THREE.Vector3(); - mpNPool.push( mpN23 ); - ++ mpNPoolCount; - - mpN31 = new THREE.Vector3(); - mpNPool.push( mpN31 ); - ++ mpNPoolCount; - - } else { - - mpN12 = mpNPool[ mpNPoolCount ]; - ++ mpNPoolCount; - - mpN23 = mpNPool[ mpNPoolCount ]; - ++ mpNPoolCount; - - mpN31 = mpNPool[ mpNPoolCount ]; - ++ mpNPoolCount; - - } - - mpN12.copy( face.vertexNormalsModel[ 0 ] ).add( face.vertexNormalsModel[ 1 ] ).normalize(); - mpN23.copy( face.vertexNormalsModel[ 1 ] ).add( face.vertexNormalsModel[ 2 ] ).normalize(); - mpN31.copy( face.vertexNormalsModel[ 2 ] ).add( face.vertexNormalsModel[ 0 ] ).normalize(); - - } - - // a - if ( bHasNormal ) { - - tempFace.vertexNormalsModel[ 0 ] = face.vertexNormalsModel[ 0 ]; - tempFace.vertexNormalsModel[ 1 ] = mpN12; - tempFace.vertexNormalsModel[ 2 ] = mpN31; - - } - - drawTriangle( v1, mpV12, mpV31, uv1, mpUV12, mpUV31, shader, tempFace, material ); - - // b - if ( bHasNormal ) { - - tempFace.vertexNormalsModel[ 0 ] = face.vertexNormalsModel[ 1 ]; - tempFace.vertexNormalsModel[ 1 ] = mpN23; - tempFace.vertexNormalsModel[ 2 ] = mpN12; - - } - - drawTriangle( v2, mpV23, mpV12, uv2, mpUV23, mpUV12, shader, tempFace, material ); - - // c - if ( bHasNormal ) { - - tempFace.vertexNormalsModel[ 0 ] = mpN12; - tempFace.vertexNormalsModel[ 1 ] = mpN23; - tempFace.vertexNormalsModel[ 2 ] = mpN31; - - } - - drawTriangle( mpV12, mpV23, mpV31, mpUV12, mpUV23, mpUV31, shader, tempFace, material ); - - // d - if ( bHasNormal ) { - - tempFace.vertexNormalsModel[ 0 ] = face.vertexNormalsModel[ 2 ]; - tempFace.vertexNormalsModel[ 1 ] = mpN31; - tempFace.vertexNormalsModel[ 2 ] = mpN23; - - } - - drawTriangle( v3, mpV31, mpV23, uv3, mpUV31, mpUV23, shader, tempFace, material ); - - return; - - } - - // Z values (.28 fixed-point) - - var z1 = ( v1.z * viewportZScale + viewportZOffs ) | 0; - var z2 = ( v2.z * viewportZScale + viewportZOffs ) | 0; - var z3 = ( v3.z * viewportZScale + viewportZOffs ) | 0; - - // UV values - var bHasUV = false; - var tu1, tv1, tu2, tv2, tu3, tv3; - - if ( uv1 && uv2 && uv3 ) { - - bHasUV = true; - - tu1 = uv1.x; - tv1 = 1 - uv1.y; - tu2 = uv2.x; - tv2 = 1 - uv2.y; - tu3 = uv3.x; - tv3 = 1 - uv3.y; - - } - - // Normal values - var n1, n2, n3, nz1, nz2, nz3; - - if ( bHasNormal ) { - - n1 = face.vertexNormalsModel[ 0 ]; - n2 = face.vertexNormalsModel[ 1 ]; - n3 = face.vertexNormalsModel[ 2 ]; - nz1 = n1.z * 255; - nz2 = n2.z * 255; - nz3 = n3.z * 255; - - } - - // Deltas - - var dx12 = x1 - x2, dy12 = y2 - y1; - var dx23 = x2 - x3, dy23 = y3 - y2; - var dx31 = x3 - x1, dy31 = y1 - y3; - - // Bounding rectangle - - var minx = Math.max( ( Math.min( x1, x2, x3 ) + subpixelBias ) >> subpixelBits, 0 ); - var maxx = Math.min( ( Math.max( x1, x2, x3 ) + subpixelBias ) >> subpixelBits, canvasWidth ); - var miny = Math.max( ( Math.min( y1, y2, y3 ) + subpixelBias ) >> subpixelBits, 0 ); - var maxy = Math.min( ( Math.max( y1, y2, y3 ) + subpixelBias ) >> subpixelBits, canvasHeight ); - - rectx1 = Math.min( minx, rectx1 ); - rectx2 = Math.max( maxx, rectx2 ); - recty1 = Math.min( miny, recty1 ); - recty2 = Math.max( maxy, recty2 ); - - // Block size, standard 8x8 (must be power of two) - - var q = blockSize; - - // Start in corner of 8x8 block - - minx &= ~ ( q - 1 ); - miny &= ~ ( q - 1 ); - - // Constant part of half-edge functions - - var minXfixscale = ( minx << subpixelBits ); - var minYfixscale = ( miny << subpixelBits ); - - var c1 = dy12 * ( ( minXfixscale ) - x1 ) + dx12 * ( ( minYfixscale ) - y1 ); - var c2 = dy23 * ( ( minXfixscale ) - x2 ) + dx23 * ( ( minYfixscale ) - y2 ); - var c3 = dy31 * ( ( minXfixscale ) - x3 ) + dx31 * ( ( minYfixscale ) - y3 ); - - // Correct for fill convention - - if ( dy12 > 0 || ( dy12 == 0 && dx12 > 0 ) ) c1 ++; - if ( dy23 > 0 || ( dy23 == 0 && dx23 > 0 ) ) c2 ++; - if ( dy31 > 0 || ( dy31 == 0 && dx31 > 0 ) ) c3 ++; - - // Note this doesn't kill subpixel precision, but only because we test for >=0 (not >0). - // It's a bit subtle. :) - c1 = ( c1 - 1 ) >> subpixelBits; - c2 = ( c2 - 1 ) >> subpixelBits; - c3 = ( c3 - 1 ) >> subpixelBits; - - // Z interpolation setup - - var dz12 = z1 - z2, dz31 = z3 - z1; - var invDet = 1.0 / ( dx12 * dy31 - dx31 * dy12 ); - var dzdx = ( invDet * ( dz12 * dy31 - dz31 * dy12 ) ); // dz per one subpixel step in x - var dzdy = ( invDet * ( dz12 * dx31 - dx12 * dz31 ) ); // dz per one subpixel step in y - - // Z at top/left corner of rast area - - var cz = ( z1 + ( ( minXfixscale ) - x1 ) * dzdx + ( ( minYfixscale ) - y1 ) * dzdy ) | 0; - - // Z pixel steps - - dzdx = ( dzdx * fixscale ) | 0; - dzdy = ( dzdy * fixscale ) | 0; - - var dtvdx, dtvdy, cbtu, cbtv; - if ( bHasUV ) { - - // UV interpolation setup - var dtu12 = tu1 - tu2, dtu31 = tu3 - tu1; - var dtudx = ( invDet * ( dtu12 * dy31 - dtu31 * dy12 ) ); // dtu per one subpixel step in x - var dtudy = ( invDet * ( dtu12 * dx31 - dx12 * dtu31 ) ); // dtu per one subpixel step in y - var dtv12 = tv1 - tv2, dtv31 = tv3 - tv1; - dtvdx = ( invDet * ( dtv12 * dy31 - dtv31 * dy12 ) ); // dtv per one subpixel step in x - dtvdy = ( invDet * ( dtv12 * dx31 - dx12 * dtv31 ) ); // dtv per one subpixel step in y - - // UV at top/left corner of rast area - cbtu = ( tu1 + ( minXfixscale - x1 ) * dtudx + ( minYfixscale - y1 ) * dtudy ); - cbtv = ( tv1 + ( minXfixscale - x1 ) * dtvdx + ( minYfixscale - y1 ) * dtvdy ); - - // UV pixel steps - dtudx = dtudx * fixscale; - dtudy = dtudy * fixscale; - dtvdx = dtvdx * fixscale; - dtvdy = dtvdy * fixscale; - - } - - var dnzdy, cbnz; - - if ( bHasNormal ) { - - // Normal interpolation setup - var dnz12 = nz1 - nz2, dnz31 = nz3 - nz1; - var dnzdx = ( invDet * ( dnz12 * dy31 - dnz31 * dy12 ) ); // dnz per one subpixel step in x - var dnzdy = ( invDet * ( dnz12 * dx31 - dx12 * dnz31 ) ); // dnz per one subpixel step in y - - // Normal at top/left corner of rast area - cbnz = ( nz1 + ( minXfixscale - x1 ) * dnzdx + ( minYfixscale - y1 ) * dnzdy ); - - // Normal pixel steps - dnzdx = ( dnzdx * fixscale ); - dnzdy = ( dnzdy * fixscale ); - - } - - // Set up min/max corners - var qm1 = q - 1; // for convenience - var nmin1 = 0, nmax1 = 0; - var nmin2 = 0, nmax2 = 0; - var nmin3 = 0, nmax3 = 0; - var nminz = 0, nmaxz = 0; - if ( dx12 >= 0 ) nmax1 -= qm1 * dx12; else nmin1 -= qm1 * dx12; - if ( dy12 >= 0 ) nmax1 -= qm1 * dy12; else nmin1 -= qm1 * dy12; - if ( dx23 >= 0 ) nmax2 -= qm1 * dx23; else nmin2 -= qm1 * dx23; - if ( dy23 >= 0 ) nmax2 -= qm1 * dy23; else nmin2 -= qm1 * dy23; - if ( dx31 >= 0 ) nmax3 -= qm1 * dx31; else nmin3 -= qm1 * dx31; - if ( dy31 >= 0 ) nmax3 -= qm1 * dy31; else nmin3 -= qm1 * dy31; - if ( dzdx >= 0 ) nmaxz += qm1 * dzdx; else nminz += qm1 * dzdx; - if ( dzdy >= 0 ) nmaxz += qm1 * dzdy; else nminz += qm1 * dzdy; - - // Loop through blocks - var linestep = canvasWidth - q; - - var cb1 = c1; - var cb2 = c2; - var cb3 = c3; - var cbz = cz; - var qstep = - q; - var e1x = qstep * dy12; - var e2x = qstep * dy23; - var e3x = qstep * dy31; - var ezx = qstep * dzdx; - - var etux, etvx; - if ( bHasUV ) { - - etux = qstep * dtudx; - etvx = qstep * dtvdx; - - } - - var enzx; - if ( bHasNormal ) { - - enzx = qstep * dnzdx; - - } - - var x0 = minx; - - for ( var y0 = miny; y0 < maxy; y0 += q ) { - - // New block line - keep hunting for tri outer edge in old block line dir - while ( x0 >= minx && x0 < maxx && cb1 >= nmax1 && cb2 >= nmax2 && cb3 >= nmax3 ) { - - x0 += qstep; - cb1 += e1x; - cb2 += e2x; - cb3 += e3x; - cbz += ezx; - - if ( bHasUV ) { - - cbtu += etux; - cbtv += etvx; - - } - - if ( bHasNormal ) { - - cbnz += enzx; - - } - - } - - // Okay, we're now in a block we know is outside. Reverse direction and go into main loop. - qstep = - qstep; - e1x = - e1x; - e2x = - e2x; - e3x = - e3x; - ezx = - ezx; - - if ( bHasUV ) { - - etux = - etux; - etvx = - etvx; - - } - - if ( bHasNormal ) { - - enzx = - enzx; - - } - - while ( 1 ) { - - // Step everything - x0 += qstep; - cb1 += e1x; - cb2 += e2x; - cb3 += e3x; - cbz += ezx; - - if ( bHasUV ) { - - cbtu += etux; - cbtv += etvx; - - } - - if ( bHasNormal ) { - - cbnz += enzx; - - } - - // We're done with this block line when at least one edge completely out - // If an edge function is too small and decreasing in the current traversal - // dir, we're done with this line. - if ( x0 < minx || x0 >= maxx ) break; - if ( cb1 < nmax1 ) if ( e1x < 0 ) break; else continue; - if ( cb2 < nmax2 ) if ( e2x < 0 ) break; else continue; - if ( cb3 < nmax3 ) if ( e3x < 0 ) break; else continue; - - // We can skip this block if it's already fully covered - var blockX = x0 >> blockShift; - var blockY = y0 >> blockShift; - var blockId = blockX + blockY * canvasWBlocks; - var minz = cbz + nminz; - - // farthest point in block closer than closest point in our tri? - if ( blockMaxZ[ blockId ] < minz ) continue; - - // Need to do a deferred clear? - var bflags = blockFlags[ blockId ]; - if ( bflags & BLOCK_NEEDCLEAR ) clearBlock( blockX, blockY ); - blockFlags[ blockId ] = bflags & ~ ( BLOCK_ISCLEAR | BLOCK_NEEDCLEAR ); - - // Offset at top-left corner - var offset = x0 + y0 * canvasWidth; - - // Accept whole block when fully covered - if ( cb1 >= nmin1 && cb2 >= nmin2 && cb3 >= nmin3 ) { - - var maxz = cbz + nmaxz; - blockMaxZ[ blockId ] = Math.min( blockMaxZ[ blockId ], maxz ); - - var cy1 = cb1; - var cy2 = cb2; - var cyz = cbz; - - var cytu, cytv; - if ( bHasUV ) { - - cytu = cbtu; - cytv = cbtv; - - } - - var cynz; - if ( bHasNormal ) { - - cynz = cbnz; - - } - - - for ( var iy = 0; iy < q; iy ++ ) { - - var cx1 = cy1; - var cx2 = cy2; - var cxz = cyz; - - var cxtu; - var cxtv; - if ( bHasUV ) { - - cxtu = cytu; - cxtv = cytv; - - } - - var cxnz; - if ( bHasNormal ) { - - cxnz = cynz; - - } - - for ( var ix = 0; ix < q; ix ++ ) { - - var z = cxz; - - if ( z < zbuffer[ offset ] ) { - - shader( data, zbuffer, offset, z, cxtu, cxtv, cxnz, face, material ); - - } - - cx1 += dy12; - cx2 += dy23; - cxz += dzdx; - - if ( bHasUV ) { - - cxtu += dtudx; - cxtv += dtvdx; - - } - - if ( bHasNormal ) { - - cxnz += dnzdx; - - } - - offset ++; - - } - - cy1 += dx12; - cy2 += dx23; - cyz += dzdy; - - if ( bHasUV ) { - - cytu += dtudy; - cytv += dtvdy; - - } - - if ( bHasNormal ) { - - cynz += dnzdy; - - } - - offset += linestep; - - } - - } else { - - // Partially covered block - - var cy1 = cb1; - var cy2 = cb2; - var cy3 = cb3; - var cyz = cbz; - - var cytu, cytv; - if ( bHasUV ) { - - cytu = cbtu; - cytv = cbtv; - - } - - var cynz; - if ( bHasNormal ) { - - cynz = cbnz; - - } - - for ( var iy = 0; iy < q; iy ++ ) { - - var cx1 = cy1; - var cx2 = cy2; - var cx3 = cy3; - var cxz = cyz; - - var cxtu; - var cxtv; - if ( bHasUV ) { - - cxtu = cytu; - cxtv = cytv; - - } - - var cxnz; - if ( bHasNormal ) { - - cxnz = cynz; - - } - - for ( var ix = 0; ix < q; ix ++ ) { - - if ( ( cx1 | cx2 | cx3 ) >= 0 ) { - - var z = cxz; - - if ( z < zbuffer[ offset ] ) { - - shader( data, zbuffer, offset, z, cxtu, cxtv, cxnz, face, material ); - - } - - } - - cx1 += dy12; - cx2 += dy23; - cx3 += dy31; - cxz += dzdx; - - if ( bHasUV ) { - - cxtu += dtudx; - cxtv += dtvdx; - - } - - if ( bHasNormal ) { - - cxnz += dnzdx; - - } - - offset ++; - - } - - cy1 += dx12; - cy2 += dx23; - cy3 += dx31; - cyz += dzdy; - - if ( bHasUV ) { - - cytu += dtudy; - cytv += dtvdy; - - } - - if ( bHasNormal ) { - - cynz += dnzdy; - - } - - offset += linestep; - - } - - } - - } - - // Advance to next row of blocks - cb1 += q * dx12; - cb2 += q * dx23; - cb3 += q * dx31; - cbz += q * dzdy; - - if ( bHasUV ) { - - cbtu += q * dtudy; - cbtv += q * dtvdy; - - } - - if ( bHasNormal ) { - - cbnz += q * dnzdy; - - } - - } - - } - - // When drawing line, the blockShiftShift has to be zero. In order to clean pixel - // Using color1 and color2 to interpolation pixel color - // LineWidth is according to material.linewidth - function drawLine( v1, v2, color1, color2, shader, material ) { - - // While the line mode is enable, blockSize has to be changed to 0. - if ( ! lineMode ) { - - lineMode = true; - blockShift = 0; - blockSize = 1 << blockShift; - - _this.setSize( canvas.width, canvas.height ); - - } - - // TODO: Implement per-pixel z-clipping - if ( v1.z < - 1 || v1.z > 1 || v2.z < - 1 || v2.z > 1 ) return; - - var halfLineWidth = Math.floor( ( material.linewidth - 1 ) * 0.5 ); - - // https://gist.github.com/2486101 - // explanation: http://pouet.net/topic.php?which=8760&page=1 - - // 28.4 fixed-point coordinates - var x1 = ( v1.x * viewportXScale + viewportXOffs ) | 0; - var x2 = ( v2.x * viewportXScale + viewportXOffs ) | 0; - - var y1 = ( v1.y * viewportYScale + viewportYOffs ) | 0; - var y2 = ( v2.y * viewportYScale + viewportYOffs ) | 0; - - var z1 = ( v1.z * viewportZScale + viewportZOffs ) | 0; - var z2 = ( v2.z * viewportZScale + viewportZOffs ) | 0; - - // Deltas - var dx12 = x1 - x2, dy12 = y1 - y2, dz12 = z1 - z2; - - // Bounding rectangle - var minx = Math.max( ( Math.min( x1, x2 ) + subpixelBias ) >> subpixelBits, 0 ); - var maxx = Math.min( ( Math.max( x1, x2 ) + subpixelBias ) >> subpixelBits, canvasWidth ); - var miny = Math.max( ( Math.min( y1, y2 ) + subpixelBias ) >> subpixelBits, 0 ); - var maxy = Math.min( ( Math.max( y1, y2 ) + subpixelBias ) >> subpixelBits, canvasHeight ); - var minz = Math.max( ( Math.min( z1, z2 ) + subpixelBias ) >> subpixelBits, 0 ); - var maxz = ( Math.max( z1, z2 ) + subpixelBias ) >> subpixelBits; - - rectx1 = Math.min( minx, rectx1 ); - rectx2 = Math.max( maxx, rectx2 ); - recty1 = Math.min( miny, recty1 ); - recty2 = Math.max( maxy, recty2 ); - - // Get the line's unit vector and cross vector - var length = Math.sqrt( ( dy12 * dy12 ) + ( dx12 * dx12 ) ); - var unitX = ( dx12 / length ); - var unitY = ( dy12 / length ); - var unitZ = ( dz12 / length ); - var pixelX, pixelY, pixelZ; - var pX, pY, pZ; - crossVector.set( unitX, unitY, unitZ ); - crossVector.cross( lookVector ); - crossVector.normalize(); - - while ( length > 0 ) { - - // Get this pixel. - pixelX = x2 + length * unitX; - pixelY = y2 + length * unitY; - pixelZ = z2 + length * unitZ; - - pixelX = ( pixelX + subpixelBias ) >> subpixelBits; - pixelY = ( pixelY + subpixelBias ) >> subpixelBits; - pZ = ( pixelZ + subpixelBias ) >> subpixelBits; - - // Draw line with line width - for ( var i = - halfLineWidth; i <= halfLineWidth; ++ i ) { - - // Compute the line pixels. - // Get the pixels on the vector that crosses to the line vector - pX = Math.floor( ( pixelX + crossVector.x * i ) ); - pY = Math.floor( ( pixelY + crossVector.y * i ) ); - - // if pixel is over the rect. Continue - if ( rectx1 >= pX || rectx2 <= pX || recty1 >= pY || recty2 <= pY ) - continue; - - // Find this pixel at which block - var blockX = pX >> blockShift; - var blockY = pY >> blockShift; - var blockId = blockX + blockY * canvasWBlocks; - - // Compare the pixel depth width z block. - if ( blockMaxZ[ blockId ] < minz ) continue; - - blockMaxZ[ blockId ] = Math.min( blockMaxZ[ blockId ], maxz ); - - var bflags = blockFlags[ blockId ]; - if ( bflags & BLOCK_NEEDCLEAR ) clearBlock( blockX, blockY ); - blockFlags[ blockId ] = bflags & ~ ( BLOCK_ISCLEAR | BLOCK_NEEDCLEAR ); - - // draw pixel - var offset = pX + pY * canvasWidth; - - if ( pZ < zbuffer[ offset ] ) { - - shader( data, zbuffer, offset, pZ, color1, color2, material ); - - } - - } - - -- length; - - } - - } - - function clearBlock( blockX, blockY ) { - - var zoffset = blockX * blockSize + blockY * blockSize * canvasWidth; - var poffset = zoffset * 4; - - var zlinestep = canvasWidth - blockSize; - var plinestep = zlinestep * 4; - - for ( var y = 0; y < blockSize; y ++ ) { - - for ( var x = 0; x < blockSize; x ++ ) { - - zbuffer[ zoffset ++ ] = maxZVal; - - data[ poffset ++ ] = clearColor.r * 255 | 0; - data[ poffset ++ ] = clearColor.g * 255 | 0; - data[ poffset ++ ] = clearColor.b * 255 | 0; - data[ poffset ++ ] = getAlpha() * 255 | 0; - - } - - zoffset += zlinestep; - poffset += plinestep; - - } - - } - - function finishClear( ) { - - var block = 0; - - for ( var y = 0; y < canvasHBlocks; y ++ ) { - - for ( var x = 0; x < canvasWBlocks; x ++ ) { - - if ( blockFlags[ block ] & BLOCK_NEEDCLEAR ) { - - clearBlock( x, y ); - blockFlags[ block ] = BLOCK_ISCLEAR; - - } - - block ++; - - } - - } - - } - -}; - -THREE.SoftwareRenderer.Texture = function () { - - var canvas; - - this.fromImage = function ( image ) { - - if ( ! image || image.width <= 0 || image.height <= 0 ) - return; - - if ( canvas === undefined ) { - - canvas = document.createElement( 'canvas' ); - - } - - var size = image.width > image.height ? image.width : image.height; - size = THREE.Math.ceilPowerOfTwo( size ); - - if ( canvas.width != size || canvas.height != size ) { - - canvas.width = size; - canvas.height = size; - - } - - var ctx = canvas.getContext( '2d' ); - ctx.clearRect( 0, 0, size, size ); - ctx.drawImage( image, 0, 0, size, size ); - - var imgData = ctx.getImageData( 0, 0, size, size ); - - this.data = imgData.data; - this.width = size; - this.height = size; - this.srcUrl = image.src; - - }; - -}; diff --git a/examples/js/renderers/WebGLDeferredRenderer.js b/examples/js/renderers/WebGLDeferredRenderer.js deleted file mode 100644 index 56653c6110181b..00000000000000 --- a/examples/js/renderers/WebGLDeferredRenderer.js +++ /dev/null @@ -1,2491 +0,0 @@ -/** - * @author alteredq / http://alteredqualia.com/ - * @author MPanknin / http://www.redplant.de/ - * @author takahiro / https://github.com/takahirox - * - * WebGLDeferredRenderer supports two types of Deferred Renderings. - * One is Classic Deferred Rendering and the other one is - * Light Pre-Pass (Deferred Lighting). - * Classic Deferred Rendering is default. You can use Light Pre-Pass - * by calling .enableLightPrePass( true ) method. - * - * Dependencies - * - THREE.CopyShader - * - THREE.RenderPass - * - THREE.ShaderPass - * - THREE.EffectComposer - * - THREE.FXAAShader - * - * TODO - * - reuse existing glsl - * - shadow - * - optimization - * - MRT (when it's available on Three.js) - * - AmbientLight - * - HemisphereLight - * - PointLight (distance < 0) - * - morphNormals - * - BumpMap - * - ToneMap - * - envMap - * - wrapAround - * - addEffect - */ - -THREE.WebGLDeferredRenderer = function ( parameters ) { - - parameters = parameters || {}; - - // private properties - - var _this = this; - - var _context; - var _state; - - var _width, _height; - - // for Classic Deferred Rendering - var _compColor; - var _passColor, _passForward, _passCopy; - - // for Light Pre-Pass - var _compReconstruction; - var _passReconstruction; - - // for Common - var _compNormalDepth, _compLight, _compFinal; - var _passNormalDepth, _passLight, _passLightFullscreen, _passFinal, _passFXAA; - - var _depthTexture; - - var _currentCamera; - - var _lightScene, _lightFullscreenScene; - - var _antialias = false; - var _hasTransparentObject = false; - var _lightPrePass = false; - var _cacheKeepAlive = false; - - var _tmpMaterial = new THREE.ShaderMaterial( { visible: false } ); - var _tmpVector3 = new THREE.Vector3(); - - // scene/material/light cache for deferred rendering. - // save them at the creation and release - // if they're unused removeThresholdCount frames - // unless _cacheKeepAlive is true. - - // scene.uuid -> lightScene, lightFullscreenScene - var _lightScenesCache = {}; - var _lightFullscreenScenesCache = {}; - - // object.material.uuid -> deferredMaterial or - // object.material[ n ].uuid -> deferredMaterial - var _normalDepthMaterialsCache = {}; - var _normalDepthShininessMaterialsCache = {}; - var _colorMaterialsCache = {}; - var _reconstructionMaterialsCache = {}; - - // originalLight.uuid -> deferredLight - var _deferredLightsCache = {}; - - // deferredLight.uuid -> deferredLightMaterial - var _classicDeferredLightMaterialsCache = {}; - var _lightPrePassMaterialsCache = {}; - - var _removeThresholdCount = 60; - - // deferredMaterials.uuid -> object.material or - // deferredMaterials.uuid -> object.material[ n ] - // save before render and release after render. - var _originalMaterialsTable = {}; - - // object.uuid -> originalOnBeforeRender - // save before render and release after render. - var _originalOnBeforeRendersTable = {}; - - // object.material.uuid -> object.material.visible or - // object.material[ i ].uuid -> object.material[ i ].visible or - // save before render and release after render. - var _originalVisibleTable = {}; - - // external properties - - this.renderer = undefined; - this.domElement = undefined; - - this.forwardRendering = false; // for debug - - // private methods - - function init( parameters ) { - - _this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer(); - _this.domElement = _this.renderer.domElement; - - _context = _this.renderer.getContext(); - _state = _this.renderer.state; - - _width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize( new THREE.Vector2() ).width; - _height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize( new THREE.Vector2() ).height; - - var antialias = parameters.antialias !== undefined ? parameters.antialias : false; - - if ( parameters.cacheKeepAlive !== undefined ) _cacheKeepAlive = parameters.cacheKeepAlive; - - initDepthTexture(); - - initPassNormalDepth(); - initPassColor(); - initPassLight(); - initPassReconstruction(); - initPassFinal(); - - _this.setSize( _width, _height ); - _this.setAntialias( antialias ); - _this.enableLightPrePass( false ); - - } - - function initDepthTexture() { - - _depthTexture = new THREE.DepthTexture( - _width, - _height, - THREE.UnsignedInt248Type, - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - THREE.DepthStencilFormat - ); - - } - - function initPassNormalDepth() { - - _passNormalDepth = new THREE.RenderPass(); - _passNormalDepth.clear = true; - - var rt = new THREE.WebGLRenderTarget( _width, _height, { - minFilter: THREE.NearestFilter, - magFilter: THREE.NearestFilter, - format: THREE.RGBAFormat, - type: THREE.FloatType, - stencilBuffer: true, - depthTexture: _depthTexture - } ); - - rt.texture.generateMipamps = false; - - _compNormalDepth = new THREE.EffectComposer( _this.renderer, rt ); - _compNormalDepth.renderToScreen = false; - _compNormalDepth.addPass( _passNormalDepth ); - - } - - function initPassColor() { - - _passColor = new THREE.RenderPass(); - _passColor.clear = true; - - var rt = new THREE.WebGLRenderTarget( _width, _height, { - minFilter: THREE.NearestFilter, - magFilter: THREE.NearestFilter, - format: THREE.RGBAFormat, - type: THREE.FloatType, - depthTexture: _depthTexture - } ); - - rt.texture.generateMipamps = false; - - _compColor = new THREE.EffectComposer( _this.renderer, rt ); - _compColor.renderToScreen = false; - _compColor.addPass( _passColor ); - - } - - function initPassLight() { - - _passLightFullscreen = new THREE.RenderPass(); - _passLightFullscreen.clear = true; - _passLightFullscreen.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); - - _passLight = new THREE.RenderPass(); - _passLight.clear = false; - - var rt = new THREE.WebGLRenderTarget( _width, _height, { - minFilter: THREE.NearestFilter, - magFilter: THREE.NearestFilter, - format: THREE.RGBAFormat, - type: THREE.FloatType, - depthTexture: _depthTexture - } ); - - rt.texture.generateMipamps = false; - - _compLight = new THREE.EffectComposer( _this.renderer, rt ); - _compLight.renderToScreen = false; - _compLight.addPass( _passLightFullscreen ); - _compLight.addPass( _passLight ); - - } - - function initPassReconstruction() { - - _passReconstruction = new THREE.RenderPass(); - _passReconstruction.clear = true; - - var rt = new THREE.WebGLRenderTarget( _width, _height, { - minFilter: THREE.NearestFilter, - magFilter: THREE.NearestFilter, - format: THREE.RGBAFormat, - type: THREE.FloatType, - depthTexture: _depthTexture - } ); - - rt.texture.generateMipamps = false; - - _compReconstruction = new THREE.EffectComposer( _this.renderer, rt ); - _compReconstruction.renderToScreen = false; - _compReconstruction.addPass( _passReconstruction ); - - } - - function initPassFinal() { - - _passFinal = new THREE.ShaderPass( THREE.ShaderDeferred[ 'final' ] ); - _passFinal.clear = true; - _passFinal.uniforms.samplerResult.value = _compLight.renderTarget2.texture; - _passFinal.material.blending = THREE.NoBlending; - _passFinal.material.depthWrite = false; - _passFinal.material.depthTest = false; - - _passForward = new THREE.RenderPass(); - _passForward.clear = false; - - _passCopy = new THREE.ShaderPass( THREE.CopyShader ); - - _passFXAA = new THREE.ShaderPass( THREE.FXAAShader ); - - var rt = new THREE.WebGLRenderTarget( _width, _height, { - minFilter: THREE.NearestFilter, - magFilter: THREE.LinearFilter, - format: THREE.RGBFormat, - type: THREE.UnsignedByteType, - depthTexture: _depthTexture - } ); - - rt.texture.generateMipamps = false; - - _compFinal = new THREE.EffectComposer( _this.renderer, rt ); - _compFinal.addPass( _passFinal ); - _compFinal.addPass( _passForward ); - _compFinal.addPass( _passCopy ); - _compFinal.addPass( _passFXAA ); - - } - - function initLightScene( scene ) { - - var lightSceneData = _lightScenesCache[ scene.uuid ]; - var lightFullscreenSceneData = _lightFullscreenScenesCache[ scene.uuid ]; - - if ( lightSceneData === undefined ) { - - var s = new THREE.Scene(); - s.userData.lights = {}; - - lightSceneData = createCacheData(); - lightSceneData.scene = s; - - _lightScenesCache[ scene.uuid ] = lightSceneData; - - } - - if ( lightFullscreenSceneData === undefined ) { - - var s = new THREE.Scene(); - s.userData.lights = {}; - - var emissiveLight = createDeferredEmissiveLight(); - - s.userData.emissiveLight = emissiveLight; - s.add( emissiveLight ); - - lightFullscreenSceneData = createCacheData(); - lightFullscreenSceneData.scene = s; - - _lightFullscreenScenesCache[ scene.uuid ] = lightFullscreenSceneData; - - } - - lightSceneData.used = true; - lightFullscreenSceneData.used = true; - - var lightScene = lightSceneData.scene; - var lightFullscreenScene = lightFullscreenSceneData.scene; - - // emissiveLight is only for Classic Deferred Rendering - lightFullscreenScene.userData.emissiveLight.visible = ! _lightPrePass; - - _lightScene = lightScene; - _lightFullscreenScene = lightFullscreenScene; - - } - - function getMaterialFromCacheOrCreate( originalMaterial, cache, createFunc, updateFunc ) { - - var data = cache[ originalMaterial.uuid ]; - - if ( data === undefined ) { - - data = createCacheData(); - data.material = createFunc( originalMaterial ); - cache[ originalMaterial.uuid ] = data; - - } - - data.used = true; - - updateFunc( data.material, originalMaterial ); - - _originalMaterialsTable[ data.material.uuid ] = originalMaterial; - - return data.material; - - } - - function overrideMaterialAndOnBeforeRender( object, getMaterialFunc, onBeforeRender ) { - - if ( object.material === undefined ) return; - - if ( Array.isArray( object.material ) ) { - - for ( var i = 0, il = object.material.length; i < il; i ++ ) { - - object.material[ i ] = getMaterialFunc( object.material[ i ] ); - - } - - } else { - - object.material = getMaterialFunc( object.material ); - - } - - object.onBeforeRender = onBeforeRender; - - } - - function restoreOriginalMaterial( object ) { - - if ( object.material === undefined ) return; - - if ( Array.isArray( object.material ) ) { - - for ( var i = 0, il = object.material.length; i < il; i ++ ) { - - object.material[ i ] = _originalMaterialsTable[ object.material[ i ].uuid ]; - - } - - } else { - - object.material = _originalMaterialsTable[ object.material.uuid ]; - - } - - } - - function setMaterialNormalDepth( object ) { - - overrideMaterialAndOnBeforeRender( object, getNormalDepthMaterial, updateDeferredNormalDepthUniforms ); - - } - - function getNormalDepthMaterial( originalMaterial ) { - - return getMaterialFromCacheOrCreate( - originalMaterial, - ( _lightPrePass ) ? _normalDepthShininessMaterialsCache : _normalDepthMaterialsCache, - createDeferredNormalDepthMaterial, - updateDeferredNormalDepthMaterial - ); - - } - - function createDeferredNormalDepthMaterial() { - - var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'normalDepthShininess' ] : THREE.ShaderDeferred[ 'normalDepth' ]; - - return new THREE.ShaderMaterial( { - uniforms: Object.assign( {}, shader.uniforms ), - fragmentShader: shader.fragmentShader, - vertexShader: shader.vertexShader, - blending: THREE.NoBlending - } ); - - } - - function updateDeferredNormalDepthMaterial( material, originalMaterial ) { - - if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning; - if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets; - - if ( originalMaterial.visible === true ) { - - material.visible = ! originalMaterial.transparent; - - } else { - - material.visible = false; - - } - - } - - function updateDeferredNormalDepthUniforms( renderer, scene, camera, geometry, material ) { - - if ( ! _lightPrePass ) return; - - var originalMaterial = _originalMaterialsTable[ material.uuid ]; - - if ( originalMaterial === undefined || originalMaterial.shininess === undefined ) return; - - material.uniforms.shininess.value = originalMaterial.shininess; - - } - - function setMaterialColor( object ) { - - overrideMaterialAndOnBeforeRender( object, getColorMaterial, updateDeferredColorUniforms ); - - } - - function getColorMaterial( originalMaterial ) { - - return getMaterialFromCacheOrCreate( - originalMaterial, - _colorMaterialsCache, - createDeferredColorMaterial, - updateDeferredColorMaterial - ); - - } - - function createDeferredColorMaterial( originalMaterial ) { - - var shader = THREE.ShaderDeferred[ 'color' ]; - - var material = new THREE.ShaderMaterial( { - uniforms: Object.assign( {}, shader.uniforms ), - fragmentShader: shader.fragmentShader, - vertexShader: shader.vertexShader, - blending: THREE.NoBlending - } ); - - if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map; - - return material; - - } - - function updateDeferredColorMaterial( material, originalMaterial ) { - - if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map; - if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning; - if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets; - - if ( originalMaterial.visible === true ) { - - material.visible = ! originalMaterial.transparent; - - } else { - - material.visible = false; - - } - - } - - function updateDeferredColorUniforms( renderer, scene, camera, geometry, material ) { - - var originalMaterial = _originalMaterialsTable[ material.uuid ]; - var uniforms = material.uniforms; - - var diffuse, emissive; - - if ( originalMaterial.isMeshBasicMaterial === true ) { - - emissive = originalMaterial.color; - - } else { - - diffuse = originalMaterial.color; - emissive = originalMaterial.emissive; - - } - - var specular = originalMaterial.specular; - var shininess = originalMaterial.shininess; - var map = originalMaterial.map; - - if ( diffuse !== undefined ) uniforms.diffuse.value.copy( diffuse ); - if ( emissive !== undefined ) uniforms.emissive.value.copy( emissive ); - if ( specular !== undefined ) uniforms.specular.value.copy( specular ); - if ( shininess !== undefined && uniforms.shininess !== undefined ) uniforms.shininess.value = shininess; - if ( map !== undefined ) uniforms.map.value = map; - - } - - function setMaterialReconstruction( object ) { - - overrideMaterialAndOnBeforeRender( object, getReconstructionMaterial, updateDeferredReconstructionUniforms ); - - } - - function getReconstructionMaterial( originalMaterial ) { - - if ( originalMaterial.transparent === true ) { - - _originalMaterialsTable[ originalMaterial.uuid ] = originalMaterial; - return originalMaterial; - - } - - return getMaterialFromCacheOrCreate( - originalMaterial, - _reconstructionMaterialsCache, - createDeferredReconstructionMaterial, - updateDeferredReconstructionMaterial - ); - - } - - function createDeferredReconstructionMaterial( originalMaterial ) { - - var shader = THREE.ShaderDeferred[ 'reconstruction' ]; - - var material = new THREE.ShaderMaterial( { - uniforms: Object.assign( {}, shader.uniforms ), - fragmentShader: shader.fragmentShader, - vertexShader: shader.vertexShader, - blending: THREE.NoBlending - } ); - - if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map; - - return material; - - } - - function updateDeferredReconstructionMaterial( material, originalMaterial ) { - - updateDeferredColorMaterial( material, originalMaterial ); - - } - - function updateDeferredReconstructionUniforms( renderer, scene, camera, geometry, material, group ) { - - if ( material.transparent === true ) { - - // 'this' is object here because this method is set as object.onBefore() - var onBeforeRender = _originalOnBeforeRendersTable[ this.uuid ]; - - if ( onBeforeRender ) { - - onBeforeRender.call( this, renderer, scene, camera, geometry, material, group ); - - } - - return; - - } - - updateDeferredColorUniforms( renderer, scene, camera, geometry, material ); - - material.uniforms.samplerLight.value = _compLight.renderTarget2.texture; - - } - - function setVisibleForForwardRendering( object ) { - - if ( object.material === undefined ) return; - - if ( Array.isArray( object.material ) ) { - - for ( var i = 0, il = object.material.length; i < il; i ++ ) { - - if ( _originalVisibleTable[ object.material[ i ].uuid ] === undefined ) { - - _originalVisibleTable[ object.material[ i ].uuid ] = object.material[ i ].visible; - object.material[ i ].visible = object.material[ i ].transparent && object.material[ i ].visible; - - } - - } - - } else { - - if ( _originalVisibleTable[ object.material.uuid ] === undefined ) { - - _originalVisibleTable[ object.material.uuid ] = object.material.visible; - object.material.visible = object.material.transparent && object.material.visible; - - } - - } - - } - - function restoreVisible( object ) { - - if ( object.material === undefined ) return; - - if ( Array.isArray( object.material ) ) { - - for ( var i = 0, il = object.material.length; i < il; i ++ ) { - - object.material[ i ].visible = _originalVisibleTable[ object.material[ i ].uuid ]; - - } - - } else { - - object.material.visible = _originalVisibleTable[ object.material.uuid ]; - - } - - } - - function createDeferredEmissiveLight() { - - var shader = THREE.ShaderDeferred[ 'emissiveLight' ]; - - var material = new THREE.ShaderMaterial( { - uniforms: Object.assign( {}, shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader, - blending: THREE.NoBlending, - depthWrite: false - } ); - - var geometry = new THREE.PlaneBufferGeometry( 2, 2 ); - var mesh = new THREE.Mesh( geometry, material ); - - mesh.onBeforeRender = function ( renderer, scene, camera, geometry, material ) { - - material.uniforms.samplerColor.value = _compColor.renderTarget2.texture; - - }; - - return mesh; - - } - - function createDeferredLight( originalLight ) { - - if ( originalLight.isPointLight ) { - - return createDeferredPointLight( originalLight ); - - } else if ( originalLight.isSpotLight ) { - - return createDeferredSpotLight( originalLight ); - - } else if ( originalLight.isDirectionalLight ) { - - return createDeferredDirectionalLight( originalLight ); - - } - - return null; - - } - - function createDeferredLightMaterial( originalLight ) { - - if ( originalLight.isPointLight ) { - - return createDeferredPointLightMaterial(); - - } else if ( originalLight.isSpotLight ) { - - return createDeferredSpotLightMaterial(); - - } else if ( originalLight.isDirectionalLight ) { - - return createDeferredDirectionalLightMaterial(); - - } - - return null; - - } - - function getDeferredLightMaterial( light ) { - - var cache = ( _lightPrePass ) ? _lightPrePassMaterialsCache : _classicDeferredLightMaterialsCache; - - var data = cache[ light.uuid ]; - - if ( data === undefined ) { - - data = createCacheData(); - data.material = createDeferredLightMaterial( light.userData.originalLight ); - cache[ light.uuid ] = data; - - } - - data.used = true; - - return data.material; - - } - - function updateDeferredLight( light ) { - - var originalLight = light.userData.originalLight; - - if ( originalLight.isPointLight ) { - - updateDeferredPointLight( light ); - - } - - } - - function createDeferredLightMesh( light, geometry ) { - - var mesh = new THREE.Mesh( geometry, _tmpMaterial ); - - mesh.userData.originalLight = light; - - return mesh; - - } - - function createDeferredLightShaderMaterial( shader ) { - - var material = new THREE.ShaderMaterial( { - uniforms: Object.assign( {}, shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader, - transparent: true, - blending: THREE.AdditiveBlending, - depthWrite: false - } ); - - if ( _lightPrePass ) material.premultipliedAlpha = true; - - return material; - - } - - function updateDeferredLightCommonUniforms( uniforms ) { - - if ( _lightPrePass ) { - - uniforms.samplerNormalDepthShininess.value = _compNormalDepth.renderTarget2.texture; - - } else { - - uniforms.samplerNormalDepth.value = _compNormalDepth.renderTarget2.texture; - uniforms.samplerColor.value = _compColor.renderTarget2.texture; - - } - - } - - function createDeferredPointLight( light ) { - - var mesh = createDeferredLightMesh( light, new THREE.SphereBufferGeometry( 1, 16, 8 ) ); - mesh.onBeforeRender = updateDeferredPointLightUniforms; - return mesh; - - } - - /* - * optimization: - * Renders PointLight only back face with stencil test. - */ - function createDeferredPointLightMaterial() { - - var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'pointLightPre' ] : THREE.ShaderDeferred[ 'pointLight' ]; - - var material = createDeferredLightShaderMaterial( shader ); - - material.side = THREE.BackSide; - material.depthFunc = THREE.GreaterEqualDepth; - - return material; - - } - - function updateDeferredPointLight( light ) { - - var originalLight = light.userData.originalLight; - var distance = originalLight.distance; - - if ( distance > 0 ) { - - light.scale.set( 1, 1, 1 ).multiplyScalar( distance ); - light.position.setFromMatrixPosition( originalLight.matrixWorld ); - - } - - } - - function updateDeferredPointLightUniforms( renderer, scene, camera, geometry, material ) { - - var light = this; - - var originalLight = light.userData.originalLight; - var distance = originalLight.distance; - var uniforms = material.uniforms; - - uniforms.lightColor.value.copy( originalLight.color ); - - if ( distance > 0 ) { - - uniforms.lightRadius.value = distance; - uniforms.lightIntensity.value = originalLight.intensity; - uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( _currentCamera.matrixWorldInverse ); - - } else { - - uniforms.lightRadius.value = Infinity; - - } - - updateDeferredLightCommonUniforms( uniforms ); - - } - - function createDeferredSpotLight( light ) { - - var mesh = createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) ); - mesh.onBeforeRender = updateDeferredSpotLightUniforms; - return mesh; - - } - - function createDeferredSpotLightMaterial() { - - var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'spotLightPre' ] : THREE.ShaderDeferred[ 'spotLight' ]; - - var material = createDeferredLightShaderMaterial( shader ); - - material.depthTest = false; - - return material; - - } - - function updateDeferredSpotLightUniforms() { - - var light = this; - - var originalLight = light.userData.originalLight; - var uniforms = light.material.uniforms; - - uniforms.lightAngle.value = originalLight.angle; - uniforms.lightColor.value.copy( originalLight.color ); - uniforms.lightIntensity.value = originalLight.intensity; - uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( _currentCamera.matrixWorldInverse ); - - var vec = uniforms.lightDirectionVS.value; - var vec2 = _tmpVector3; - - vec.setFromMatrixPosition( originalLight.matrixWorld ); - vec2.setFromMatrixPosition( originalLight.target.matrixWorld ); - vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse ); - - updateDeferredLightCommonUniforms( uniforms ); - - } - - function createDeferredDirectionalLight( light ) { - - var mesh = createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) ); - mesh.onBeforeRender = updateDeferredDirectionalLightUniforms; - return mesh; - - } - - function createDeferredDirectionalLightMaterial() { - - var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'directionalLightPre' ] : THREE.ShaderDeferred[ 'directionalLight' ]; - - var material = createDeferredLightShaderMaterial( shader ); - - material.depthTest = false; - - return material; - - } - - function updateDeferredDirectionalLightUniforms() { - - var light = this; - - var originalLight = light.userData.originalLight; - var uniforms = light.material.uniforms; - - uniforms.lightColor.value.copy( originalLight.color ); - uniforms.lightIntensity.value = originalLight.intensity; - - var vec = uniforms.lightDirectionVS.value; - var vec2 = _tmpVector3; - - vec.setFromMatrixPosition( originalLight.matrixWorld ); - vec2.setFromMatrixPosition( originalLight.target.matrixWorld ); - vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse ); - - updateDeferredLightCommonUniforms( uniforms ); - - } - - function saveOriginalOnBeforeRenderAndCheckTransparency( object ) { - - if ( object.material === undefined ) return; - - _originalOnBeforeRendersTable[ object.uuid ] = object.onBeforeRender; - - // _hasTransparentObject is used only for Classic Deferred Rendering - if ( _hasTransparentObject || _lightPrePass ) return; - - if ( ! object.visible ) return; - - if ( Array.isArray( object.material ) ) { - - for ( var i = 0, il = object.material.length; i < il; i ++ ) { - - if ( object.material[ i ].visible === true && object.material[ i ].transparent === true ) { - - _hasTransparentObject = true; - break; - - } - - } - - } else { - - if ( object.material.visible === true && object.material.transparent === true ) _hasTransparentObject = true; - - } - - } - - function restoreOriginalOnBeforeRender( object ) { - - if ( object.material === undefined ) return; - - object.onBeforeRender = _originalOnBeforeRendersTable[ object.uuid ]; - - } - - function addDeferredLightsToLightScene( object ) { - - if ( object.isLight !== true ) return; - - var data = _deferredLightsCache[ object.uuid ]; - - if ( data === undefined ) { - - data = createCacheData(); - data.light = createDeferredLight( object ); - _deferredLightsCache[ object.uuid ] = data; - - } - - data.used = true; - - var light = data.light; - - if ( light === null ) return; - - var scene = ( object.isPointLight === true ) ? _lightScene : _lightFullscreenScene; - - var lights = scene.userData.lights; - - if ( lights[ light.uuid ] === undefined ) { - - scene.add( light ); - - lights[ light.uuid ] = { - light: light, - found: true - }; - - } - - lights[ light.uuid ].found = true; - - } - - function updateDeferredLightsInLightScene( scene ) { - - var lights = scene.userData.lights; - var keys = Object.keys( lights ); - - for ( var i = 0, il = keys.length; i < il; i ++ ) { - - var key = keys[ i ]; - - if ( lights[ key ].found === false ) { - - scene.remove( lights[ key ].light ); - delete lights[ key ]; - - } else { - - var light = lights[ key ].light; - light.material = getDeferredLightMaterial( light ); - - updateDeferredLight( light ); - lights[ key ].found = false; - - } - - } - - } - - function updateDeferredCommonUniforms( camera ) { - - var uniforms = THREE.ShaderDeferredCommon[ 'commonUniforms' ]; - - uniforms.viewWidth.value = _width; - uniforms.viewHeight.value = _height; - - uniforms.matProjInverse.value.getInverse( camera.projectionMatrix ); - - } - - function enableFinalPasses() { - - if ( _lightPrePass ) { - - _passForward.enabled = false; - _passCopy.enabled = false; - - if ( _antialias ) { - - _passFXAA.enabled = true; - - } else { - - _passFXAA.enabled = false; - - } - - } else { - - if ( _hasTransparentObject ) { - - if ( _antialias ) { - - _passForward.enabled = true; - _passCopy.enabled = false; - _passFXAA.enabled = true; - - } else { - - _passForward.enabled = true; - _passCopy.enabled = true; - _passFXAA.enabled = false; - - } - - } else { - - if ( _antialias ) { - - _passForward.enabled = false; - _passCopy.enabled = false; - _passFXAA.enabled = true; - - } else { - - _passForward.enabled = false; - _passCopy.enabled = false; - _passFXAA.enabled = false; - - } - - } - - } - - } - - function createCacheData() { - - return { - used: true, - keepAlive: _cacheKeepAlive, - count: 0 - }; - - } - - function cleanupCache( cache ) { - - var keys = Object.keys( cache ); - - for ( var i = 0, il = keys.length; i < il; i ++ ) { - - var key = keys[ i ]; - - if ( cache[ key ].used === false ) { - - cache[ key ].count ++; - - if ( cache[ key ].keepAlive === false && cache[ key ].count > _removeThresholdCount ) { - - delete cache[ key ]; - - } - - } else { - - cache[ key ].used = false; - cache[ key ].count = 0; - - } - - } - - } - - function cleanupTable( table ) { - - var keys = Object.keys( table ); - - for ( var i = 0, il = keys.length; i < il; i ++ ) { - - var key = keys[ i ]; - - table[ key ] = undefined; - - } - - } - - function cleanupCaches() { - - cleanupCache( _lightScenesCache ); - cleanupCache( _lightFullscreenScenesCache ); - cleanupCache( _normalDepthMaterialsCache ); - cleanupCache( _normalDepthShininessMaterialsCache ); - cleanupCache( _colorMaterialsCache ); - cleanupCache( _reconstructionMaterialsCache ); - cleanupCache( _classicDeferredLightMaterialsCache ); - cleanupCache( _lightPrePassMaterialsCache ); - cleanupCache( _deferredLightsCache ); - - cleanupTable( _originalMaterialsTable ); - cleanupTable( _originalOnBeforeRendersTable ); - cleanupTable( _originalVisibleTable ); - - } - - /* - * Classic Deferred Rendering - * - * 1) g-buffer normal + depth pass - * - * RGB: normal - * A: depth - * - * - * Light Pre-Pass Rendering - * - * 1') g-buffer normal + depth pass + shininess - * - * RG: normal - * B: shininess - * A: depth - */ - - function renderNormalDepth( scene, camera ) { - - scene.traverse( setMaterialNormalDepth ); - - _passNormalDepth.scene = scene; - _passNormalDepth.camera = camera; - - _this.renderer.autoClearDepth = true; - _this.renderer.autoClearStencil = true; - - _state.buffers.stencil.setTest( true ); - _state.buffers.stencil.setFunc( _context.ALWAYS, 1, 0xffffffff ); - _state.buffers.stencil.setOp( _context.REPLACE, _context.REPLACE, _context.REPLACE ); - - _compNormalDepth.render(); - - scene.traverse( restoreOriginalMaterial ); - - } - - /* - * Classic Deferred Rendering - * - * 2) g-buffer color pass - * - * R: diffuse - * G: emissive - * B: specular - * A: shininess - */ - - function renderColor( scene, camera ) { - - scene.traverse( setMaterialColor ); - - _passColor.scene = scene; - _passColor.camera = camera; - - _this.renderer.autoClearDepth = false; - _this.renderer.autoClearStencil = false; - - _state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff ); - _state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP ); - - _compColor.render(); - - scene.traverse( restoreOriginalMaterial ); - - } - - /* - * Classic Deferred Rendering - * - * 3) light pass - */ - - function renderLight( scene, camera ) { - - scene.traverse( addDeferredLightsToLightScene ); - - updateDeferredLightsInLightScene( _lightScene ); - updateDeferredLightsInLightScene( _lightFullscreenScene ); - - _passLight.scene = _lightScene; - _passLight.camera = camera; - - _passLightFullscreen.scene = _lightFullscreenScene; - - _this.renderer.autoClearDepth = false; - _this.renderer.autoClearStencil = false; - - _compLight.render(); - - _state.buffers.stencil.setTest( false ); - - } - - /* - * Light Pre-Pass Rendering - * - * 2') Light pre pass - */ - - function renderLightPre( scene, camera ) { - - scene.traverse( addDeferredLightsToLightScene ); - - updateDeferredLightsInLightScene( _lightScene ); - updateDeferredLightsInLightScene( _lightFullscreenScene ); - - _passLight.scene = _lightScene; - _passLight.camera = camera; - - _passLightFullscreen.scene = _lightFullscreenScene; - - _this.renderer.autoClearDepth = false; - _this.renderer.autoClearStencil = false; - - _state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff ); - _state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP ); - - _compLight.render(); - - } - - /* - * Light Pre-Pass Rendering - * - * 3') Reconstruction pass - * - * Transprency handling: - * Here renders transparent objects with normal forward rendering. - */ - - function renderReconstruction( scene, camera ) { - - scene.traverse( setMaterialReconstruction ); - - _passReconstruction.scene = scene; - _passReconstruction.camera = camera; - - _this.renderer.autoClearDepth = false; - _this.renderer.autoClearStencil = false; - - _compReconstruction.render(); - - _state.buffers.stencil.setTest( false ); - - scene.traverse( restoreOriginalMaterial ); - - } - - /* - * Classic Deferred Rendering - * - * 4) Final pass - * - * transparency handling: - * If there's any transparent objects, here renders them on the deferred rendering result - * with normal forward rendering. This may be the easist way but heavy. - * We should consider any better ways someday. - * - * - * Light Pre-Pass Rendering - * - * 4') Final pass - * - * - * Common - * - * antialias handling: - * Here uses postprocessing FXAA for antialias. - * - */ - - function renderFinal( scene, camera ) { - - if ( ! _lightPrePass && _hasTransparentObject ) { - - scene.traverse( setVisibleForForwardRendering ); - scene.traverse( restoreOriginalOnBeforeRender ); - - _passForward.scene = scene; - _passForward.camera = camera; - - } - - enableFinalPasses(); - - _this.renderer.autoClearDepth = false; - _this.renderer.autoClearStencil = false; - - _compFinal.render(); - - if ( ! _lightPrePass && _hasTransparentObject ) { - - scene.traverse( restoreVisible ); - - } - - } - - // external APIs - - this.setSize = function ( width, height ) { - - _width = width; - _height = height; - - this.renderer.setSize( _width, _height ); - - _compNormalDepth.setSize( _width, _height ); - _compColor.setSize( _width, _height ); - _compLight.setSize( _width, _height ); - _compReconstruction.setSize( _width, _height ); - _compFinal.setSize( _width, _height ); - - _depthTexture.image.width = _width; - _depthTexture.image.height = _height; - _depthTexture.needsUpdate = true; - - _passFXAA.uniforms.resolution.value.set( 1 / _width, 1 / _height ); - - }; - - this.setAntialias = function ( enabled ) { - - _antialias = enabled; - - }; - - this.enableLightPrePass = function ( enabled ) { - - _lightPrePass = enabled; - - _passFinal.uniforms.samplerResult.value = ( _lightPrePass ) ? _compReconstruction.renderTarget2.texture : _compLight.renderTarget2.texture; - - }; - - this.render = function ( scene, camera ) { - - // for debug to compare with normal forward rendering - - if ( this.forwardRendering ) { - - this.renderer.render( scene, camera ); - return; - - } - - var currentSceneAutoUpdate = scene.autoUpdate; - var currentAutoClearColor = this.renderer.autoClearColor; - var currentAutoClearDepth = this.renderer.autoClearDepth; - var currentAutoClearStencil = this.renderer.autoClearStencil; - - _currentCamera = camera; - - initLightScene( scene ); - - scene.autoUpdate = false; - scene.updateMatrixWorld(); - - _hasTransparentObject = false; - - scene.traverse( saveOriginalOnBeforeRenderAndCheckTransparency ); - - updateDeferredCommonUniforms( camera ); - - renderNormalDepth( scene, camera ); - - if ( _lightPrePass ) { - - renderLightPre( scene, camera ); - renderReconstruction( scene, camera ); - - } else { - - renderColor( scene, camera ); - renderLight( scene, camera ); - - } - - renderFinal( scene, camera ); - - scene.traverse( restoreOriginalOnBeforeRender ); - - cleanupCaches(); - - scene.autoUpdate = currentSceneAutoUpdate; - this.renderer.autoClearColor = currentAutoClearColor; - this.renderer.autoClearDepth = currentAutoClearDepth; - this.renderer.autoClearStencil = currentAutoClearStencil; - - }; - - // initialize - - init( parameters ); - -}; - -THREE.DeferredShaderChunk = { - - packVector3: [ - - "float vec3_to_float( vec3 data ) {", - - " const float unit = 255.0/256.0;", - " highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;", - " return compressed;", - - "}" - - ].join( "\n" ), - - unpackFloat: [ - - "vec3 float_to_vec3( float data ) {", - - " const float unit = 255.0;", - " vec3 uncompressed;", - " uncompressed.x = fract( data );", - " float zInt = floor( data / unit );", - " uncompressed.z = fract( zInt / unit );", - " uncompressed.y = fract( floor( data - ( zInt * unit ) ) / unit );", - " return uncompressed;", - - "}" - - ].join( "\n" ), - - // Refer to http://aras-p.info/texts/CompactNormalStorage.html - packNormal: [ - - "vec2 normal_to_vec2( vec3 normal ) {", - - " return normal.xy / sqrt( normal.z * 8.0 + 8.0 ) + 0.5;", - - "}" - - ].join( "\n" ), - - unpackVector2: [ - - "vec3 vec2_to_normal( vec2 data ) {", - - " vec2 fenc = data * 4.0 - 2.0;", - " float f = dot( fenc, fenc );", - " float g = sqrt( 1.0 - f / 4.0 );", - " vec3 normal;", - " normal.xy = fenc * g;", - " normal.z = 1.0 - f / 2.0;", - " return normal;", - - "}" - - ].join( "\n" ), - - computeTextureCoord: [ - - "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );" - - ].join( "\n" ), - - packNormalDepth: [ - - "vec4 packedNormalDepth;", - "packedNormalDepth.xyz = normal * 0.5 + 0.5;", - "packedNormalDepth.w = position.z / position.w;" - - ].join( "\n" ), - - unpackNormalDepth: [ - - "vec4 normalDepthMap = texture2D( samplerNormalDepth, texCoord );", - "float depth = normalDepthMap.w;", - - "if ( depth == 0.0 ) discard;", - - "vec3 normal = normalDepthMap.xyz * 2.0 - 1.0;" - - ].join( "\n" ), - - packNormalDepthShininess: [ - - "vec4 packedNormalDepthShininess;", - "packedNormalDepthShininess.xy = normal_to_vec2( normal );", - "packedNormalDepthShininess.z = shininess;", - "packedNormalDepthShininess.w = position.z / position.w;" - - ].join( "\n" ), - - unpackNormalDepthShininess: [ - - "vec4 normalDepthMap = texture2D( samplerNormalDepthShininess, texCoord );", - "float depth = normalDepthMap.w;", - - "if ( depth == 0.0 ) discard;", - - "vec3 normal = vec2_to_normal( normalDepthMap.xy );", - "float shininess = normalDepthMap.z;" - - ].join( "\n" ), - - packColor: [ - - "vec4 packedColor;", - "packedColor.x = vec3_to_float( diffuseColor.rgb );", - "packedColor.y = vec3_to_float( emissiveColor );", - "packedColor.z = vec3_to_float( specularColor );", - "packedColor.w = shininess;" - - ].join( "\n" ), - - unpackColor: [ - - "vec4 colorMap = texture2D( samplerColor, texCoord );", - "vec3 diffuseColor = float_to_vec3( colorMap.x );", - "vec3 emissiveColor = float_to_vec3( colorMap.y );", - "vec3 specularColor = float_to_vec3( colorMap.z );", - "float shininess = colorMap.w;" - - ].join( "\n" ), - - packLight: [ - - "vec4 packedLight;", - "packedLight.xyz = lightIntensity * lightColor * max( dot( lightVector, normal ), 0.0 ) * attenuation;", - "packedLight.w = lightIntensity * specular * max( dot( lightVector, normal ), 0.0 ) * attenuation;" - - ].join( "\n" ), - - computeVertexPositionVS: [ - - "vec2 xy = texCoord * 2.0 - 1.0;", - "vec4 vertexPositionProjected = vec4( xy, depth, 1.0 );", - "vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;", - "vertexPositionVS.xyz /= vertexPositionVS.w;", - "vertexPositionVS.w = 1.0;" - - ].join( "\n" ), - - // TODO: calculate schlick - computeSpecular: [ - - "vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );", - "float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );", - "float specular = 0.31830988618 * ( shininess * 0.5 + 1.0 ) * pow( dotNormalHalf, shininess );" - - ].join( "\n" ), - - combine: [ - - "gl_FragColor = vec4( lightIntensity * lightColor * max( dot( lightVector, normal ), 0.0 ) * ( diffuseColor + specular * specularColor ) * attenuation, 1.0 );" - - ].join( "\n" ) - -}; - -THREE.ShaderDeferredCommon = { - - commonUniforms: { - - matProjInverse: new THREE.Uniform( new THREE.Matrix4() ), - - viewWidth: new THREE.Uniform( 800 ), - viewHeight: new THREE.Uniform( 600 ) - - } - -}; - -THREE.ShaderDeferred = { - - normalDepth: { - - uniforms: {}, - - vertexShader: [ - - "varying vec3 vNormal;", - "varying vec4 vPosition;", - - "#include ", - "#include ", - - "void main() {", - - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - - " vNormal = normalize( transformedNormal );", - " vPosition = gl_Position;", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "varying vec3 vNormal;", - "varying vec4 vPosition;", - - "void main() {", - - " vec3 normal = vNormal;", - " vec4 position = vPosition;", - - THREE.DeferredShaderChunk[ "packNormalDepth" ], - - " gl_FragColor = packedNormalDepth;", - - "}" - - ].join( "\n" ) - - }, - - color: { - - uniforms: { - - map: new THREE.Uniform( null ), - offsetRepeat: new THREE.Uniform( new THREE.Vector4( 0, 0, 1, 1 ) ), - - diffuse: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - emissive: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - specular: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - shininess: new THREE.Uniform( 30.0 ) - - }, - - vertexShader: [ - - "#include ", - "#include ", - "#include ", - - "void main() {", - - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform vec3 emissive;", - "uniform vec3 specular;", - "uniform float shininess;", - - "#include ", - "#include ", - THREE.DeferredShaderChunk[ "packVector3" ], - - "void main() {", - - " vec4 diffuseColor = vec4( diffuse, 1.0 );", - " vec3 emissiveColor = emissive;", - " vec3 specularColor = specular;", - - "#include ", - THREE.DeferredShaderChunk[ "packColor" ], - - " gl_FragColor = packedColor;", - - "}" - - ].join( "\n" ) - - }, - - emissiveLight: { - - uniforms: Object.assign( - - { - - samplerColor: new THREE.Uniform( null ) - - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - vertexShader: [ - - "void main() { ", - - " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );", - - "}" - - ].join( '\n' ), - - fragmentShader: [ - - "uniform sampler2D samplerColor;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - - "void main() {", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - THREE.DeferredShaderChunk[ "unpackColor" ], - - " gl_FragColor = vec4( emissiveColor, 1.0 );", - - "}" - - ].join( '\n' ) - - }, - - pointLight: { - - uniforms: Object.assign( - - { - - samplerNormalDepth: new THREE.Uniform( null ), - samplerColor: new THREE.Uniform( null ), - - lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightIntensity: new THREE.Uniform( 1.0 ), - lightRadius: new THREE.Uniform( 1.0 ) - - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - vertexShader: [ - - "void main() {", - - " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform sampler2D samplerNormalDepth;", - "uniform sampler2D samplerColor;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - "uniform vec3 lightColor;", - "uniform vec3 lightPositionVS;", - "uniform float lightIntensity;", - "uniform float lightRadius;", - - "uniform mat4 matProjInverse;", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - - "void main() {", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - THREE.DeferredShaderChunk[ "unpackNormalDepth" ], - THREE.DeferredShaderChunk[ "computeVertexPositionVS" ], - - " vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;", - " float distance = length( lightVector );", - - " if ( distance > lightRadius ) discard;", - - " lightVector = normalize( lightVector );", - - THREE.DeferredShaderChunk[ "unpackColor" ], - THREE.DeferredShaderChunk[ "computeSpecular" ], - - " //float cutoff = 0.3;", - " //float denom = distance / lightRadius + 1.0;", - " //float attenuation = 1.0 / ( denom * denom );", - " //attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );", - " //attenuation = max( attenuation, 0.0 );", - " //attenuation *= attenuation;", - - " //diffuseColor *= saturate( -distance / lightRadius + 1.0 );", - " //float attenuation = 1.0;", - - " float attenuation = saturate( -distance / lightRadius + 1.0 );", - - THREE.DeferredShaderChunk[ "combine" ], - - "}" - - ].join( "\n" ) - - }, - - spotLight: { - - uniforms: Object.assign( - - { - - samplerNormalDepth: new THREE.Uniform( null ), - samplerColor: new THREE.Uniform( null ), - - lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightAngle: new THREE.Uniform( 1.0 ), - lightIntensity: new THREE.Uniform( 1.0 ) - - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - vertexShader: [ - - "void main() { ", - - " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform sampler2D samplerNormalDepth;", - "uniform sampler2D samplerColor;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - "uniform vec3 lightColor;", - "uniform vec3 lightPositionVS;", - "uniform vec3 lightDirectionVS;", - "uniform float lightAngle;", - "uniform float lightIntensity;", - - "uniform mat4 matProjInverse;", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - - "void main() {", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - THREE.DeferredShaderChunk[ "unpackNormalDepth" ], - THREE.DeferredShaderChunk[ "computeVertexPositionVS" ], - THREE.DeferredShaderChunk[ "unpackColor" ], - - " vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );", - - " float rho = dot( lightDirectionVS, lightVector );", - " float rhoMax = cos( lightAngle );", - - " if ( rho <= rhoMax ) discard;", - - " float theta = rhoMax + 0.0001;", - " float phi = rhoMax + 0.05;", - " float falloff = 4.0;", - - " float spot = 0.0;", - - " if ( rho >= phi ) {", - - " spot = 1.0;", - - " } else if ( rho <= theta ) {", - - " spot = 0.0;", - - " } else { ", - - " spot = pow( ( rho - theta ) / ( phi - theta ), falloff );", - - " }", - - " diffuseColor *= spot;", - - THREE.DeferredShaderChunk[ "computeSpecular" ], - - " const float attenuation = 1.0;", - - THREE.DeferredShaderChunk[ "combine" ], - - "}" - - ].join( "\n" ) - - }, - - directionalLight: { - - uniforms: Object.assign( - - { - - samplerNormalDepth: new THREE.Uniform( null ), - samplerColor: new THREE.Uniform( null ), - - lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightIntensity: new THREE.Uniform( 1.0 ) - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - vertexShader: [ - - "void main() { ", - - " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );", - - "}" - - ].join( '\n' ), - - fragmentShader: [ - - "uniform sampler2D samplerNormalDepth;", - "uniform sampler2D samplerColor;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - "uniform vec3 lightColor;", - "uniform vec3 lightDirectionVS;", - "uniform float lightIntensity;", - - "uniform mat4 matProjInverse;", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - - "void main() {", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - THREE.DeferredShaderChunk[ "unpackNormalDepth" ], - THREE.DeferredShaderChunk[ "computeVertexPositionVS" ], - THREE.DeferredShaderChunk[ "unpackColor" ], - - " vec3 lightVector = normalize( lightDirectionVS );", - - THREE.DeferredShaderChunk[ "computeSpecular" ], - - " const float attenuation = 1.0;", - - THREE.DeferredShaderChunk[ "combine" ], - - "}" - - ].join( '\n' ) - - }, - - normalDepthShininess: { - - uniforms: { - - shininess: new THREE.Uniform( 30.0 ) - - }, - - vertexShader: [ - - "varying vec3 vNormal;", - "varying vec4 vPosition;", - - "#include ", - "#include ", - - "void main() {", - - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - - " vNormal = normalize( transformedNormal );", - " vPosition = gl_Position;", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "varying vec3 vNormal;", - "varying vec4 vPosition;", - - "uniform float shininess;", - - THREE.DeferredShaderChunk[ "packNormal" ], - - "void main() {", - - " vec3 normal = vNormal;", - " vec4 position = vPosition;", - - THREE.DeferredShaderChunk[ "packNormalDepthShininess" ], - - " gl_FragColor = packedNormalDepthShininess;", - - "}" - - ].join( "\n" ) - - }, - - pointLightPre: { - - uniforms: Object.assign( - - { - - samplerNormalDepthShininess: new THREE.Uniform( null ), - - lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightIntensity: new THREE.Uniform( 1.0 ), - lightRadius: new THREE.Uniform( 1.0 ) - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - - vertexShader: [ - - "void main() {", - - " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform sampler2D samplerNormalDepthShininess;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - "uniform vec3 lightColor;", - "uniform vec3 lightPositionVS;", - "uniform float lightIntensity;", - "uniform float lightRadius;", - - "uniform mat4 matProjInverse;", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - THREE.DeferredShaderChunk[ "unpackVector2" ], - - "void main() {", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ], - THREE.DeferredShaderChunk[ "computeVertexPositionVS" ], - - " vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;", - " float distance = length( lightVector );", - - " if ( distance > lightRadius ) discard;", - - " lightVector = normalize( lightVector );", - - THREE.DeferredShaderChunk[ "computeSpecular" ], - - " float attenuation = saturate( -distance / lightRadius + 1.0 );", - - THREE.DeferredShaderChunk[ "packLight" ], - - " gl_FragColor = packedLight;", - - "}" - - ].join( "\n" ) - - }, - - spotLightPre: { - - uniforms: Object.assign( - - { - - samplerNormalDepthShininess: new THREE.Uniform( null ), - - lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightAngle: new THREE.Uniform( 1.0 ), - lightIntensity: new THREE.Uniform( 1.0 ) - - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - vertexShader: [ - - "void main() { ", - - " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform sampler2D samplerNormalDepthShininess;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - "uniform vec3 lightColor;", - "uniform vec3 lightPositionVS;", - "uniform vec3 lightDirectionVS;", - "uniform float lightAngle;", - "uniform float lightIntensity;", - - "uniform mat4 matProjInverse;", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - THREE.DeferredShaderChunk[ "unpackVector2" ], - - "void main() {", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ], - THREE.DeferredShaderChunk[ "computeVertexPositionVS" ], - - " vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );", - - " float rho = dot( lightDirectionVS, lightVector );", - " float rhoMax = cos( lightAngle );", - - " if ( rho <= rhoMax ) discard;", - - " float theta = rhoMax + 0.0001;", - " float phi = rhoMax + 0.05;", - " float falloff = 4.0;", - - " float spot = 0.0;", - - " if ( rho >= phi ) {", - - " spot = 1.0;", - - " } else if ( rho <= theta ) {", - - " spot = 0.0;", - - " } else { ", - - " spot = pow( ( rho - theta ) / ( phi - theta ), falloff );", - - " }", - - THREE.DeferredShaderChunk[ "computeSpecular" ], - - " const float attenuation = 1.0;", - - THREE.DeferredShaderChunk[ "packLight" ], - - " gl_FragColor = spot * packedLight;", - - "}" - - ].join( "\n" ) - - }, - - directionalLightPre: { - - uniforms: Object.assign( - - { - - samplerNormalDepthShininess: new THREE.Uniform( null ), - - lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ), - lightIntensity: new THREE.Uniform( 1.0 ) - - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - vertexShader: [ - - "void main() { ", - - " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );", - - "}" - - ].join( '\n' ), - - fragmentShader: [ - - "uniform sampler2D samplerNormalDepthShininess;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - "uniform vec3 lightColor;", - "uniform vec3 lightDirectionVS;", - "uniform float lightIntensity;", - - "uniform mat4 matProjInverse;", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - THREE.DeferredShaderChunk[ "unpackVector2" ], - - "void main() {", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ], - THREE.DeferredShaderChunk[ "computeVertexPositionVS" ], - - " vec3 lightVector = normalize( lightDirectionVS );", - - THREE.DeferredShaderChunk[ "computeSpecular" ], - - " const float attenuation = 1.0;", - - THREE.DeferredShaderChunk[ "packLight" ], - - " gl_FragColor = packedLight;", - - "}" - - ].join( '\n' ) - - }, - - reconstruction: { - - uniforms: Object.assign( - - { - - samplerLight: new THREE.Uniform( null ), - - map: new THREE.Uniform( null ), - offsetRepeat: new THREE.Uniform( new THREE.Vector4( 0, 0, 1, 1 ) ), - - diffuse: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - emissive: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - specular: new THREE.Uniform( new THREE.Color( 0x000000 ) ), - shininess: new THREE.Uniform( 30.0 ) - - }, - - THREE.ShaderDeferredCommon[ 'commonUniforms' ] - - ), - - vertexShader: [ - - "#include ", - "#include ", - "#include ", - - "void main() {", - - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - "#include ", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform sampler2D samplerLight;", - - "uniform vec3 diffuse;", - "uniform vec3 emissive;", - "uniform vec3 specular;", - "uniform float shininess;", - - "uniform float viewHeight;", - "uniform float viewWidth;", - - "#include ", - "#include ", - - THREE.DeferredShaderChunk[ "unpackFloat" ], - - "void main() {", - - " vec4 diffuseColor = vec4( diffuse, 1.0 );", - " vec3 emissiveColor = emissive;", - " vec3 specularColor = specular;", - - THREE.DeferredShaderChunk[ "computeTextureCoord" ], - - " vec4 light = texture2D( samplerLight, texCoord );", - - "#include ", - - " vec3 diffuseFinal = diffuseColor.rgb * light.rgb;", - " vec3 emissiveFinal = emissiveColor;", - " vec3 specularFinal = specularColor * light.rgb * light.a;", - - " gl_FragColor = vec4( diffuseFinal + emissiveFinal + specularFinal, 1.0 );", - - "}" - - ].join( "\n" ) - - }, - - // TODO: implement tone mapping - final: { - - uniforms: { - - samplerResult: new THREE.Uniform( null ) - - }, - - vertexShader: [ - - "varying vec2 texCoord;", - - "void main() {", - - " vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );", - " texCoord = pos.xy * vec2( 0.5 ) + 0.5;", - " gl_Position = pos;", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "varying vec2 texCoord;", - "uniform sampler2D samplerResult;", - - "void main() {", - - " gl_FragColor = texture2D( samplerResult, texCoord );", - - "}" - - ].join( "\n" ) - - } - -}; diff --git a/examples/js/shaders/AfterimageShader.js b/examples/js/shaders/AfterimageShader.js index ab4a5df03444d4..f62f872a1237b4 100644 --- a/examples/js/shaders/AfterimageShader.js +++ b/examples/js/shaders/AfterimageShader.js @@ -22,8 +22,8 @@ THREE.AfterimageShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -37,21 +37,21 @@ THREE.AfterimageShader = { "uniform sampler2D tNew;", "varying vec2 vUv;", - + "vec4 when_gt( vec4 x, float y ) {", - "return max( sign( x - y ), 0.0 );", + " return max( sign( x - y ), 0.0 );", "}", "void main() {", - "vec4 texelOld = texture2D( tOld, vUv );", - "vec4 texelNew = texture2D( tNew, vUv );", - - "texelOld *= damp * when_gt( texelOld, 0.1 );", + " vec4 texelOld = texture2D( tOld, vUv );", + " vec4 texelNew = texture2D( tNew, vUv );", + + " texelOld *= damp * when_gt( texelOld, 0.1 );", - "gl_FragColor = max(texelNew, texelOld);", + " gl_FragColor = max(texelNew, texelOld);", "}" diff --git a/examples/js/shaders/BasicShader.js b/examples/js/shaders/BasicShader.js index 16fdfe921b7171..87684ec60e3f5c 100644 --- a/examples/js/shaders/BasicShader.js +++ b/examples/js/shaders/BasicShader.js @@ -12,7 +12,7 @@ THREE.BasicShader = { "void main() {", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -22,7 +22,7 @@ THREE.BasicShader = { "void main() {", - "gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );", + " gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5 );", "}" diff --git a/examples/js/shaders/BleachBypassShader.js b/examples/js/shaders/BleachBypassShader.js index bed3c704565958..e73c0cf4e0a692 100644 --- a/examples/js/shaders/BleachBypassShader.js +++ b/examples/js/shaders/BleachBypassShader.js @@ -21,8 +21,8 @@ THREE.BleachBypassShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -38,24 +38,24 @@ THREE.BleachBypassShader = { "void main() {", - "vec4 base = texture2D( tDiffuse, vUv );", + " vec4 base = texture2D( tDiffuse, vUv );", - "vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );", - "float lum = dot( lumCoeff, base.rgb );", - "vec3 blend = vec3( lum );", + " vec3 lumCoeff = vec3( 0.25, 0.65, 0.1 );", + " float lum = dot( lumCoeff, base.rgb );", + " vec3 blend = vec3( lum );", - "float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );", + " float L = min( 1.0, max( 0.0, 10.0 * ( lum - 0.45 ) ) );", - "vec3 result1 = 2.0 * base.rgb * blend;", - "vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );", + " vec3 result1 = 2.0 * base.rgb * blend;", + " vec3 result2 = 1.0 - 2.0 * ( 1.0 - blend ) * ( 1.0 - base.rgb );", - "vec3 newColor = mix( result1, result2, L );", + " vec3 newColor = mix( result1, result2, L );", - "float A2 = opacity * base.a;", - "vec3 mixRGB = A2 * newColor.rgb;", - "mixRGB += ( ( 1.0 - A2 ) * base.rgb );", + " float A2 = opacity * base.a;", + " vec3 mixRGB = A2 * newColor.rgb;", + " mixRGB += ( ( 1.0 - A2 ) * base.rgb );", - "gl_FragColor = vec4( mixRGB, base.a );", + " gl_FragColor = vec4( mixRGB, base.a );", "}" diff --git a/examples/js/shaders/BlendShader.js b/examples/js/shaders/BlendShader.js index 1dbd5236ac78e7..91dbbf3f74df00 100644 --- a/examples/js/shaders/BlendShader.js +++ b/examples/js/shaders/BlendShader.js @@ -21,8 +21,8 @@ THREE.BlendShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -40,9 +40,9 @@ THREE.BlendShader = { "void main() {", - "vec4 texel1 = texture2D( tDiffuse1, vUv );", - "vec4 texel2 = texture2D( tDiffuse2, vUv );", - "gl_FragColor = opacity * mix( texel1, texel2, mixRatio );", + " vec4 texel1 = texture2D( tDiffuse1, vUv );", + " vec4 texel2 = texture2D( tDiffuse2, vUv );", + " gl_FragColor = opacity * mix( texel1, texel2, mixRatio );", "}" diff --git a/examples/js/shaders/BokehShader.js b/examples/js/shaders/BokehShader.js index 20c0a93e9495a3..92f6da25164d7f 100644 --- a/examples/js/shaders/BokehShader.js +++ b/examples/js/shaders/BokehShader.js @@ -32,8 +32,8 @@ THREE.BokehShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -77,67 +77,67 @@ THREE.BokehShader = { "void main() {", - "vec2 aspectcorrect = vec2( 1.0, aspect );", - - "float viewZ = getViewZ( getDepth( vUv ) );", - - "float factor = ( focus + viewZ );", // viewZ is <= 0, so this is a difference equation - - "vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );", - - "vec2 dofblur9 = dofblur * 0.9;", - "vec2 dofblur7 = dofblur * 0.7;", - "vec2 dofblur4 = dofblur * 0.4;", - - "vec4 col = vec4( 0.0 );", - - "col += texture2D( tColor, vUv.xy );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );", - - "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", - - "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );", - - "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", - "col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", - "col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );", - - "gl_FragColor = col / 41.0;", - "gl_FragColor.a = 1.0;", + " vec2 aspectcorrect = vec2( 1.0, aspect );", + + " float viewZ = getViewZ( getDepth( vUv ) );", + + " float factor = ( focus + viewZ );", // viewZ is <= 0, so this is a difference equation + + " vec2 dofblur = vec2 ( clamp( factor * aperture, -maxblur, maxblur ) );", + + " vec2 dofblur9 = dofblur * 0.9;", + " vec2 dofblur7 = dofblur * 0.7;", + " vec2 dofblur4 = dofblur * 0.4;", + + " vec4 col = vec4( 0.0 );", + + " col += texture2D( tColor, vUv.xy );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur );", + + " col += texture2D( tColor, vUv.xy + ( vec2( 0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.15, 0.37 ) * aspectcorrect ) * dofblur9 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.37, 0.15 ) * aspectcorrect ) * dofblur9 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.37, -0.15 ) * aspectcorrect ) * dofblur9 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.15, -0.37 ) * aspectcorrect ) * dofblur9 );", + + " col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.40, 0.0 ) * aspectcorrect ) * dofblur7 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur7 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur7 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur7 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur7 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur7 );", + + " col += texture2D( tColor, vUv.xy + ( vec2( 0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.0, -0.4 ) * aspectcorrect ) * dofblur4 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.29, 0.29 ) * aspectcorrect ) * dofblur4 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.4, 0.0 ) * aspectcorrect ) * dofblur4 );", + " col += texture2D( tColor, vUv.xy + ( vec2( -0.29, -0.29 ) * aspectcorrect ) * dofblur4 );", + " col += texture2D( tColor, vUv.xy + ( vec2( 0.0, 0.4 ) * aspectcorrect ) * dofblur4 );", + + " gl_FragColor = col / 41.0;", + " gl_FragColor.a = 1.0;", "}" diff --git a/examples/js/shaders/BokehShader2.js b/examples/js/shaders/BokehShader2.js index 311b6946da78b8..53c971427e5d54 100644 --- a/examples/js/shaders/BokehShader2.js +++ b/examples/js/shaders/BokehShader2.js @@ -55,8 +55,8 @@ THREE.BokehShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -142,213 +142,213 @@ THREE.BokehShader = { "//------------------------------------------", "float penta(vec2 coords) {", - "//pentagonal shape", - "float scale = float(rings) - 1.3;", - "vec4 HS0 = vec4( 1.0, 0.0, 0.0, 1.0);", - "vec4 HS1 = vec4( 0.309016994, 0.951056516, 0.0, 1.0);", - "vec4 HS2 = vec4(-0.809016994, 0.587785252, 0.0, 1.0);", - "vec4 HS3 = vec4(-0.809016994,-0.587785252, 0.0, 1.0);", - "vec4 HS4 = vec4( 0.309016994,-0.951056516, 0.0, 1.0);", - "vec4 HS5 = vec4( 0.0 ,0.0 , 1.0, 1.0);", + " //pentagonal shape", + " float scale = float(rings) - 1.3;", + " vec4 HS0 = vec4( 1.0, 0.0, 0.0, 1.0);", + " vec4 HS1 = vec4( 0.309016994, 0.951056516, 0.0, 1.0);", + " vec4 HS2 = vec4(-0.809016994, 0.587785252, 0.0, 1.0);", + " vec4 HS3 = vec4(-0.809016994,-0.587785252, 0.0, 1.0);", + " vec4 HS4 = vec4( 0.309016994,-0.951056516, 0.0, 1.0);", + " vec4 HS5 = vec4( 0.0 ,0.0 , 1.0, 1.0);", - "vec4 one = vec4( 1.0 );", + " vec4 one = vec4( 1.0 );", - "vec4 P = vec4((coords),vec2(scale, scale));", + " vec4 P = vec4((coords),vec2(scale, scale));", - "vec4 dist = vec4(0.0);", - "float inorout = -4.0;", + " vec4 dist = vec4(0.0);", + " float inorout = -4.0;", - "dist.x = dot( P, HS0 );", - "dist.y = dot( P, HS1 );", - "dist.z = dot( P, HS2 );", - "dist.w = dot( P, HS3 );", + " dist.x = dot( P, HS0 );", + " dist.y = dot( P, HS1 );", + " dist.z = dot( P, HS2 );", + " dist.w = dot( P, HS3 );", - "dist = smoothstep( -feather, feather, dist );", + " dist = smoothstep( -feather, feather, dist );", - "inorout += dot( dist, one );", + " inorout += dot( dist, one );", - "dist.x = dot( P, HS4 );", - "dist.y = HS5.w - abs( P.z );", + " dist.x = dot( P, HS4 );", + " dist.y = HS5.w - abs( P.z );", - "dist = smoothstep( -feather, feather, dist );", - "inorout += dist.x;", + " dist = smoothstep( -feather, feather, dist );", + " inorout += dist.x;", - "return clamp( inorout, 0.0, 1.0 );", + " return clamp( inorout, 0.0, 1.0 );", "}", "float bdepth(vec2 coords) {", - "// Depth buffer blur", - "float d = 0.0;", - "float kernel[9];", - "vec2 offset[9];", + " // Depth buffer blur", + " float d = 0.0;", + " float kernel[9];", + " vec2 offset[9];", - "vec2 wh = vec2(1.0/textureWidth,1.0/textureHeight) * dbsize;", + " vec2 wh = vec2(1.0/textureWidth,1.0/textureHeight) * dbsize;", - "offset[0] = vec2(-wh.x,-wh.y);", - "offset[1] = vec2( 0.0, -wh.y);", - "offset[2] = vec2( wh.x -wh.y);", + " offset[0] = vec2(-wh.x,-wh.y);", + " offset[1] = vec2( 0.0, -wh.y);", + " offset[2] = vec2( wh.x -wh.y);", - "offset[3] = vec2(-wh.x, 0.0);", - "offset[4] = vec2( 0.0, 0.0);", - "offset[5] = vec2( wh.x, 0.0);", + " offset[3] = vec2(-wh.x, 0.0);", + " offset[4] = vec2( 0.0, 0.0);", + " offset[5] = vec2( wh.x, 0.0);", - "offset[6] = vec2(-wh.x, wh.y);", - "offset[7] = vec2( 0.0, wh.y);", - "offset[8] = vec2( wh.x, wh.y);", + " offset[6] = vec2(-wh.x, wh.y);", + " offset[7] = vec2( 0.0, wh.y);", + " offset[8] = vec2( wh.x, wh.y);", - "kernel[0] = 1.0/16.0; kernel[1] = 2.0/16.0; kernel[2] = 1.0/16.0;", - "kernel[3] = 2.0/16.0; kernel[4] = 4.0/16.0; kernel[5] = 2.0/16.0;", - "kernel[6] = 1.0/16.0; kernel[7] = 2.0/16.0; kernel[8] = 1.0/16.0;", + " kernel[0] = 1.0/16.0; kernel[1] = 2.0/16.0; kernel[2] = 1.0/16.0;", + " kernel[3] = 2.0/16.0; kernel[4] = 4.0/16.0; kernel[5] = 2.0/16.0;", + " kernel[6] = 1.0/16.0; kernel[7] = 2.0/16.0; kernel[8] = 1.0/16.0;", - "for( int i=0; i<9; i++ ) {", - "float tmp = texture2D(tDepth, coords + offset[i]).r;", - "d += tmp * kernel[i];", - "}", + " for( int i=0; i<9; i++ ) {", + " float tmp = texture2D(tDepth, coords + offset[i]).r;", + " d += tmp * kernel[i];", + " }", - "return d;", + " return d;", "}", "vec3 color(vec2 coords,float blur) {", - "//processing the sample", + " //processing the sample", - "vec3 col = vec3(0.0);", - "vec2 texel = vec2(1.0/textureWidth,1.0/textureHeight);", + " vec3 col = vec3(0.0);", + " vec2 texel = vec2(1.0/textureWidth,1.0/textureHeight);", - "col.r = texture2D(tColor,coords + vec2(0.0,1.0)*texel*fringe*blur).r;", - "col.g = texture2D(tColor,coords + vec2(-0.866,-0.5)*texel*fringe*blur).g;", - "col.b = texture2D(tColor,coords + vec2(0.866,-0.5)*texel*fringe*blur).b;", + " col.r = texture2D(tColor,coords + vec2(0.0,1.0)*texel*fringe*blur).r;", + " col.g = texture2D(tColor,coords + vec2(-0.866,-0.5)*texel*fringe*blur).g;", + " col.b = texture2D(tColor,coords + vec2(0.866,-0.5)*texel*fringe*blur).b;", - "vec3 lumcoeff = vec3(0.299,0.587,0.114);", - "float lum = dot(col.rgb, lumcoeff);", - "float thresh = max((lum-threshold)*gain, 0.0);", - "return col+mix(vec3(0.0),col,thresh*blur);", + " vec3 lumcoeff = vec3(0.299,0.587,0.114);", + " float lum = dot(col.rgb, lumcoeff);", + " float thresh = max((lum-threshold)*gain, 0.0);", + " return col+mix(vec3(0.0),col,thresh*blur);", "}", "vec3 debugFocus(vec3 col, float blur, float depth) {", - "float edge = 0.002*depth; //distance based edge smoothing", - "float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);", - "float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);", + " float edge = 0.002*depth; //distance based edge smoothing", + " float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);", + " float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);", - "col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);", - "col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);", + " col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);", + " col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);", - "return col;", + " return col;", "}", "float linearize(float depth) {", - "return -zfar * znear / (depth * (zfar - znear) - zfar);", + " return -zfar * znear / (depth * (zfar - znear) - zfar);", "}", "float vignette() {", - "float dist = distance(vUv.xy, vec2(0.5,0.5));", - "dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);", - "return clamp(dist,0.0,1.0);", + " float dist = distance(vUv.xy, vec2(0.5,0.5));", + " dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);", + " return clamp(dist,0.0,1.0);", "}", "float gather(float i, float j, int ringsamples, inout vec3 col, float w, float h, float blur) {", - "float rings2 = float(rings);", - "float step = PI*2.0 / float(ringsamples);", - "float pw = cos(j*step)*i;", - "float ph = sin(j*step)*i;", - "float p = 1.0;", - "if (pentagon) {", - "p = penta(vec2(pw,ph));", - "}", - "col += color(vUv.xy + vec2(pw*w,ph*h), blur) * mix(1.0, i/rings2, bias) * p;", - "return 1.0 * mix(1.0, i /rings2, bias) * p;", + " float rings2 = float(rings);", + " float step = PI*2.0 / float(ringsamples);", + " float pw = cos(j*step)*i;", + " float ph = sin(j*step)*i;", + " float p = 1.0;", + " if (pentagon) {", + " p = penta(vec2(pw,ph));", + " }", + " col += color(vUv.xy + vec2(pw*w,ph*h), blur) * mix(1.0, i/rings2, bias) * p;", + " return 1.0 * mix(1.0, i /rings2, bias) * p;", "}", "void main() {", - "//scene depth calculation", + " //scene depth calculation", - "float depth = linearize(texture2D(tDepth,vUv.xy).x);", + " float depth = linearize(texture2D(tDepth,vUv.xy).x);", - "// Blur depth?", - "if ( depthblur ) {", - "depth = linearize(bdepth(vUv.xy));", - "}", + " // Blur depth?", + " if ( depthblur ) {", + " depth = linearize(bdepth(vUv.xy));", + " }", - "//focal plane calculation", + " //focal plane calculation", - "float fDepth = focalDepth;", + " float fDepth = focalDepth;", - "if (shaderFocus) {", + " if (shaderFocus) {", - "fDepth = linearize(texture2D(tDepth,focusCoords).x);", + " fDepth = linearize(texture2D(tDepth,focusCoords).x);", - "}", + " }", - "// dof blur factor calculation", + " // dof blur factor calculation", - "float blur = 0.0;", + " float blur = 0.0;", - "if (manualdof) {", - "float a = depth-fDepth; // Focal plane", - "float b = (a-fdofstart)/fdofdist; // Far DoF", - "float c = (-a-ndofstart)/ndofdist; // Near Dof", - "blur = (a>0.0) ? b : c;", - "} else {", - "float f = focalLength; // focal length in mm", - "float d = fDepth*1000.0; // focal plane in mm", - "float o = depth*1000.0; // depth in mm", + " if (manualdof) {", + " float a = depth-fDepth; // Focal plane", + " float b = (a-fdofstart)/fdofdist; // Far DoF", + " float c = (-a-ndofstart)/ndofdist; // Near Dof", + " blur = (a>0.0) ? b : c;", + " } else {", + " float f = focalLength; // focal length in mm", + " float d = fDepth*1000.0; // focal plane in mm", + " float o = depth*1000.0; // depth in mm", - "float a = (o*f)/(o-f);", - "float b = (d*f)/(d-f);", - "float c = (d-f)/(d*fstop*CoC);", + " float a = (o*f)/(o-f);", + " float b = (d*f)/(d-f);", + " float c = (d-f)/(d*fstop*CoC);", - "blur = abs(a-b)*c;", - "}", + " blur = abs(a-b)*c;", + " }", - "blur = clamp(blur,0.0,1.0);", + " blur = clamp(blur,0.0,1.0);", - "// calculation of pattern for dithering", + " // calculation of pattern for dithering", - "vec2 noise = vec2(rand(vUv.xy), rand( vUv.xy + vec2( 0.4, 0.6 ) ) )*dithering*blur;", + " vec2 noise = vec2(rand(vUv.xy), rand( vUv.xy + vec2( 0.4, 0.6 ) ) )*dithering*blur;", - "// getting blur x and y step factor", + " // getting blur x and y step factor", - "float w = (1.0/textureWidth)*blur*maxblur+noise.x;", - "float h = (1.0/textureHeight)*blur*maxblur+noise.y;", + " float w = (1.0/textureWidth)*blur*maxblur+noise.x;", + " float h = (1.0/textureHeight)*blur*maxblur+noise.y;", - "// calculation of final color", + " // calculation of final color", - "vec3 col = vec3(0.0);", + " vec3 col = vec3(0.0);", - "if(blur < 0.05) {", - "//some optimization thingy", - "col = texture2D(tColor, vUv.xy).rgb;", - "} else {", - "col = texture2D(tColor, vUv.xy).rgb;", - "float s = 1.0;", - "int ringsamples;", + " if(blur < 0.05) {", + " //some optimization thingy", + " col = texture2D(tColor, vUv.xy).rgb;", + " } else {", + " col = texture2D(tColor, vUv.xy).rgb;", + " float s = 1.0;", + " int ringsamples;", - "for (int i = 1; i <= rings; i++) {", - "/*unboxstart*/", - "ringsamples = i * samples;", + " for (int i = 1; i <= rings; i++) {", + " /*unboxstart*/", + " ringsamples = i * samples;", - "for (int j = 0 ; j < maxringsamples ; j++) {", - "if (j >= ringsamples) break;", - "s += gather(float(i), float(j), ringsamples, col, w, h, blur);", - "}", - "/*unboxend*/", - "}", + " for (int j = 0 ; j < maxringsamples ; j++) {", + " if (j >= ringsamples) break;", + " s += gather(float(i), float(j), ringsamples, col, w, h, blur);", + " }", + " /*unboxend*/", + " }", - "col /= s; //divide by sample count", - "}", + " col /= s; //divide by sample count", + " }", - "if (showFocus) {", - "col = debugFocus(col, blur, depth);", - "}", + " if (showFocus) {", + " col = debugFocus(col, blur, depth);", + " }", - "if (vignetting) {", - "col *= vignette();", - "}", + " if (vignetting) {", + " col *= vignette();", + " }", - "gl_FragColor.rgb = col;", - "gl_FragColor.a = 1.0;", + " gl_FragColor.rgb = col;", + " gl_FragColor.a = 1.0;", "} " ].join( "\n" ) diff --git a/examples/js/shaders/BrightnessContrastShader.js b/examples/js/shaders/BrightnessContrastShader.js index 7f0c1fe7d6bc40..8487c2d0586dcf 100644 --- a/examples/js/shaders/BrightnessContrastShader.js +++ b/examples/js/shaders/BrightnessContrastShader.js @@ -23,9 +23,9 @@ THREE.BrightnessContrastShader = { "void main() {", - "vUv = uv;", + " vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -41,15 +41,15 @@ THREE.BrightnessContrastShader = { "void main() {", - "gl_FragColor = texture2D( tDiffuse, vUv );", + " gl_FragColor = texture2D( tDiffuse, vUv );", - "gl_FragColor.rgb += brightness;", + " gl_FragColor.rgb += brightness;", - "if (contrast > 0.0) {", - "gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;", - "} else {", - "gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;", - "}", + " if (contrast > 0.0) {", + " gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) / (1.0 - contrast) + 0.5;", + " } else {", + " gl_FragColor.rgb = (gl_FragColor.rgb - 0.5) * (1.0 + contrast) + 0.5;", + " }", "}" diff --git a/examples/js/shaders/ColorCorrectionShader.js b/examples/js/shaders/ColorCorrectionShader.js index adbb7522993108..3972ef33dcec96 100644 --- a/examples/js/shaders/ColorCorrectionShader.js +++ b/examples/js/shaders/ColorCorrectionShader.js @@ -21,9 +21,9 @@ THREE.ColorCorrectionShader = { "void main() {", - "vUv = uv;", + " vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -40,8 +40,8 @@ THREE.ColorCorrectionShader = { "void main() {", - "gl_FragColor = texture2D( tDiffuse, vUv );", - "gl_FragColor.rgb = mulRGB * pow( ( gl_FragColor.rgb + addRGB ), powRGB );", + " gl_FragColor = texture2D( tDiffuse, vUv );", + " gl_FragColor.rgb = mulRGB * pow( ( gl_FragColor.rgb + addRGB ), powRGB );", "}" diff --git a/examples/js/shaders/ColorifyShader.js b/examples/js/shaders/ColorifyShader.js index 037f69ae00f46e..16b10920331265 100644 --- a/examples/js/shaders/ColorifyShader.js +++ b/examples/js/shaders/ColorifyShader.js @@ -19,8 +19,8 @@ THREE.ColorifyShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -35,12 +35,12 @@ THREE.ColorifyShader = { "void main() {", - "vec4 texel = texture2D( tDiffuse, vUv );", + " vec4 texel = texture2D( tDiffuse, vUv );", - "vec3 luma = vec3( 0.299, 0.587, 0.114 );", - "float v = dot( texel.xyz, luma );", + " vec3 luma = vec3( 0.299, 0.587, 0.114 );", + " float v = dot( texel.xyz, luma );", - "gl_FragColor = vec4( v * color, texel.w );", + " gl_FragColor = vec4( v * color, texel.w );", "}" diff --git a/examples/js/shaders/ConvolutionShader.js b/examples/js/shaders/ConvolutionShader.js index 0e520653078947..446609fa34ca02 100644 --- a/examples/js/shaders/ConvolutionShader.js +++ b/examples/js/shaders/ConvolutionShader.js @@ -31,8 +31,8 @@ THREE.ConvolutionShader = { "void main() {", - "vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -49,17 +49,17 @@ THREE.ConvolutionShader = { "void main() {", - "vec2 imageCoord = vUv;", - "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", + " vec2 imageCoord = vUv;", + " vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", - "for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {", + " for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {", - "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", - "imageCoord += uImageIncrement;", + " sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", + " imageCoord += uImageIncrement;", - "}", + " }", - "gl_FragColor = sum;", + " gl_FragColor = sum;", "}" diff --git a/examples/js/shaders/CopyShader.js b/examples/js/shaders/CopyShader.js index 9843a42fc4c2d2..b118e73448431b 100644 --- a/examples/js/shaders/CopyShader.js +++ b/examples/js/shaders/CopyShader.js @@ -9,7 +9,7 @@ THREE.CopyShader = { uniforms: { "tDiffuse": { value: null }, - "opacity": { value: 1.0 } + "opacity": { value: 1.0 } }, @@ -19,8 +19,8 @@ THREE.CopyShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -36,8 +36,8 @@ THREE.CopyShader = { "void main() {", - "vec4 texel = texture2D( tDiffuse, vUv );", - "gl_FragColor = opacity * texel;", + " vec4 texel = texture2D( tDiffuse, vUv );", + " gl_FragColor = opacity * texel;", "}" diff --git a/examples/js/shaders/DOFMipMapShader.js b/examples/js/shaders/DOFMipMapShader.js index dad52f851e99ca..61898237e5b974 100644 --- a/examples/js/shaders/DOFMipMapShader.js +++ b/examples/js/shaders/DOFMipMapShader.js @@ -23,8 +23,8 @@ THREE.DOFMipMapShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -42,14 +42,14 @@ THREE.DOFMipMapShader = { "void main() {", - "vec4 depth = texture2D( tDepth, vUv );", + " vec4 depth = texture2D( tDepth, vUv );", - "float factor = depth.x - focus;", + " float factor = depth.x - focus;", - "vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );", + " vec4 col = texture2D( tColor, vUv, 2.0 * maxblur * abs( focus - depth.x ) );", - "gl_FragColor = col;", - "gl_FragColor.a = 1.0;", + " gl_FragColor = col;", + " gl_FragColor.a = 1.0;", "}" diff --git a/examples/js/shaders/DepthLimitedBlurShader.js b/examples/js/shaders/DepthLimitedBlurShader.js index d9e71acea35743..d63d23f570c248 100644 --- a/examples/js/shaders/DepthLimitedBlurShader.js +++ b/examples/js/shaders/DepthLimitedBlurShader.js @@ -4,19 +4,19 @@ THREE.DepthLimitedBlurShader = { defines: { - 'KERNEL_RADIUS': 4, - 'DEPTH_PACKING': 1, - 'PERSPECTIVE_CAMERA': 1 + "KERNEL_RADIUS": 4, + "DEPTH_PACKING": 1, + "PERSPECTIVE_CAMERA": 1 }, uniforms: { - 'tDiffuse': { value: null }, - 'size': { value: new THREE.Vector2( 512, 512 ) }, - 'sampleUvOffsets': { value: [ new THREE.Vector2( 0, 0 ) ] }, - 'sampleWeights': { value: [ 1.0 ] }, - 'tDepth': { value: null }, - 'cameraNear': { value: 10 }, - 'cameraFar': { value: 1000 }, - 'depthCutoff': { value: 10 }, + "tDiffuse": { value: null }, + "size": { value: new THREE.Vector2( 512, 512 ) }, + "sampleUvOffsets": { value: [ new THREE.Vector2( 0, 0 ) ] }, + "sampleWeights": { value: [ 1.0 ] }, + "tDepth": { value: null }, + "cameraNear": { value: 10 }, + "cameraFar": { value: 1000 }, + "depthCutoff": { value: 10 }, }, vertexShader: [ "#include ", @@ -149,9 +149,9 @@ THREE.BlurShaderUtils = { configure: function ( material, kernelRadius, stdDev, uvIncrement ) { - material.defines[ 'KERNEL_RADIUS' ] = kernelRadius; - material.uniforms[ 'sampleUvOffsets' ].value = THREE.BlurShaderUtils.createSampleOffsets( kernelRadius, uvIncrement ); - material.uniforms[ 'sampleWeights' ].value = THREE.BlurShaderUtils.createSampleWeights( kernelRadius, stdDev ); + material.defines[ "KERNEL_RADIUS" ] = kernelRadius; + material.uniforms[ "sampleUvOffsets" ].value = THREE.BlurShaderUtils.createSampleOffsets( kernelRadius, uvIncrement ); + material.uniforms[ "sampleWeights" ].value = THREE.BlurShaderUtils.createSampleWeights( kernelRadius, stdDev ); material.needsUpdate = true; } diff --git a/examples/js/shaders/DigitalGlitch.js b/examples/js/shaders/DigitalGlitch.js index 0dfc3b1cbf520b..7722ec219e3553 100644 --- a/examples/js/shaders/DigitalGlitch.js +++ b/examples/js/shaders/DigitalGlitch.js @@ -31,13 +31,13 @@ THREE.DigitalGlitch = { "varying vec2 vUv;", "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" ].join( "\n" ), fragmentShader: [ - "uniform int byp;",//should we apply the glitch ? + "uniform int byp;", //should we apply the glitch ? "uniform sampler2D tDiffuse;", "uniform sampler2D tDisp;", @@ -55,47 +55,47 @@ THREE.DigitalGlitch = { "float rand(vec2 co){", - "return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);", + " return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);", "}", "void main() {", - "if(byp<1) {", - "vec2 p = vUv;", - "float xs = floor(gl_FragCoord.x / 0.5);", - "float ys = floor(gl_FragCoord.y / 0.5);", - //based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch - "vec4 normal = texture2D (tDisp, p*seed*seed);", - "if(p.ydistortion_x-col_s*seed) {", - "if(seed_x>0.){", - "p.y = 1. - (p.y + distortion_y);", - "}", - "else {", - "p.y = distortion_y;", - "}", - "}", - "if(p.xdistortion_y-col_s*seed) {", - "if(seed_y>0.){", - "p.x=distortion_x;", - "}", - "else {", - "p.x = 1. - (p.x + distortion_x);", - "}", - "}", - "p.x+=normal.x*seed_x*(seed/5.);", - "p.y+=normal.y*seed_y*(seed/5.);", - //base from RGB shift shader - "vec2 offset = amount * vec2( cos(angle), sin(angle));", - "vec4 cr = texture2D(tDiffuse, p + offset);", - "vec4 cga = texture2D(tDiffuse, p);", - "vec4 cb = texture2D(tDiffuse, p - offset);", - "gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", - //add noise - "vec4 snow = 200.*amount*vec4(rand(vec2(xs * seed,ys * seed*50.))*0.2);", - "gl_FragColor = gl_FragColor+ snow;", - "}", - "else {", - "gl_FragColor=texture2D (tDiffuse, vUv);", - "}", + " if(byp<1) {", + " vec2 p = vUv;", + " float xs = floor(gl_FragCoord.x / 0.5);", + " float ys = floor(gl_FragCoord.y / 0.5);", + //based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch + " vec4 normal = texture2D (tDisp, p*seed*seed);", + " if(p.ydistortion_x-col_s*seed) {", + " if(seed_x>0.){", + " p.y = 1. - (p.y + distortion_y);", + " }", + " else {", + " p.y = distortion_y;", + " }", + " }", + " if(p.xdistortion_y-col_s*seed) {", + " if(seed_y>0.){", + " p.x=distortion_x;", + " }", + " else {", + " p.x = 1. - (p.x + distortion_x);", + " }", + " }", + " p.x+=normal.x*seed_x*(seed/5.);", + " p.y+=normal.y*seed_y*(seed/5.);", + //base from RGB shift shader + " vec2 offset = amount * vec2( cos(angle), sin(angle));", + " vec4 cr = texture2D(tDiffuse, p + offset);", + " vec4 cga = texture2D(tDiffuse, p);", + " vec4 cb = texture2D(tDiffuse, p - offset);", + " gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", + //add noise + " vec4 snow = 200.*amount*vec4(rand(vec2(xs * seed,ys * seed*50.))*0.2);", + " gl_FragColor = gl_FragColor+ snow;", + " }", + " else {", + " gl_FragColor=texture2D (tDiffuse, vUv);", + " }", "}" ].join( "\n" ) diff --git a/examples/js/shaders/DotScreenShader.js b/examples/js/shaders/DotScreenShader.js index 7159a63342cbf4..cbfdb4dd43ad5c 100644 --- a/examples/js/shaders/DotScreenShader.js +++ b/examples/js/shaders/DotScreenShader.js @@ -11,10 +11,10 @@ THREE.DotScreenShader = { uniforms: { "tDiffuse": { value: null }, - "tSize": { value: new THREE.Vector2( 256, 256 ) }, - "center": { value: new THREE.Vector2( 0.5, 0.5 ) }, - "angle": { value: 1.57 }, - "scale": { value: 1.0 } + "tSize": { value: new THREE.Vector2( 256, 256 ) }, + "center": { value: new THREE.Vector2( 0.5, 0.5 ) }, + "angle": { value: 1.57 }, + "scale": { value: 1.0 } }, @@ -24,8 +24,8 @@ THREE.DotScreenShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -44,22 +44,22 @@ THREE.DotScreenShader = { "float pattern() {", - "float s = sin( angle ), c = cos( angle );", + " float s = sin( angle ), c = cos( angle );", - "vec2 tex = vUv * tSize - center;", - "vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;", + " vec2 tex = vUv * tSize - center;", + " vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale;", - "return ( sin( point.x ) * sin( point.y ) ) * 4.0;", + " return ( sin( point.x ) * sin( point.y ) ) * 4.0;", "}", "void main() {", - "vec4 color = texture2D( tDiffuse, vUv );", + " vec4 color = texture2D( tDiffuse, vUv );", - "float average = ( color.r + color.g + color.b ) / 3.0;", + " float average = ( color.r + color.g + color.b ) / 3.0;", - "gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );", + " gl_FragColor = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a );", "}" diff --git a/examples/js/shaders/FXAAShader.js b/examples/js/shaders/FXAAShader.js index a616887f7f3fb6..731e2036463246 100644 --- a/examples/js/shaders/FXAAShader.js +++ b/examples/js/shaders/FXAAShader.js @@ -23,1093 +23,1093 @@ THREE.FXAAShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" ].join( "\n" ), fragmentShader: [ - "precision highp float;", - "", - "uniform sampler2D tDiffuse;", - "", - "uniform vec2 resolution;", - "", - "varying vec2 vUv;", - "", - "// FXAA 3.11 implementation by NVIDIA, ported to WebGL by Agost Biro (biro@archilogic.com)", - "", - "//----------------------------------------------------------------------------------", - "// File: es3-kepler\FXAA\assets\shaders/FXAA_DefaultES.frag", - "// SDK Version: v3.00", - "// Email: gameworks@nvidia.com", - "// Site: http://developer.nvidia.com/", - "//", - "// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.", - "//", - "// Redistribution and use in source and binary forms, with or without", - "// modification, are permitted provided that the following conditions", - "// are met:", - "// * Redistributions of source code must retain the above copyright", - "// notice, this list of conditions and the following disclaimer.", - "// * Redistributions in binary form must reproduce the above copyright", - "// notice, this list of conditions and the following disclaimer in the", - "// documentation and/or other materials provided with the distribution.", - "// * Neither the name of NVIDIA CORPORATION nor the names of its", - "// contributors may be used to endorse or promote products derived", - "// from this software without specific prior written permission.", - "//", - "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY", - "// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE", - "// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", - "// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR", - "// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", - "// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,", - "// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR", - "// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY", - "// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT", - "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE", - "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", - "//", - "//----------------------------------------------------------------------------------", - "", - "#define FXAA_PC 1", - "#define FXAA_GLSL_100 1", - "#define FXAA_QUALITY_PRESET 12", - "", - "#define FXAA_GREEN_AS_LUMA 1", - "", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_PC_CONSOLE", - " //", - " // The console algorithm for PC is included", - " // for developers targeting really low spec machines.", - " // Likely better to just run FXAA_PC, and use a really low preset.", - " //", - " #define FXAA_PC_CONSOLE 0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_GLSL_120", - " #define FXAA_GLSL_120 0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_GLSL_130", - " #define FXAA_GLSL_130 0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_HLSL_3", - " #define FXAA_HLSL_3 0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_HLSL_4", - " #define FXAA_HLSL_4 0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_HLSL_5", - " #define FXAA_HLSL_5 0", - "#endif", - "/*==========================================================================*/", - "#ifndef FXAA_GREEN_AS_LUMA", - " //", - " // For those using non-linear color,", - " // and either not able to get luma in alpha, or not wanting to,", - " // this enables FXAA to run using green as a proxy for luma.", - " // So with this enabled, no need to pack luma in alpha.", - " //", - " // This will turn off AA on anything which lacks some amount of green.", - " // Pure red and blue or combination of only R and B, will get no AA.", - " //", - " // Might want to lower the settings for both,", - " // fxaaConsoleEdgeThresholdMin", - " // fxaaQualityEdgeThresholdMin", - " // In order to insure AA does not get turned off on colors", - " // which contain a minor amount of green.", - " //", - " // 1 = On.", - " // 0 = Off.", - " //", - " #define FXAA_GREEN_AS_LUMA 0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_EARLY_EXIT", - " //", - " // Controls algorithm's early exit path.", - " // On PS3 turning this ON adds 2 cycles to the shader.", - " // On 360 turning this OFF adds 10ths of a millisecond to the shader.", - " // Turning this off on console will result in a more blurry image.", - " // So this defaults to on.", - " //", - " // 1 = On.", - " // 0 = Off.", - " //", - " #define FXAA_EARLY_EXIT 1", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_DISCARD", - " //", - " // Only valid for PC OpenGL currently.", - " // Probably will not work when FXAA_GREEN_AS_LUMA = 1.", - " //", - " // 1 = Use discard on pixels which don't need AA.", - " // For APIs which enable concurrent TEX+ROP from same surface.", - " // 0 = Return unchanged color on pixels which don't need AA.", - " //", - " #define FXAA_DISCARD 0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_FAST_PIXEL_OFFSET", - " //", - " // Used for GLSL 120 only.", - " //", - " // 1 = GL API supports fast pixel offsets", - " // 0 = do not use fast pixel offsets", - " //", - " #ifdef GL_EXT_gpu_shader4", - " #define FXAA_FAST_PIXEL_OFFSET 1", - " #endif", - " #ifdef GL_NV_gpu_shader5", - " #define FXAA_FAST_PIXEL_OFFSET 1", - " #endif", - " #ifdef GL_ARB_gpu_shader5", - " #define FXAA_FAST_PIXEL_OFFSET 1", - " #endif", - " #ifndef FXAA_FAST_PIXEL_OFFSET", - " #define FXAA_FAST_PIXEL_OFFSET 0", - " #endif", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#ifndef FXAA_GATHER4_ALPHA", - " //", - " // 1 = API supports gather4 on alpha channel.", - " // 0 = API does not support gather4 on alpha channel.", - " //", - " #if (FXAA_HLSL_5 == 1)", - " #define FXAA_GATHER4_ALPHA 1", - " #endif", - " #ifdef GL_ARB_gpu_shader5", - " #define FXAA_GATHER4_ALPHA 1", - " #endif", - " #ifdef GL_NV_gpu_shader5", - " #define FXAA_GATHER4_ALPHA 1", - " #endif", - " #ifndef FXAA_GATHER4_ALPHA", - " #define FXAA_GATHER4_ALPHA 0", - " #endif", - "#endif", - "", - "", - "/*============================================================================", - " FXAA QUALITY - TUNING KNOBS", - "------------------------------------------------------------------------------", - "NOTE the other tuning knobs are now in the shader function inputs!", - "============================================================================*/", - "#ifndef FXAA_QUALITY_PRESET", - " //", - " // Choose the quality preset.", - " // This needs to be compiled into the shader as it effects code.", - " // Best option to include multiple presets is to", - " // in each shader define the preset, then include this file.", - " //", - " // OPTIONS", - " // -----------------------------------------------------------------------", - " // 10 to 15 - default medium dither (10=fastest, 15=highest quality)", - " // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)", - " // 39 - no dither, very expensive", - " //", - " // NOTES", - " // -----------------------------------------------------------------------", - " // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)", - " // 13 = about same speed as FXAA 3.9 and better than 12", - " // 23 = closest to FXAA 3.9 visually and performance wise", - " // _ = the lowest digit is directly related to performance", - " // _ = the highest digit is directly related to style", - " //", - " #define FXAA_QUALITY_PRESET 12", - "#endif", - "", - "", - "/*============================================================================", - "", - " FXAA QUALITY - PRESETS", - "", - "============================================================================*/", - "", - "/*============================================================================", - " FXAA QUALITY - MEDIUM DITHER PRESETS", - "============================================================================*/", - "#if (FXAA_QUALITY_PRESET == 10)", - " #define FXAA_QUALITY_PS 3", - " #define FXAA_QUALITY_P0 1.5", - " #define FXAA_QUALITY_P1 3.0", - " #define FXAA_QUALITY_P2 12.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 11)", - " #define FXAA_QUALITY_PS 4", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 3.0", - " #define FXAA_QUALITY_P3 12.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 12)", - " #define FXAA_QUALITY_PS 5", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 4.0", - " #define FXAA_QUALITY_P4 12.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 13)", - " #define FXAA_QUALITY_PS 6", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 4.0", - " #define FXAA_QUALITY_P5 12.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 14)", - " #define FXAA_QUALITY_PS 7", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 4.0", - " #define FXAA_QUALITY_P6 12.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 15)", - " #define FXAA_QUALITY_PS 8", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 2.0", - " #define FXAA_QUALITY_P6 4.0", - " #define FXAA_QUALITY_P7 12.0", - "#endif", - "", - "/*============================================================================", - " FXAA QUALITY - LOW DITHER PRESETS", - "============================================================================*/", - "#if (FXAA_QUALITY_PRESET == 20)", - " #define FXAA_QUALITY_PS 3", - " #define FXAA_QUALITY_P0 1.5", - " #define FXAA_QUALITY_P1 2.0", - " #define FXAA_QUALITY_P2 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 21)", - " #define FXAA_QUALITY_PS 4", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 22)", - " #define FXAA_QUALITY_PS 5", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 23)", - " #define FXAA_QUALITY_PS 6", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 24)", - " #define FXAA_QUALITY_PS 7", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 3.0", - " #define FXAA_QUALITY_P6 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 25)", - " #define FXAA_QUALITY_PS 8", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 2.0", - " #define FXAA_QUALITY_P6 4.0", - " #define FXAA_QUALITY_P7 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 26)", - " #define FXAA_QUALITY_PS 9", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 2.0", - " #define FXAA_QUALITY_P6 2.0", - " #define FXAA_QUALITY_P7 4.0", - " #define FXAA_QUALITY_P8 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 27)", - " #define FXAA_QUALITY_PS 10", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 2.0", - " #define FXAA_QUALITY_P6 2.0", - " #define FXAA_QUALITY_P7 2.0", - " #define FXAA_QUALITY_P8 4.0", - " #define FXAA_QUALITY_P9 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 28)", - " #define FXAA_QUALITY_PS 11", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 2.0", - " #define FXAA_QUALITY_P6 2.0", - " #define FXAA_QUALITY_P7 2.0", - " #define FXAA_QUALITY_P8 2.0", - " #define FXAA_QUALITY_P9 4.0", - " #define FXAA_QUALITY_P10 8.0", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_QUALITY_PRESET == 29)", - " #define FXAA_QUALITY_PS 12", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.5", - " #define FXAA_QUALITY_P2 2.0", - " #define FXAA_QUALITY_P3 2.0", - " #define FXAA_QUALITY_P4 2.0", - " #define FXAA_QUALITY_P5 2.0", - " #define FXAA_QUALITY_P6 2.0", - " #define FXAA_QUALITY_P7 2.0", - " #define FXAA_QUALITY_P8 2.0", - " #define FXAA_QUALITY_P9 2.0", - " #define FXAA_QUALITY_P10 4.0", - " #define FXAA_QUALITY_P11 8.0", - "#endif", - "", - "/*============================================================================", - " FXAA QUALITY - EXTREME QUALITY", - "============================================================================*/", - "#if (FXAA_QUALITY_PRESET == 39)", - " #define FXAA_QUALITY_PS 12", - " #define FXAA_QUALITY_P0 1.0", - " #define FXAA_QUALITY_P1 1.0", - " #define FXAA_QUALITY_P2 1.0", - " #define FXAA_QUALITY_P3 1.0", - " #define FXAA_QUALITY_P4 1.0", - " #define FXAA_QUALITY_P5 1.5", - " #define FXAA_QUALITY_P6 2.0", - " #define FXAA_QUALITY_P7 2.0", - " #define FXAA_QUALITY_P8 2.0", - " #define FXAA_QUALITY_P9 2.0", - " #define FXAA_QUALITY_P10 4.0", - " #define FXAA_QUALITY_P11 8.0", - "#endif", - "", - "", - "", - "/*============================================================================", - "", - " API PORTING", - "", - "============================================================================*/", - "#if (FXAA_GLSL_100 == 1) || (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)", - " #define FxaaBool bool", - " #define FxaaDiscard discard", - " #define FxaaFloat float", - " #define FxaaFloat2 vec2", - " #define FxaaFloat3 vec3", - " #define FxaaFloat4 vec4", - " #define FxaaHalf float", - " #define FxaaHalf2 vec2", - " #define FxaaHalf3 vec3", - " #define FxaaHalf4 vec4", - " #define FxaaInt2 ivec2", - " #define FxaaSat(x) clamp(x, 0.0, 1.0)", - " #define FxaaTex sampler2D", - "#else", - " #define FxaaBool bool", - " #define FxaaDiscard clip(-1)", - " #define FxaaFloat float", - " #define FxaaFloat2 float2", - " #define FxaaFloat3 float3", - " #define FxaaFloat4 float4", - " #define FxaaHalf half", - " #define FxaaHalf2 half2", - " #define FxaaHalf3 half3", - " #define FxaaHalf4 half4", - " #define FxaaSat(x) saturate(x)", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_GLSL_100 == 1)", - " #define FxaaTexTop(t, p) texture2D(t, p, 0.0)", - " #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), 0.0)", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_GLSL_120 == 1)", - " // Requires,", - " // #version 120", - " // And at least,", - " // #extension GL_EXT_gpu_shader4 : enable", - " // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)", - " #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)", - " #if (FXAA_FAST_PIXEL_OFFSET == 1)", - " #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)", - " #else", - " #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)", - " #endif", - " #if (FXAA_GATHER4_ALPHA == 1)", - " // use #extension GL_ARB_gpu_shader5 : enable", - " #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)", - " #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)", - " #define FxaaTexGreen4(t, p) textureGather(t, p, 1)", - " #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)", - " #endif", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_GLSL_130 == 1)", - " // Requires \"#version 130\" or better", - " #define FxaaTexTop(t, p) textureLod(t, p, 0.0)", - " #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)", - " #if (FXAA_GATHER4_ALPHA == 1)", - " // use #extension GL_ARB_gpu_shader5 : enable", - " #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)", - " #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)", - " #define FxaaTexGreen4(t, p) textureGather(t, p, 1)", - " #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)", - " #endif", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_HLSL_3 == 1)", - " #define FxaaInt2 float2", - " #define FxaaTex sampler2D", - " #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))", - " #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_HLSL_4 == 1)", - " #define FxaaInt2 int2", - " struct FxaaTex { SamplerState smpl; Texture2D tex; };", - " #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)", - " #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)", - "#endif", - "/*--------------------------------------------------------------------------*/", - "#if (FXAA_HLSL_5 == 1)", - " #define FxaaInt2 int2", - " struct FxaaTex { SamplerState smpl; Texture2D tex; };", - " #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)", - " #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)", - " #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)", - " #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)", - " #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)", - " #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)", - "#endif", - "", - "", - "/*============================================================================", - " GREEN AS LUMA OPTION SUPPORT FUNCTION", - "============================================================================*/", - "#if (FXAA_GREEN_AS_LUMA == 0)", - " FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }", - "#else", - " FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }", - "#endif", - "", - "", - "", - "", - "/*============================================================================", - "", - " FXAA3 QUALITY - PC", - "", - "============================================================================*/", - "#if (FXAA_PC == 1)", - "/*--------------------------------------------------------------------------*/", - "FxaaFloat4 FxaaPixelShader(", - " //", - " // Use noperspective interpolation here (turn off perspective interpolation).", - " // {xy} = center of pixel", - " FxaaFloat2 pos,", - " //", - " // Used only for FXAA Console, and not used on the 360 version.", - " // Use noperspective interpolation here (turn off perspective interpolation).", - " // {xy_} = upper left of pixel", - " // {_zw} = lower right of pixel", - " FxaaFloat4 fxaaConsolePosPos,", - " //", - " // Input color texture.", - " // {rgb_} = color in linear or perceptual color space", - " // if (FXAA_GREEN_AS_LUMA == 0)", - " // {__a} = luma in perceptual color space (not linear)", - " FxaaTex tex,", - " //", - " // Only used on the optimized 360 version of FXAA Console.", - " // For everything but 360, just use the same input here as for \"tex\".", - " // For 360, same texture, just alias with a 2nd sampler.", - " // This sampler needs to have an exponent bias of -1.", - " FxaaTex fxaaConsole360TexExpBiasNegOne,", - " //", - " // Only used on the optimized 360 version of FXAA Console.", - " // For everything but 360, just use the same input here as for \"tex\".", - " // For 360, same texture, just alias with a 3nd sampler.", - " // This sampler needs to have an exponent bias of -2.", - " FxaaTex fxaaConsole360TexExpBiasNegTwo,", - " //", - " // Only used on FXAA Quality.", - " // This must be from a constant/uniform.", - " // {x_} = 1.0/screenWidthInPixels", - " // {_y} = 1.0/screenHeightInPixels", - " FxaaFloat2 fxaaQualityRcpFrame,", - " //", - " // Only used on FXAA Console.", - " // This must be from a constant/uniform.", - " // This effects sub-pixel AA quality and inversely sharpness.", - " // Where N ranges between,", - " // N = 0.50 (default)", - " // N = 0.33 (sharper)", - " // {x__} = -N/screenWidthInPixels", - " // {_y_} = -N/screenHeightInPixels", - " // {_z_} = N/screenWidthInPixels", - " // {__w} = N/screenHeightInPixels", - " FxaaFloat4 fxaaConsoleRcpFrameOpt,", - " //", - " // Only used on FXAA Console.", - " // Not used on 360, but used on PS3 and PC.", - " // This must be from a constant/uniform.", - " // {x__} = -2.0/screenWidthInPixels", - " // {_y_} = -2.0/screenHeightInPixels", - " // {_z_} = 2.0/screenWidthInPixels", - " // {__w} = 2.0/screenHeightInPixels", - " FxaaFloat4 fxaaConsoleRcpFrameOpt2,", - " //", - " // Only used on FXAA Console.", - " // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.", - " // This must be from a constant/uniform.", - " // {x__} = 8.0/screenWidthInPixels", - " // {_y_} = 8.0/screenHeightInPixels", - " // {_z_} = -4.0/screenWidthInPixels", - " // {__w} = -4.0/screenHeightInPixels", - " FxaaFloat4 fxaaConsole360RcpFrameOpt2,", - " //", - " // Only used on FXAA Quality.", - " // This used to be the FXAA_QUALITY_SUBPIX define.", - " // It is here now to allow easier tuning.", - " // Choose the amount of sub-pixel aliasing removal.", - " // This can effect sharpness.", - " // 1.00 - upper limit (softer)", - " // 0.75 - default amount of filtering", - " // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)", - " // 0.25 - almost off", - " // 0.00 - completely off", - " FxaaFloat fxaaQualitySubpix,", - " //", - " // Only used on FXAA Quality.", - " // This used to be the FXAA_QUALITY_EDGE_THRESHOLD define.", - " // It is here now to allow easier tuning.", - " // The minimum amount of local contrast required to apply algorithm.", - " // 0.333 - too little (faster)", - " // 0.250 - low quality", - " // 0.166 - default", - " // 0.125 - high quality", - " // 0.063 - overkill (slower)", - " FxaaFloat fxaaQualityEdgeThreshold,", - " //", - " // Only used on FXAA Quality.", - " // This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define.", - " // It is here now to allow easier tuning.", - " // Trims the algorithm from processing darks.", - " // 0.0833 - upper limit (default, the start of visible unfiltered edges)", - " // 0.0625 - high quality (faster)", - " // 0.0312 - visible limit (slower)", - " // Special notes when using FXAA_GREEN_AS_LUMA,", - " // Likely want to set this to zero.", - " // As colors that are mostly not-green", - " // will appear very dark in the green channel!", - " // Tune by looking at mostly non-green content,", - " // then start at zero and increase until aliasing is a problem.", - " FxaaFloat fxaaQualityEdgeThresholdMin,", - " //", - " // Only used on FXAA Console.", - " // This used to be the FXAA_CONSOLE_EDGE_SHARPNESS define.", - " // It is here now to allow easier tuning.", - " // This does not effect PS3, as this needs to be compiled in.", - " // Use FXAA_CONSOLE_PS3_EDGE_SHARPNESS for PS3.", - " // Due to the PS3 being ALU bound,", - " // there are only three safe values here: 2 and 4 and 8.", - " // These options use the shaders ability to a free *|/ by 2|4|8.", - " // For all other platforms can be a non-power of two.", - " // 8.0 is sharper (default!!!)", - " // 4.0 is softer", - " // 2.0 is really soft (good only for vector graphics inputs)", - " FxaaFloat fxaaConsoleEdgeSharpness,", - " //", - " // Only used on FXAA Console.", - " // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD define.", - " // It is here now to allow easier tuning.", - " // This does not effect PS3, as this needs to be compiled in.", - " // Use FXAA_CONSOLE_PS3_EDGE_THRESHOLD for PS3.", - " // Due to the PS3 being ALU bound,", - " // there are only two safe values here: 1/4 and 1/8.", - " // These options use the shaders ability to a free *|/ by 2|4|8.", - " // The console setting has a different mapping than the quality setting.", - " // Other platforms can use other values.", - " // 0.125 leaves less aliasing, but is softer (default!!!)", - " // 0.25 leaves more aliasing, and is sharper", - " FxaaFloat fxaaConsoleEdgeThreshold,", - " //", - " // Only used on FXAA Console.", - " // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD_MIN define.", - " // It is here now to allow easier tuning.", - " // Trims the algorithm from processing darks.", - " // The console setting has a different mapping than the quality setting.", - " // This only applies when FXAA_EARLY_EXIT is 1.", - " // This does not apply to PS3,", - " // PS3 was simplified to avoid more shader instructions.", - " // 0.06 - faster but more aliasing in darks", - " // 0.05 - default", - " // 0.04 - slower and less aliasing in darks", - " // Special notes when using FXAA_GREEN_AS_LUMA,", - " // Likely want to set this to zero.", - " // As colors that are mostly not-green", - " // will appear very dark in the green channel!", - " // Tune by looking at mostly non-green content,", - " // then start at zero and increase until aliasing is a problem.", - " FxaaFloat fxaaConsoleEdgeThresholdMin,", - " //", - " // Extra constants for 360 FXAA Console only.", - " // Use zeros or anything else for other platforms.", - " // These must be in physical constant registers and NOT immediates.", - " // Immediates will result in compiler un-optimizing.", - " // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)", - " FxaaFloat4 fxaaConsole360ConstDir", - ") {", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat2 posM;", - " posM.x = pos.x;", - " posM.y = pos.y;", - " #if (FXAA_GATHER4_ALPHA == 1)", - " #if (FXAA_DISCARD == 0)", - " FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);", - " #if (FXAA_GREEN_AS_LUMA == 0)", - " #define lumaM rgbyM.w", - " #else", - " #define lumaM rgbyM.y", - " #endif", - " #endif", - " #if (FXAA_GREEN_AS_LUMA == 0)", - " FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);", - " FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));", - " #else", - " FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);", - " FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));", - " #endif", - " #if (FXAA_DISCARD == 1)", - " #define lumaM luma4A.w", - " #endif", - " #define lumaE luma4A.z", - " #define lumaS luma4A.x", - " #define lumaSE luma4A.y", - " #define lumaNW luma4B.w", - " #define lumaN luma4B.z", - " #define lumaW luma4B.x", - " #else", - " FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);", - " #if (FXAA_GREEN_AS_LUMA == 0)", - " #define lumaM rgbyM.w", - " #else", - " #define lumaM rgbyM.y", - " #endif", - " #if (FXAA_GLSL_100 == 1)", - " FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0, 1.0), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 0.0), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0,-1.0), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 0.0), fxaaQualityRcpFrame.xy));", - " #else", - " FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));", - " #endif", - " #endif", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat maxSM = max(lumaS, lumaM);", - " FxaaFloat minSM = min(lumaS, lumaM);", - " FxaaFloat maxESM = max(lumaE, maxSM);", - " FxaaFloat minESM = min(lumaE, minSM);", - " FxaaFloat maxWN = max(lumaN, lumaW);", - " FxaaFloat minWN = min(lumaN, lumaW);", - " FxaaFloat rangeMax = max(maxWN, maxESM);", - " FxaaFloat rangeMin = min(minWN, minESM);", - " FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;", - " FxaaFloat range = rangeMax - rangeMin;", - " FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);", - " FxaaBool earlyExit = range < rangeMaxClamped;", - "/*--------------------------------------------------------------------------*/", - " if(earlyExit)", - " #if (FXAA_DISCARD == 1)", - " FxaaDiscard;", - " #else", - " return rgbyM;", - " #endif", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_GATHER4_ALPHA == 0)", - " #if (FXAA_GLSL_100 == 1)", - " FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0,-1.0), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 1.0), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0,-1.0), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 1.0), fxaaQualityRcpFrame.xy));", - " #else", - " FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));", - " #endif", - " #else", - " FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));", - " FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));", - " #endif", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat lumaNS = lumaN + lumaS;", - " FxaaFloat lumaWE = lumaW + lumaE;", - " FxaaFloat subpixRcpRange = 1.0/range;", - " FxaaFloat subpixNSWE = lumaNS + lumaWE;", - " FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;", - " FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat lumaNESE = lumaNE + lumaSE;", - " FxaaFloat lumaNWNE = lumaNW + lumaNE;", - " FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;", - " FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat lumaNWSW = lumaNW + lumaSW;", - " FxaaFloat lumaSWSE = lumaSW + lumaSE;", - " FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);", - " FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);", - " FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;", - " FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;", - " FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;", - " FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;", - " FxaaFloat lengthSign = fxaaQualityRcpFrame.x;", - " FxaaBool horzSpan = edgeHorz >= edgeVert;", - " FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;", - "/*--------------------------------------------------------------------------*/", - " if(!horzSpan) lumaN = lumaW;", - " if(!horzSpan) lumaS = lumaE;", - " if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;", - " FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat gradientN = lumaN - lumaM;", - " FxaaFloat gradientS = lumaS - lumaM;", - " FxaaFloat lumaNN = lumaN + lumaM;", - " FxaaFloat lumaSS = lumaS + lumaM;", - " FxaaBool pairN = abs(gradientN) >= abs(gradientS);", - " FxaaFloat gradient = max(abs(gradientN), abs(gradientS));", - " if(pairN) lengthSign = -lengthSign;", - " FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat2 posB;", - " posB.x = posM.x;", - " posB.y = posM.y;", - " FxaaFloat2 offNP;", - " offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;", - " offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;", - " if(!horzSpan) posB.x += lengthSign * 0.5;", - " if( horzSpan) posB.y += lengthSign * 0.5;", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat2 posN;", - " posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;", - " posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;", - " FxaaFloat2 posP;", - " posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;", - " posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;", - " FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;", - " FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));", - " FxaaFloat subpixE = subpixC * subpixC;", - " FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));", - "/*--------------------------------------------------------------------------*/", - " if(!pairN) lumaNN = lumaSS;", - " FxaaFloat gradientScaled = gradient * 1.0/4.0;", - " FxaaFloat lumaMM = lumaM - lumaNN * 0.5;", - " FxaaFloat subpixF = subpixD * subpixE;", - " FxaaBool lumaMLTZero = lumaMM < 0.0;", - "/*--------------------------------------------------------------------------*/", - " lumaEndN -= lumaNN * 0.5;", - " lumaEndP -= lumaNN * 0.5;", - " FxaaBool doneN = abs(lumaEndN) >= gradientScaled;", - " FxaaBool doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;", - " FxaaBool doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;", - "/*--------------------------------------------------------------------------*/", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 3)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 4)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 5)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 6)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 7)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 8)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 9)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 10)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 11)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;", - "/*--------------------------------------------------------------------------*/", - " #if (FXAA_QUALITY_PS > 12)", - " if(doneNP) {", - " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", - " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", - " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", - " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", - " doneN = abs(lumaEndN) >= gradientScaled;", - " doneP = abs(lumaEndP) >= gradientScaled;", - " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;", - " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;", - " doneNP = (!doneN) || (!doneP);", - " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;", - " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - " #endif", - "/*--------------------------------------------------------------------------*/", - " }", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat dstN = posM.x - posN.x;", - " FxaaFloat dstP = posP.x - posM.x;", - " if(!horzSpan) dstN = posM.y - posN.y;", - " if(!horzSpan) dstP = posP.y - posM.y;", - "/*--------------------------------------------------------------------------*/", - " FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;", - " FxaaFloat spanLength = (dstP + dstN);", - " FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;", - " FxaaFloat spanLengthRcp = 1.0/spanLength;", - "/*--------------------------------------------------------------------------*/", - " FxaaBool directionN = dstN < dstP;", - " FxaaFloat dst = min(dstN, dstP);", - " FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;", - " FxaaFloat subpixG = subpixF * subpixF;", - " FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;", - " FxaaFloat subpixH = subpixG * fxaaQualitySubpix;", - "/*--------------------------------------------------------------------------*/", - " FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;", - " FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);", - " if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;", - " if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;", - " #if (FXAA_DISCARD == 1)", - " return FxaaTexTop(tex, posM);", - " #else", - " return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);", - " #endif", - "}", - "/*==========================================================================*/", - "#endif", - "", - "void main() {", - " gl_FragColor = FxaaPixelShader(", - " vUv,", - " vec4(0.0),", - " tDiffuse,", - " tDiffuse,", - " tDiffuse,", - " resolution,", - " vec4(0.0),", - " vec4(0.0),", - " vec4(0.0),", - " 0.75,", - " 0.166,", - " 0.0833,", - " 0.0,", - " 0.0,", - " 0.0,", - " vec4(0.0)", - " );", - "", - " // TODO avoid querying texture twice for same texel", - " gl_FragColor.a = texture2D(tDiffuse, vUv).a;", - "}" - ].join("\n") + "precision highp float;", + "", + "uniform sampler2D tDiffuse;", + "", + "uniform vec2 resolution;", + "", + "varying vec2 vUv;", + "", + "// FXAA 3.11 implementation by NVIDIA, ported to WebGL by Agost Biro (biro@archilogic.com)", + "", + "//----------------------------------------------------------------------------------", + "// File: es3-kepler\FXAA\assets\shaders/FXAA_DefaultES.frag", + "// SDK Version: v3.00", + "// Email: gameworks@nvidia.com", + "// Site: http://developer.nvidia.com/", + "//", + "// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.", + "//", + "// Redistribution and use in source and binary forms, with or without", + "// modification, are permitted provided that the following conditions", + "// are met:", + "// * Redistributions of source code must retain the above copyright", + "// notice, this list of conditions and the following disclaimer.", + "// * Redistributions in binary form must reproduce the above copyright", + "// notice, this list of conditions and the following disclaimer in the", + "// documentation and/or other materials provided with the distribution.", + "// * Neither the name of NVIDIA CORPORATION nor the names of its", + "// contributors may be used to endorse or promote products derived", + "// from this software without specific prior written permission.", + "//", + "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY", + "// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE", + "// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", + "// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR", + "// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", + "// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,", + "// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR", + "// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY", + "// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT", + "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE", + "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", + "//", + "//----------------------------------------------------------------------------------", + "", + "#define FXAA_PC 1", + "#define FXAA_GLSL_100 1", + "#define FXAA_QUALITY_PRESET 12", + "", + "#define FXAA_GREEN_AS_LUMA 1", + "", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_PC_CONSOLE", + " //", + " // The console algorithm for PC is included", + " // for developers targeting really low spec machines.", + " // Likely better to just run FXAA_PC, and use a really low preset.", + " //", + " #define FXAA_PC_CONSOLE 0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_GLSL_120", + " #define FXAA_GLSL_120 0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_GLSL_130", + " #define FXAA_GLSL_130 0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_HLSL_3", + " #define FXAA_HLSL_3 0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_HLSL_4", + " #define FXAA_HLSL_4 0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_HLSL_5", + " #define FXAA_HLSL_5 0", + "#endif", + "/*==========================================================================*/", + "#ifndef FXAA_GREEN_AS_LUMA", + " //", + " // For those using non-linear color,", + " // and either not able to get luma in alpha, or not wanting to,", + " // this enables FXAA to run using green as a proxy for luma.", + " // So with this enabled, no need to pack luma in alpha.", + " //", + " // This will turn off AA on anything which lacks some amount of green.", + " // Pure red and blue or combination of only R and B, will get no AA.", + " //", + " // Might want to lower the settings for both,", + " // fxaaConsoleEdgeThresholdMin", + " // fxaaQualityEdgeThresholdMin", + " // In order to insure AA does not get turned off on colors", + " // which contain a minor amount of green.", + " //", + " // 1 = On.", + " // 0 = Off.", + " //", + " #define FXAA_GREEN_AS_LUMA 0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_EARLY_EXIT", + " //", + " // Controls algorithm's early exit path.", + " // On PS3 turning this ON adds 2 cycles to the shader.", + " // On 360 turning this OFF adds 10ths of a millisecond to the shader.", + " // Turning this off on console will result in a more blurry image.", + " // So this defaults to on.", + " //", + " // 1 = On.", + " // 0 = Off.", + " //", + " #define FXAA_EARLY_EXIT 1", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_DISCARD", + " //", + " // Only valid for PC OpenGL currently.", + " // Probably will not work when FXAA_GREEN_AS_LUMA = 1.", + " //", + " // 1 = Use discard on pixels which don't need AA.", + " // For APIs which enable concurrent TEX+ROP from same surface.", + " // 0 = Return unchanged color on pixels which don't need AA.", + " //", + " #define FXAA_DISCARD 0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_FAST_PIXEL_OFFSET", + " //", + " // Used for GLSL 120 only.", + " //", + " // 1 = GL API supports fast pixel offsets", + " // 0 = do not use fast pixel offsets", + " //", + " #ifdef GL_EXT_gpu_shader4", + " #define FXAA_FAST_PIXEL_OFFSET 1", + " #endif", + " #ifdef GL_NV_gpu_shader5", + " #define FXAA_FAST_PIXEL_OFFSET 1", + " #endif", + " #ifdef GL_ARB_gpu_shader5", + " #define FXAA_FAST_PIXEL_OFFSET 1", + " #endif", + " #ifndef FXAA_FAST_PIXEL_OFFSET", + " #define FXAA_FAST_PIXEL_OFFSET 0", + " #endif", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#ifndef FXAA_GATHER4_ALPHA", + " //", + " // 1 = API supports gather4 on alpha channel.", + " // 0 = API does not support gather4 on alpha channel.", + " //", + " #if (FXAA_HLSL_5 == 1)", + " #define FXAA_GATHER4_ALPHA 1", + " #endif", + " #ifdef GL_ARB_gpu_shader5", + " #define FXAA_GATHER4_ALPHA 1", + " #endif", + " #ifdef GL_NV_gpu_shader5", + " #define FXAA_GATHER4_ALPHA 1", + " #endif", + " #ifndef FXAA_GATHER4_ALPHA", + " #define FXAA_GATHER4_ALPHA 0", + " #endif", + "#endif", + "", + "", + "/*============================================================================", + " FXAA QUALITY - TUNING KNOBS", + "------------------------------------------------------------------------------", + "NOTE the other tuning knobs are now in the shader function inputs!", + "============================================================================*/", + "#ifndef FXAA_QUALITY_PRESET", + " //", + " // Choose the quality preset.", + " // This needs to be compiled into the shader as it effects code.", + " // Best option to include multiple presets is to", + " // in each shader define the preset, then include this file.", + " //", + " // OPTIONS", + " // -----------------------------------------------------------------------", + " // 10 to 15 - default medium dither (10=fastest, 15=highest quality)", + " // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)", + " // 39 - no dither, very expensive", + " //", + " // NOTES", + " // -----------------------------------------------------------------------", + " // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)", + " // 13 = about same speed as FXAA 3.9 and better than 12", + " // 23 = closest to FXAA 3.9 visually and performance wise", + " // _ = the lowest digit is directly related to performance", + " // _ = the highest digit is directly related to style", + " //", + " #define FXAA_QUALITY_PRESET 12", + "#endif", + "", + "", + "/*============================================================================", + "", + " FXAA QUALITY - PRESETS", + "", + "============================================================================*/", + "", + "/*============================================================================", + " FXAA QUALITY - MEDIUM DITHER PRESETS", + "============================================================================*/", + "#if (FXAA_QUALITY_PRESET == 10)", + " #define FXAA_QUALITY_PS 3", + " #define FXAA_QUALITY_P0 1.5", + " #define FXAA_QUALITY_P1 3.0", + " #define FXAA_QUALITY_P2 12.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 11)", + " #define FXAA_QUALITY_PS 4", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 3.0", + " #define FXAA_QUALITY_P3 12.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 12)", + " #define FXAA_QUALITY_PS 5", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 4.0", + " #define FXAA_QUALITY_P4 12.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 13)", + " #define FXAA_QUALITY_PS 6", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 4.0", + " #define FXAA_QUALITY_P5 12.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 14)", + " #define FXAA_QUALITY_PS 7", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 4.0", + " #define FXAA_QUALITY_P6 12.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 15)", + " #define FXAA_QUALITY_PS 8", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 2.0", + " #define FXAA_QUALITY_P6 4.0", + " #define FXAA_QUALITY_P7 12.0", + "#endif", + "", + "/*============================================================================", + " FXAA QUALITY - LOW DITHER PRESETS", + "============================================================================*/", + "#if (FXAA_QUALITY_PRESET == 20)", + " #define FXAA_QUALITY_PS 3", + " #define FXAA_QUALITY_P0 1.5", + " #define FXAA_QUALITY_P1 2.0", + " #define FXAA_QUALITY_P2 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 21)", + " #define FXAA_QUALITY_PS 4", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 22)", + " #define FXAA_QUALITY_PS 5", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 23)", + " #define FXAA_QUALITY_PS 6", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 24)", + " #define FXAA_QUALITY_PS 7", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 3.0", + " #define FXAA_QUALITY_P6 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 25)", + " #define FXAA_QUALITY_PS 8", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 2.0", + " #define FXAA_QUALITY_P6 4.0", + " #define FXAA_QUALITY_P7 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 26)", + " #define FXAA_QUALITY_PS 9", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 2.0", + " #define FXAA_QUALITY_P6 2.0", + " #define FXAA_QUALITY_P7 4.0", + " #define FXAA_QUALITY_P8 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 27)", + " #define FXAA_QUALITY_PS 10", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 2.0", + " #define FXAA_QUALITY_P6 2.0", + " #define FXAA_QUALITY_P7 2.0", + " #define FXAA_QUALITY_P8 4.0", + " #define FXAA_QUALITY_P9 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 28)", + " #define FXAA_QUALITY_PS 11", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 2.0", + " #define FXAA_QUALITY_P6 2.0", + " #define FXAA_QUALITY_P7 2.0", + " #define FXAA_QUALITY_P8 2.0", + " #define FXAA_QUALITY_P9 4.0", + " #define FXAA_QUALITY_P10 8.0", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_QUALITY_PRESET == 29)", + " #define FXAA_QUALITY_PS 12", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.5", + " #define FXAA_QUALITY_P2 2.0", + " #define FXAA_QUALITY_P3 2.0", + " #define FXAA_QUALITY_P4 2.0", + " #define FXAA_QUALITY_P5 2.0", + " #define FXAA_QUALITY_P6 2.0", + " #define FXAA_QUALITY_P7 2.0", + " #define FXAA_QUALITY_P8 2.0", + " #define FXAA_QUALITY_P9 2.0", + " #define FXAA_QUALITY_P10 4.0", + " #define FXAA_QUALITY_P11 8.0", + "#endif", + "", + "/*============================================================================", + " FXAA QUALITY - EXTREME QUALITY", + "============================================================================*/", + "#if (FXAA_QUALITY_PRESET == 39)", + " #define FXAA_QUALITY_PS 12", + " #define FXAA_QUALITY_P0 1.0", + " #define FXAA_QUALITY_P1 1.0", + " #define FXAA_QUALITY_P2 1.0", + " #define FXAA_QUALITY_P3 1.0", + " #define FXAA_QUALITY_P4 1.0", + " #define FXAA_QUALITY_P5 1.5", + " #define FXAA_QUALITY_P6 2.0", + " #define FXAA_QUALITY_P7 2.0", + " #define FXAA_QUALITY_P8 2.0", + " #define FXAA_QUALITY_P9 2.0", + " #define FXAA_QUALITY_P10 4.0", + " #define FXAA_QUALITY_P11 8.0", + "#endif", + "", + "", + "", + "/*============================================================================", + "", + " API PORTING", + "", + "============================================================================*/", + "#if (FXAA_GLSL_100 == 1) || (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)", + " #define FxaaBool bool", + " #define FxaaDiscard discard", + " #define FxaaFloat float", + " #define FxaaFloat2 vec2", + " #define FxaaFloat3 vec3", + " #define FxaaFloat4 vec4", + " #define FxaaHalf float", + " #define FxaaHalf2 vec2", + " #define FxaaHalf3 vec3", + " #define FxaaHalf4 vec4", + " #define FxaaInt2 ivec2", + " #define FxaaSat(x) clamp(x, 0.0, 1.0)", + " #define FxaaTex sampler2D", + "#else", + " #define FxaaBool bool", + " #define FxaaDiscard clip(-1)", + " #define FxaaFloat float", + " #define FxaaFloat2 float2", + " #define FxaaFloat3 float3", + " #define FxaaFloat4 float4", + " #define FxaaHalf half", + " #define FxaaHalf2 half2", + " #define FxaaHalf3 half3", + " #define FxaaHalf4 half4", + " #define FxaaSat(x) saturate(x)", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_GLSL_100 == 1)", + " #define FxaaTexTop(t, p) texture2D(t, p, 0.0)", + " #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), 0.0)", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_GLSL_120 == 1)", + " // Requires,", + " // #version 120", + " // And at least,", + " // #extension GL_EXT_gpu_shader4 : enable", + " // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)", + " #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)", + " #if (FXAA_FAST_PIXEL_OFFSET == 1)", + " #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)", + " #else", + " #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)", + " #endif", + " #if (FXAA_GATHER4_ALPHA == 1)", + " // use #extension GL_ARB_gpu_shader5 : enable", + " #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)", + " #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)", + " #define FxaaTexGreen4(t, p) textureGather(t, p, 1)", + " #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)", + " #endif", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_GLSL_130 == 1)", + " // Requires \"#version 130\" or better", + " #define FxaaTexTop(t, p) textureLod(t, p, 0.0)", + " #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)", + " #if (FXAA_GATHER4_ALPHA == 1)", + " // use #extension GL_ARB_gpu_shader5 : enable", + " #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)", + " #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)", + " #define FxaaTexGreen4(t, p) textureGather(t, p, 1)", + " #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)", + " #endif", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_HLSL_3 == 1)", + " #define FxaaInt2 float2", + " #define FxaaTex sampler2D", + " #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))", + " #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_HLSL_4 == 1)", + " #define FxaaInt2 int2", + " struct FxaaTex { SamplerState smpl; Texture2D tex; };", + " #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)", + " #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)", + "#endif", + "/*--------------------------------------------------------------------------*/", + "#if (FXAA_HLSL_5 == 1)", + " #define FxaaInt2 int2", + " struct FxaaTex { SamplerState smpl; Texture2D tex; };", + " #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)", + " #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)", + " #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)", + " #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)", + " #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)", + " #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)", + "#endif", + "", + "", + "/*============================================================================", + " GREEN AS LUMA OPTION SUPPORT FUNCTION", + "============================================================================*/", + "#if (FXAA_GREEN_AS_LUMA == 0)", + " FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }", + "#else", + " FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }", + "#endif", + "", + "", + "", + "", + "/*============================================================================", + "", + " FXAA3 QUALITY - PC", + "", + "============================================================================*/", + "#if (FXAA_PC == 1)", + "/*--------------------------------------------------------------------------*/", + "FxaaFloat4 FxaaPixelShader(", + " //", + " // Use noperspective interpolation here (turn off perspective interpolation).", + " // {xy} = center of pixel", + " FxaaFloat2 pos,", + " //", + " // Used only for FXAA Console, and not used on the 360 version.", + " // Use noperspective interpolation here (turn off perspective interpolation).", + " // {xy_} = upper left of pixel", + " // {_zw} = lower right of pixel", + " FxaaFloat4 fxaaConsolePosPos,", + " //", + " // Input color texture.", + " // {rgb_} = color in linear or perceptual color space", + " // if (FXAA_GREEN_AS_LUMA == 0)", + " // {__a} = luma in perceptual color space (not linear)", + " FxaaTex tex,", + " //", + " // Only used on the optimized 360 version of FXAA Console.", + " // For everything but 360, just use the same input here as for \"tex\".", + " // For 360, same texture, just alias with a 2nd sampler.", + " // This sampler needs to have an exponent bias of -1.", + " FxaaTex fxaaConsole360TexExpBiasNegOne,", + " //", + " // Only used on the optimized 360 version of FXAA Console.", + " // For everything but 360, just use the same input here as for \"tex\".", + " // For 360, same texture, just alias with a 3nd sampler.", + " // This sampler needs to have an exponent bias of -2.", + " FxaaTex fxaaConsole360TexExpBiasNegTwo,", + " //", + " // Only used on FXAA Quality.", + " // This must be from a constant/uniform.", + " // {x_} = 1.0/screenWidthInPixels", + " // {_y} = 1.0/screenHeightInPixels", + " FxaaFloat2 fxaaQualityRcpFrame,", + " //", + " // Only used on FXAA Console.", + " // This must be from a constant/uniform.", + " // This effects sub-pixel AA quality and inversely sharpness.", + " // Where N ranges between,", + " // N = 0.50 (default)", + " // N = 0.33 (sharper)", + " // {x__} = -N/screenWidthInPixels", + " // {_y_} = -N/screenHeightInPixels", + " // {_z_} = N/screenWidthInPixels", + " // {__w} = N/screenHeightInPixels", + " FxaaFloat4 fxaaConsoleRcpFrameOpt,", + " //", + " // Only used on FXAA Console.", + " // Not used on 360, but used on PS3 and PC.", + " // This must be from a constant/uniform.", + " // {x__} = -2.0/screenWidthInPixels", + " // {_y_} = -2.0/screenHeightInPixels", + " // {_z_} = 2.0/screenWidthInPixels", + " // {__w} = 2.0/screenHeightInPixels", + " FxaaFloat4 fxaaConsoleRcpFrameOpt2,", + " //", + " // Only used on FXAA Console.", + " // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.", + " // This must be from a constant/uniform.", + " // {x__} = 8.0/screenWidthInPixels", + " // {_y_} = 8.0/screenHeightInPixels", + " // {_z_} = -4.0/screenWidthInPixels", + " // {__w} = -4.0/screenHeightInPixels", + " FxaaFloat4 fxaaConsole360RcpFrameOpt2,", + " //", + " // Only used on FXAA Quality.", + " // This used to be the FXAA_QUALITY_SUBPIX define.", + " // It is here now to allow easier tuning.", + " // Choose the amount of sub-pixel aliasing removal.", + " // This can effect sharpness.", + " // 1.00 - upper limit (softer)", + " // 0.75 - default amount of filtering", + " // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)", + " // 0.25 - almost off", + " // 0.00 - completely off", + " FxaaFloat fxaaQualitySubpix,", + " //", + " // Only used on FXAA Quality.", + " // This used to be the FXAA_QUALITY_EDGE_THRESHOLD define.", + " // It is here now to allow easier tuning.", + " // The minimum amount of local contrast required to apply algorithm.", + " // 0.333 - too little (faster)", + " // 0.250 - low quality", + " // 0.166 - default", + " // 0.125 - high quality", + " // 0.063 - overkill (slower)", + " FxaaFloat fxaaQualityEdgeThreshold,", + " //", + " // Only used on FXAA Quality.", + " // This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define.", + " // It is here now to allow easier tuning.", + " // Trims the algorithm from processing darks.", + " // 0.0833 - upper limit (default, the start of visible unfiltered edges)", + " // 0.0625 - high quality (faster)", + " // 0.0312 - visible limit (slower)", + " // Special notes when using FXAA_GREEN_AS_LUMA,", + " // Likely want to set this to zero.", + " // As colors that are mostly not-green", + " // will appear very dark in the green channel!", + " // Tune by looking at mostly non-green content,", + " // then start at zero and increase until aliasing is a problem.", + " FxaaFloat fxaaQualityEdgeThresholdMin,", + " //", + " // Only used on FXAA Console.", + " // This used to be the FXAA_CONSOLE_EDGE_SHARPNESS define.", + " // It is here now to allow easier tuning.", + " // This does not effect PS3, as this needs to be compiled in.", + " // Use FXAA_CONSOLE_PS3_EDGE_SHARPNESS for PS3.", + " // Due to the PS3 being ALU bound,", + " // there are only three safe values here: 2 and 4 and 8.", + " // These options use the shaders ability to a free *|/ by 2|4|8.", + " // For all other platforms can be a non-power of two.", + " // 8.0 is sharper (default!!!)", + " // 4.0 is softer", + " // 2.0 is really soft (good only for vector graphics inputs)", + " FxaaFloat fxaaConsoleEdgeSharpness,", + " //", + " // Only used on FXAA Console.", + " // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD define.", + " // It is here now to allow easier tuning.", + " // This does not effect PS3, as this needs to be compiled in.", + " // Use FXAA_CONSOLE_PS3_EDGE_THRESHOLD for PS3.", + " // Due to the PS3 being ALU bound,", + " // there are only two safe values here: 1/4 and 1/8.", + " // These options use the shaders ability to a free *|/ by 2|4|8.", + " // The console setting has a different mapping than the quality setting.", + " // Other platforms can use other values.", + " // 0.125 leaves less aliasing, but is softer (default!!!)", + " // 0.25 leaves more aliasing, and is sharper", + " FxaaFloat fxaaConsoleEdgeThreshold,", + " //", + " // Only used on FXAA Console.", + " // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD_MIN define.", + " // It is here now to allow easier tuning.", + " // Trims the algorithm from processing darks.", + " // The console setting has a different mapping than the quality setting.", + " // This only applies when FXAA_EARLY_EXIT is 1.", + " // This does not apply to PS3,", + " // PS3 was simplified to avoid more shader instructions.", + " // 0.06 - faster but more aliasing in darks", + " // 0.05 - default", + " // 0.04 - slower and less aliasing in darks", + " // Special notes when using FXAA_GREEN_AS_LUMA,", + " // Likely want to set this to zero.", + " // As colors that are mostly not-green", + " // will appear very dark in the green channel!", + " // Tune by looking at mostly non-green content,", + " // then start at zero and increase until aliasing is a problem.", + " FxaaFloat fxaaConsoleEdgeThresholdMin,", + " //", + " // Extra constants for 360 FXAA Console only.", + " // Use zeros or anything else for other platforms.", + " // These must be in physical constant registers and NOT immediates.", + " // Immediates will result in compiler un-optimizing.", + " // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)", + " FxaaFloat4 fxaaConsole360ConstDir", + ") {", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat2 posM;", + " posM.x = pos.x;", + " posM.y = pos.y;", + " #if (FXAA_GATHER4_ALPHA == 1)", + " #if (FXAA_DISCARD == 0)", + " FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);", + " #if (FXAA_GREEN_AS_LUMA == 0)", + " #define lumaM rgbyM.w", + " #else", + " #define lumaM rgbyM.y", + " #endif", + " #endif", + " #if (FXAA_GREEN_AS_LUMA == 0)", + " FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);", + " FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));", + " #else", + " FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);", + " FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));", + " #endif", + " #if (FXAA_DISCARD == 1)", + " #define lumaM luma4A.w", + " #endif", + " #define lumaE luma4A.z", + " #define lumaS luma4A.x", + " #define lumaSE luma4A.y", + " #define lumaNW luma4B.w", + " #define lumaN luma4B.z", + " #define lumaW luma4B.x", + " #else", + " FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);", + " #if (FXAA_GREEN_AS_LUMA == 0)", + " #define lumaM rgbyM.w", + " #else", + " #define lumaM rgbyM.y", + " #endif", + " #if (FXAA_GLSL_100 == 1)", + " FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0, 1.0), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 0.0), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 0.0,-1.0), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 0.0), fxaaQualityRcpFrame.xy));", + " #else", + " FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));", + " #endif", + " #endif", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat maxSM = max(lumaS, lumaM);", + " FxaaFloat minSM = min(lumaS, lumaM);", + " FxaaFloat maxESM = max(lumaE, maxSM);", + " FxaaFloat minESM = min(lumaE, minSM);", + " FxaaFloat maxWN = max(lumaN, lumaW);", + " FxaaFloat minWN = min(lumaN, lumaW);", + " FxaaFloat rangeMax = max(maxWN, maxESM);", + " FxaaFloat rangeMin = min(minWN, minESM);", + " FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;", + " FxaaFloat range = rangeMax - rangeMin;", + " FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);", + " FxaaBool earlyExit = range < rangeMaxClamped;", + "/*--------------------------------------------------------------------------*/", + " if(earlyExit)", + " #if (FXAA_DISCARD == 1)", + " FxaaDiscard;", + " #else", + " return rgbyM;", + " #endif", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_GATHER4_ALPHA == 0)", + " #if (FXAA_GLSL_100 == 1)", + " FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0,-1.0), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0, 1.0), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2( 1.0,-1.0), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaFloat2(-1.0, 1.0), fxaaQualityRcpFrame.xy));", + " #else", + " FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));", + " #endif", + " #else", + " FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));", + " FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));", + " #endif", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat lumaNS = lumaN + lumaS;", + " FxaaFloat lumaWE = lumaW + lumaE;", + " FxaaFloat subpixRcpRange = 1.0/range;", + " FxaaFloat subpixNSWE = lumaNS + lumaWE;", + " FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;", + " FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat lumaNESE = lumaNE + lumaSE;", + " FxaaFloat lumaNWNE = lumaNW + lumaNE;", + " FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;", + " FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat lumaNWSW = lumaNW + lumaSW;", + " FxaaFloat lumaSWSE = lumaSW + lumaSE;", + " FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);", + " FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);", + " FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;", + " FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;", + " FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;", + " FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;", + " FxaaFloat lengthSign = fxaaQualityRcpFrame.x;", + " FxaaBool horzSpan = edgeHorz >= edgeVert;", + " FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;", + "/*--------------------------------------------------------------------------*/", + " if(!horzSpan) lumaN = lumaW;", + " if(!horzSpan) lumaS = lumaE;", + " if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;", + " FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat gradientN = lumaN - lumaM;", + " FxaaFloat gradientS = lumaS - lumaM;", + " FxaaFloat lumaNN = lumaN + lumaM;", + " FxaaFloat lumaSS = lumaS + lumaM;", + " FxaaBool pairN = abs(gradientN) >= abs(gradientS);", + " FxaaFloat gradient = max(abs(gradientN), abs(gradientS));", + " if(pairN) lengthSign = -lengthSign;", + " FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat2 posB;", + " posB.x = posM.x;", + " posB.y = posM.y;", + " FxaaFloat2 offNP;", + " offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;", + " offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;", + " if(!horzSpan) posB.x += lengthSign * 0.5;", + " if( horzSpan) posB.y += lengthSign * 0.5;", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat2 posN;", + " posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;", + " posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;", + " FxaaFloat2 posP;", + " posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;", + " posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;", + " FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;", + " FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));", + " FxaaFloat subpixE = subpixC * subpixC;", + " FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));", + "/*--------------------------------------------------------------------------*/", + " if(!pairN) lumaNN = lumaSS;", + " FxaaFloat gradientScaled = gradient * 1.0/4.0;", + " FxaaFloat lumaMM = lumaM - lumaNN * 0.5;", + " FxaaFloat subpixF = subpixD * subpixE;", + " FxaaBool lumaMLTZero = lumaMM < 0.0;", + "/*--------------------------------------------------------------------------*/", + " lumaEndN -= lumaNN * 0.5;", + " lumaEndP -= lumaNN * 0.5;", + " FxaaBool doneN = abs(lumaEndN) >= gradientScaled;", + " FxaaBool doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;", + " FxaaBool doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;", + "/*--------------------------------------------------------------------------*/", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 3)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 4)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 5)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 6)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 7)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 8)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 9)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 10)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 11)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;", + "/*--------------------------------------------------------------------------*/", + " #if (FXAA_QUALITY_PS > 12)", + " if(doneNP) {", + " if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));", + " if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));", + " if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;", + " if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;", + " doneN = abs(lumaEndN) >= gradientScaled;", + " doneP = abs(lumaEndP) >= gradientScaled;", + " if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;", + " if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;", + " doneNP = (!doneN) || (!doneP);", + " if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;", + " if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + " #endif", + "/*--------------------------------------------------------------------------*/", + " }", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat dstN = posM.x - posN.x;", + " FxaaFloat dstP = posP.x - posM.x;", + " if(!horzSpan) dstN = posM.y - posN.y;", + " if(!horzSpan) dstP = posP.y - posM.y;", + "/*--------------------------------------------------------------------------*/", + " FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;", + " FxaaFloat spanLength = (dstP + dstN);", + " FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;", + " FxaaFloat spanLengthRcp = 1.0/spanLength;", + "/*--------------------------------------------------------------------------*/", + " FxaaBool directionN = dstN < dstP;", + " FxaaFloat dst = min(dstN, dstP);", + " FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;", + " FxaaFloat subpixG = subpixF * subpixF;", + " FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;", + " FxaaFloat subpixH = subpixG * fxaaQualitySubpix;", + "/*--------------------------------------------------------------------------*/", + " FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;", + " FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);", + " if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;", + " if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;", + " #if (FXAA_DISCARD == 1)", + " return FxaaTexTop(tex, posM);", + " #else", + " return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);", + " #endif", + "}", + "/*==========================================================================*/", + "#endif", + "", + "void main() {", + " gl_FragColor = FxaaPixelShader(", + " vUv,", + " vec4(0.0),", + " tDiffuse,", + " tDiffuse,", + " tDiffuse,", + " resolution,", + " vec4(0.0),", + " vec4(0.0),", + " vec4(0.0),", + " 0.75,", + " 0.166,", + " 0.0833,", + " 0.0,", + " 0.0,", + " 0.0,", + " vec4(0.0)", + " );", + "", + " // TODO avoid querying texture twice for same texel", + " gl_FragColor.a = texture2D(tDiffuse, vUv).a;", + "}" + ].join( "\n" ) }; diff --git a/examples/js/shaders/FilmShader.js b/examples/js/shaders/FilmShader.js index 5f65eaac05900d..5bfc7bc0b4d5c6 100644 --- a/examples/js/shaders/FilmShader.js +++ b/examples/js/shaders/FilmShader.js @@ -39,8 +39,8 @@ THREE.FilmShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -70,32 +70,32 @@ THREE.FilmShader = { "void main() {", - // sample the source - "vec4 cTextureScreen = texture2D( tDiffuse, vUv );", + // sample the source + " vec4 cTextureScreen = texture2D( tDiffuse, vUv );", - // make some noise - "float dx = rand( vUv + time );", + // make some noise + " float dx = rand( vUv + time );", - // add noise - "vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx, 0.0, 1.0 );", + // add noise + " vec3 cResult = cTextureScreen.rgb + cTextureScreen.rgb * clamp( 0.1 + dx, 0.0, 1.0 );", - // get us a sine and cosine - "vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );", + // get us a sine and cosine + " vec2 sc = vec2( sin( vUv.y * sCount ), cos( vUv.y * sCount ) );", - // add scanlines - "cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;", + // add scanlines + " cResult += cTextureScreen.rgb * vec3( sc.x, sc.y, sc.x ) * sIntensity;", - // interpolate between source and result by intensity - "cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );", + // interpolate between source and result by intensity + " cResult = cTextureScreen.rgb + clamp( nIntensity, 0.0,1.0 ) * ( cResult - cTextureScreen.rgb );", - // convert to grayscale if desired - "if( grayscale ) {", + // convert to grayscale if desired + " if( grayscale ) {", - "cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );", + " cResult = vec3( cResult.r * 0.3 + cResult.g * 0.59 + cResult.b * 0.11 );", - "}", + " }", - "gl_FragColor = vec4( cResult, cTextureScreen.a );", + " gl_FragColor = vec4( cResult, cTextureScreen.a );", "}" diff --git a/examples/js/shaders/FocusShader.js b/examples/js/shaders/FocusShader.js index cfc4f7c7af9a2e..ebb5261c047fdd 100644 --- a/examples/js/shaders/FocusShader.js +++ b/examples/js/shaders/FocusShader.js @@ -24,8 +24,8 @@ THREE.FocusShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -44,45 +44,45 @@ THREE.FocusShader = { "void main() {", - "vec4 color, org, tmp, add;", - "float sample_dist, f;", - "vec2 vin;", - "vec2 uv = vUv;", + " vec4 color, org, tmp, add;", + " float sample_dist, f;", + " vec2 vin;", + " vec2 uv = vUv;", - "add = color = org = texture2D( tDiffuse, uv );", + " add = color = org = texture2D( tDiffuse, uv );", - "vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );", - "sample_dist = dot( vin, vin ) * 2.0;", + " vin = ( uv - vec2( 0.5 ) ) * vec2( 1.4 );", + " sample_dist = dot( vin, vin ) * 2.0;", - "f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;", + " f = ( waveFactor * 100.0 + sample_dist ) * sampleDistance * 4.0;", - "vec2 sampleSize = vec2( 1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );", + " vec2 sampleSize = vec2( 1.0 / screenWidth, 1.0 / screenHeight ) * vec2( f );", - "add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );", - "if( tmp.b < color.b ) color = tmp;", + " add += tmp = texture2D( tDiffuse, uv + vec2( 0.111964, 0.993712 ) * sampleSize );", + " if( tmp.b < color.b ) color = tmp;", - "add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );", - "if( tmp.b < color.b ) color = tmp;", + " add += tmp = texture2D( tDiffuse, uv + vec2( 0.846724, 0.532032 ) * sampleSize );", + " if( tmp.b < color.b ) color = tmp;", - "add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );", - "if( tmp.b < color.b ) color = tmp;", + " add += tmp = texture2D( tDiffuse, uv + vec2( 0.943883, -0.330279 ) * sampleSize );", + " if( tmp.b < color.b ) color = tmp;", - "add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );", - "if( tmp.b < color.b ) color = tmp;", + " add += tmp = texture2D( tDiffuse, uv + vec2( 0.330279, -0.943883 ) * sampleSize );", + " if( tmp.b < color.b ) color = tmp;", - "add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );", - "if( tmp.b < color.b ) color = tmp;", + " add += tmp = texture2D( tDiffuse, uv + vec2( -0.532032, -0.846724 ) * sampleSize );", + " if( tmp.b < color.b ) color = tmp;", - "add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );", - "if( tmp.b < color.b ) color = tmp;", + " add += tmp = texture2D( tDiffuse, uv + vec2( -0.993712, -0.111964 ) * sampleSize );", + " if( tmp.b < color.b ) color = tmp;", - "add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );", - "if( tmp.b < color.b ) color = tmp;", + " add += tmp = texture2D( tDiffuse, uv + vec2( -0.707107, 0.707107 ) * sampleSize );", + " if( tmp.b < color.b ) color = tmp;", - "color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );", - "color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );", + " color = color * vec4( 2.0 ) - ( add / vec4( 8.0 ) );", + " color = color + ( add / vec4( 8.0 ) - color ) * ( vec4( 1.0 ) - vec4( sample_dist * 0.5 ) );", - "gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );", + " gl_FragColor = vec4( color.rgb * color.rgb * vec3( 0.95 ) + color.rgb, 1.0 );", "}" diff --git a/examples/js/shaders/FreiChenShader.js b/examples/js/shaders/FreiChenShader.js index 932615e69629e4..094e962658372e 100644 --- a/examples/js/shaders/FreiChenShader.js +++ b/examples/js/shaders/FreiChenShader.js @@ -21,8 +21,8 @@ THREE.FreiChenShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -55,38 +55,38 @@ THREE.FreiChenShader = { "void main(void)", "{", - "G[0] = g0,", - "G[1] = g1,", - "G[2] = g2,", - "G[3] = g3,", - "G[4] = g4,", - "G[5] = g5,", - "G[6] = g6,", - "G[7] = g7,", - "G[8] = g8;", - - "mat3 I;", - "float cnv[9];", - "vec3 sample;", - - /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ - "for (float i=0.0; i<3.0; i++) {", - "for (float j=0.0; j<3.0; j++) {", - "sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;", - "I[int(i)][int(j)] = length(sample);", - "}", - "}", - - /* calculate the convolution values for all the masks */ - "for (int i=0; i<9; i++) {", - "float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);", - "cnv[i] = dp3 * dp3;", - "}", - - "float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);", - "float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);", - - "gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);", + " G[0] = g0,", + " G[1] = g1,", + " G[2] = g2,", + " G[3] = g3,", + " G[4] = g4,", + " G[5] = g5,", + " G[6] = g6,", + " G[7] = g7,", + " G[8] = g8;", + + " mat3 I;", + " float cnv[9];", + " vec3 sample;", + + /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ + " for (float i=0.0; i<3.0; i++) {", + " for (float j=0.0; j<3.0; j++) {", + " sample = texture2D(tDiffuse, vUv + texel * vec2(i-1.0,j-1.0) ).rgb;", + " I[int(i)][int(j)] = length(sample);", + " }", + " }", + + /* calculate the convolution values for all the masks */ + " for (int i=0; i<9; i++) {", + " float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);", + " cnv[i] = dp3 * dp3;", + " }", + + " float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);", + " float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);", + + " gl_FragColor = vec4(vec3(sqrt(M/S)), 1.0);", "}" ].join( "\n" ) diff --git a/examples/js/shaders/FresnelShader.js b/examples/js/shaders/FresnelShader.js index e7639a723936d0..ec5636aa39fd2b 100644 --- a/examples/js/shaders/FresnelShader.js +++ b/examples/js/shaders/FresnelShader.js @@ -29,20 +29,20 @@ THREE.FresnelShader = { "void main() {", - "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", + " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + " vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", - "vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );", + " vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );", - "vec3 I = worldPosition.xyz - cameraPosition;", + " vec3 I = worldPosition.xyz - cameraPosition;", - "vReflect = reflect( I, worldNormal );", - "vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );", - "vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );", - "vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );", - "vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );", + " vReflect = reflect( I, worldNormal );", + " vRefract[0] = refract( normalize( I ), worldNormal, mRefractionRatio );", + " vRefract[1] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.99 );", + " vRefract[2] = refract( normalize( I ), worldNormal, mRefractionRatio * 0.98 );", + " vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), mFresnelPower );", - "gl_Position = projectionMatrix * mvPosition;", + " gl_Position = projectionMatrix * mvPosition;", "}" @@ -58,14 +58,14 @@ THREE.FresnelShader = { "void main() {", - "vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );", - "vec4 refractedColor = vec4( 1.0 );", + " vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );", + " vec4 refractedColor = vec4( 1.0 );", - "refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;", - "refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;", - "refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;", + " refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;", + " refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;", + " refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;", - "gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );", + " gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );", "}" diff --git a/examples/js/shaders/GammaCorrectionShader.js b/examples/js/shaders/GammaCorrectionShader.js index 4c2a373fba16b5..6e878c6f4099bf 100644 --- a/examples/js/shaders/GammaCorrectionShader.js +++ b/examples/js/shaders/GammaCorrectionShader.js @@ -19,8 +19,8 @@ THREE.GammaCorrectionShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -34,9 +34,9 @@ THREE.GammaCorrectionShader = { "void main() {", - "vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );", + " vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );", - "gl_FragColor = LinearToGamma( tex, float( GAMMA_FACTOR ) );", + " gl_FragColor = LinearTosRGB( tex );", // optional: LinearToGamma( tex, float( GAMMA_FACTOR ) ); "}" diff --git a/examples/js/shaders/GodRaysShader.js b/examples/js/shaders/GodRaysShader.js index ed55d6283ec6b0..95bb17805ef6e5 100644 --- a/examples/js/shaders/GodRaysShader.js +++ b/examples/js/shaders/GodRaysShader.js @@ -141,16 +141,16 @@ THREE.GodRaysGenerateShader = { "for ( float i = 0.0; i < TAPS_PER_PASS; i += 1.0 ) {", - // Accumulate samples, making sure we dont walk past the light source. + // Accumulate samples, making sure we dont walk past the light source. - // The check for uv.y < 1 would not be necessary with "border" UV wrap - // mode, with a black border color. I don't think this is currently - // exposed by three.js. As a result there might be artifacts when the - // sun is to the left, right or bottom of screen as these cases are - // not specifically handled. + // The check for uv.y < 1 would not be necessary with "border" UV wrap + // mode, with a black border color. I don't think this is currently + // exposed by three.js. As a result there might be artifacts when the + // sun is to the left, right or bottom of screen as these cases are + // not specifically handled. - "col += ( i <= iters && uv.y < 1.0 ? texture2D( tInput, uv ).r : 0.0 );", - "uv += stepv;", + " col += ( i <= iters && uv.y < 1.0 ? texture2D( tInput, uv ).r : 0.0 );", + " uv += stepv;", "}", */ diff --git a/examples/js/shaders/HalftoneShader.js b/examples/js/shaders/HalftoneShader.js index 56df6b935efbf1..8b8a7b7d86817a 100644 --- a/examples/js/shaders/HalftoneShader.js +++ b/examples/js/shaders/HalftoneShader.js @@ -27,14 +27,14 @@ THREE.HalftoneShader = { vertexShader: [ - "varying vec2 vUV;", + "varying vec2 vUV;", - "void main() {", + "void main() {", - "vUV = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", + " vUV = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);", - "}" + "}" ].join( "\n" ), @@ -70,242 +70,242 @@ THREE.HalftoneShader = { "float blend( float a, float b, float t ) {", - // linear blend - "return a * ( 1.0 - t ) + b * t;", + // linear blend + " return a * ( 1.0 - t ) + b * t;", "}", "float hypot( float x, float y ) {", - // vector magnitude - "return sqrt( x * x + y * y );", + // vector magnitude + " return sqrt( x * x + y * y );", "}", "float rand( vec2 seed ){", - // get pseudo-random number + // get pseudo-random number "return fract( sin( dot( seed.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );", "}", "float distanceToDotRadius( float channel, vec2 coord, vec2 normal, vec2 p, float angle, float rad_max ) {", - // apply shape-specific transforms - "float dist = hypot( coord.x - p.x, coord.y - p.y );", - "float rad = channel;", + // apply shape-specific transforms + " float dist = hypot( coord.x - p.x, coord.y - p.y );", + " float rad = channel;", - "if ( shape == SHAPE_DOT ) {", + " if ( shape == SHAPE_DOT ) {", - "rad = pow( abs( rad ), 1.125 ) * rad_max;", + " rad = pow( abs( rad ), 1.125 ) * rad_max;", - "} else if ( shape == SHAPE_ELLIPSE ) {", + " } else if ( shape == SHAPE_ELLIPSE ) {", - "rad = pow( abs( rad ), 1.125 ) * rad_max;", + " rad = pow( abs( rad ), 1.125 ) * rad_max;", - "if ( dist != 0.0 ) {", - "float dot_p = abs( ( p.x - coord.x ) / dist * normal.x + ( p.y - coord.y ) / dist * normal.y );", - "dist = ( dist * ( 1.0 - SQRT2_HALF_MINUS_ONE ) ) + dot_p * dist * SQRT2_MINUS_ONE;", - "}", + " if ( dist != 0.0 ) {", + " float dot_p = abs( ( p.x - coord.x ) / dist * normal.x + ( p.y - coord.y ) / dist * normal.y );", + " dist = ( dist * ( 1.0 - SQRT2_HALF_MINUS_ONE ) ) + dot_p * dist * SQRT2_MINUS_ONE;", + " }", - "} else if ( shape == SHAPE_LINE ) {", + " } else if ( shape == SHAPE_LINE ) {", - "rad = pow( abs( rad ), 1.5) * rad_max;", - "float dot_p = ( p.x - coord.x ) * normal.x + ( p.y - coord.y ) * normal.y;", - "dist = hypot( normal.x * dot_p, normal.y * dot_p );", + " rad = pow( abs( rad ), 1.5) * rad_max;", + " float dot_p = ( p.x - coord.x ) * normal.x + ( p.y - coord.y ) * normal.y;", + " dist = hypot( normal.x * dot_p, normal.y * dot_p );", - "} else if ( shape == SHAPE_SQUARE ) {", + " } else if ( shape == SHAPE_SQUARE ) {", - "float theta = atan( p.y - coord.y, p.x - coord.x ) - angle;", - "float sin_t = abs( sin( theta ) );", - "float cos_t = abs( cos( theta ) );", - "rad = pow( abs( rad ), 1.4 );", - "rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) );", + " float theta = atan( p.y - coord.y, p.x - coord.x ) - angle;", + " float sin_t = abs( sin( theta ) );", + " float cos_t = abs( cos( theta ) );", + " rad = pow( abs( rad ), 1.4 );", + " rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) );", - "}", + " }", - "return rad - dist;", + " return rad - dist;", "}", "struct Cell {", - // grid sample positions - "vec2 normal;", - "vec2 p1;", - "vec2 p2;", - "vec2 p3;", - "vec2 p4;", - "float samp2;", - "float samp1;", - "float samp3;", - "float samp4;", + // grid sample positions + " vec2 normal;", + " vec2 p1;", + " vec2 p2;", + " vec2 p3;", + " vec2 p4;", + " float samp2;", + " float samp1;", + " float samp3;", + " float samp4;", "};", "vec4 getSample( vec2 point ) {", - // multi-sampled point - "vec4 tex = texture2D( tDiffuse, vec2( point.x / width, point.y / height ) );", - "float base = rand( vec2( floor( point.x ), floor( point.y ) ) ) * PI2;", - "float step = PI2 / float( samples );", - "float dist = radius * 0.66;", + // multi-sampled point + " vec4 tex = texture2D( tDiffuse, vec2( point.x / width, point.y / height ) );", + " float base = rand( vec2( floor( point.x ), floor( point.y ) ) ) * PI2;", + " float step = PI2 / float( samples );", + " float dist = radius * 0.66;", - "for ( int i = 0; i < samples; ++i ) {", + " for ( int i = 0; i < samples; ++i ) {", - "float r = base + step * float( i );", - "vec2 coord = point + vec2( cos( r ) * dist, sin( r ) * dist );", - "tex += texture2D( tDiffuse, vec2( coord.x / width, coord.y / height ) );", + " float r = base + step * float( i );", + " vec2 coord = point + vec2( cos( r ) * dist, sin( r ) * dist );", + " tex += texture2D( tDiffuse, vec2( coord.x / width, coord.y / height ) );", - "}", + " }", - "tex /= float( samples ) + 1.0;", - "return tex;", + " tex /= float( samples ) + 1.0;", + " return tex;", "}", "float getDotColour( Cell c, vec2 p, int channel, float angle, float aa ) {", - // get colour for given point - "float dist_c_1, dist_c_2, dist_c_3, dist_c_4, res;", + // get colour for given point + " float dist_c_1, dist_c_2, dist_c_3, dist_c_4, res;", - "if ( channel == 0 ) {", + " if ( channel == 0 ) {", - "c.samp1 = getSample( c.p1 ).r;", - "c.samp2 = getSample( c.p2 ).r;", - "c.samp3 = getSample( c.p3 ).r;", - "c.samp4 = getSample( c.p4 ).r;", + " c.samp1 = getSample( c.p1 ).r;", + " c.samp2 = getSample( c.p2 ).r;", + " c.samp3 = getSample( c.p3 ).r;", + " c.samp4 = getSample( c.p4 ).r;", - "} else if (channel == 1) {", + " } else if (channel == 1) {", - "c.samp1 = getSample( c.p1 ).g;", - "c.samp2 = getSample( c.p2 ).g;", - "c.samp3 = getSample( c.p3 ).g;", - "c.samp4 = getSample( c.p4 ).g;", + " c.samp1 = getSample( c.p1 ).g;", + " c.samp2 = getSample( c.p2 ).g;", + " c.samp3 = getSample( c.p3 ).g;", + " c.samp4 = getSample( c.p4 ).g;", - "} else {", + " } else {", - "c.samp1 = getSample( c.p1 ).b;", - "c.samp3 = getSample( c.p3 ).b;", - "c.samp2 = getSample( c.p2 ).b;", - "c.samp4 = getSample( c.p4 ).b;", + " c.samp1 = getSample( c.p1 ).b;", + " c.samp3 = getSample( c.p3 ).b;", + " c.samp2 = getSample( c.p2 ).b;", + " c.samp4 = getSample( c.p4 ).b;", - "}", + " }", - "dist_c_1 = distanceToDotRadius( c.samp1, c.p1, c.normal, p, angle, radius );", - "dist_c_2 = distanceToDotRadius( c.samp2, c.p2, c.normal, p, angle, radius );", - "dist_c_3 = distanceToDotRadius( c.samp3, c.p3, c.normal, p, angle, radius );", - "dist_c_4 = distanceToDotRadius( c.samp4, c.p4, c.normal, p, angle, radius );", - "res = ( dist_c_1 > 0.0 ) ? clamp( dist_c_1 / aa, 0.0, 1.0 ) : 0.0;", - "res += ( dist_c_2 > 0.0 ) ? clamp( dist_c_2 / aa, 0.0, 1.0 ) : 0.0;", - "res += ( dist_c_3 > 0.0 ) ? clamp( dist_c_3 / aa, 0.0, 1.0 ) : 0.0;", - "res += ( dist_c_4 > 0.0 ) ? clamp( dist_c_4 / aa, 0.0, 1.0 ) : 0.0;", - "res = clamp( res, 0.0, 1.0 );", + " dist_c_1 = distanceToDotRadius( c.samp1, c.p1, c.normal, p, angle, radius );", + " dist_c_2 = distanceToDotRadius( c.samp2, c.p2, c.normal, p, angle, radius );", + " dist_c_3 = distanceToDotRadius( c.samp3, c.p3, c.normal, p, angle, radius );", + " dist_c_4 = distanceToDotRadius( c.samp4, c.p4, c.normal, p, angle, radius );", + " res = ( dist_c_1 > 0.0 ) ? clamp( dist_c_1 / aa, 0.0, 1.0 ) : 0.0;", + " res += ( dist_c_2 > 0.0 ) ? clamp( dist_c_2 / aa, 0.0, 1.0 ) : 0.0;", + " res += ( dist_c_3 > 0.0 ) ? clamp( dist_c_3 / aa, 0.0, 1.0 ) : 0.0;", + " res += ( dist_c_4 > 0.0 ) ? clamp( dist_c_4 / aa, 0.0, 1.0 ) : 0.0;", + " res = clamp( res, 0.0, 1.0 );", - "return res;", + " return res;", "}", "Cell getReferenceCell( vec2 p, vec2 origin, float grid_angle, float step ) {", - // get containing cell - "Cell c;", - - // calc grid - "vec2 n = vec2( cos( grid_angle ), sin( grid_angle ) );", - "float threshold = step * 0.5;", - "float dot_normal = n.x * ( p.x - origin.x ) + n.y * ( p.y - origin.y );", - "float dot_line = -n.y * ( p.x - origin.x ) + n.x * ( p.y - origin.y );", - "vec2 offset = vec2( n.x * dot_normal, n.y * dot_normal );", - "float offset_normal = mod( hypot( offset.x, offset.y ), step );", - "float normal_dir = ( dot_normal < 0.0 ) ? 1.0 : -1.0;", - "float normal_scale = ( ( offset_normal < threshold ) ? -offset_normal : step - offset_normal ) * normal_dir;", - "float offset_line = mod( hypot( ( p.x - offset.x ) - origin.x, ( p.y - offset.y ) - origin.y ), step );", - "float line_dir = ( dot_line < 0.0 ) ? 1.0 : -1.0;", - "float line_scale = ( ( offset_line < threshold ) ? -offset_line : step - offset_line ) * line_dir;", - - // get closest corner - "c.normal = n;", - "c.p1.x = p.x - n.x * normal_scale + n.y * line_scale;", - "c.p1.y = p.y - n.y * normal_scale - n.x * line_scale;", - - // scatter - "if ( scatter != 0.0 ) {", - - "float off_mag = scatter * threshold * 0.5;", - "float off_angle = rand( vec2( floor( c.p1.x ), floor( c.p1.y ) ) ) * PI2;", - "c.p1.x += cos( off_angle ) * off_mag;", - "c.p1.y += sin( off_angle ) * off_mag;", - - "}", - - // find corners - "float normal_step = normal_dir * ( ( offset_normal < threshold ) ? step : -step );", - "float line_step = line_dir * ( ( offset_line < threshold ) ? step : -step );", - "c.p2.x = c.p1.x - n.x * normal_step;", - "c.p2.y = c.p1.y - n.y * normal_step;", - "c.p3.x = c.p1.x + n.y * line_step;", - "c.p3.y = c.p1.y - n.x * line_step;", - "c.p4.x = c.p1.x - n.x * normal_step + n.y * line_step;", - "c.p4.y = c.p1.y - n.y * normal_step - n.x * line_step;", - - "return c;", + // get containing cell + " Cell c;", + + // calc grid + " vec2 n = vec2( cos( grid_angle ), sin( grid_angle ) );", + " float threshold = step * 0.5;", + " float dot_normal = n.x * ( p.x - origin.x ) + n.y * ( p.y - origin.y );", + " float dot_line = -n.y * ( p.x - origin.x ) + n.x * ( p.y - origin.y );", + " vec2 offset = vec2( n.x * dot_normal, n.y * dot_normal );", + " float offset_normal = mod( hypot( offset.x, offset.y ), step );", + " float normal_dir = ( dot_normal < 0.0 ) ? 1.0 : -1.0;", + " float normal_scale = ( ( offset_normal < threshold ) ? -offset_normal : step - offset_normal ) * normal_dir;", + " float offset_line = mod( hypot( ( p.x - offset.x ) - origin.x, ( p.y - offset.y ) - origin.y ), step );", + " float line_dir = ( dot_line < 0.0 ) ? 1.0 : -1.0;", + " float line_scale = ( ( offset_line < threshold ) ? -offset_line : step - offset_line ) * line_dir;", + + // get closest corner + " c.normal = n;", + " c.p1.x = p.x - n.x * normal_scale + n.y * line_scale;", + " c.p1.y = p.y - n.y * normal_scale - n.x * line_scale;", + + // scatter + " if ( scatter != 0.0 ) {", + + " float off_mag = scatter * threshold * 0.5;", + " float off_angle = rand( vec2( floor( c.p1.x ), floor( c.p1.y ) ) ) * PI2;", + " c.p1.x += cos( off_angle ) * off_mag;", + " c.p1.y += sin( off_angle ) * off_mag;", + + " }", + + // find corners + " float normal_step = normal_dir * ( ( offset_normal < threshold ) ? step : -step );", + " float line_step = line_dir * ( ( offset_line < threshold ) ? step : -step );", + " c.p2.x = c.p1.x - n.x * normal_step;", + " c.p2.y = c.p1.y - n.y * normal_step;", + " c.p3.x = c.p1.x + n.y * line_step;", + " c.p3.y = c.p1.y - n.x * line_step;", + " c.p4.x = c.p1.x - n.x * normal_step + n.y * line_step;", + " c.p4.y = c.p1.y - n.y * normal_step - n.x * line_step;", + + " return c;", "}", "float blendColour( float a, float b, float t ) {", - // blend colours - "if ( blendingMode == BLENDING_LINEAR ) {", - "return blend( a, b, 1.0 - t );", - "} else if ( blendingMode == BLENDING_ADD ) {", - "return blend( a, min( 1.0, a + b ), t );", - "} else if ( blendingMode == BLENDING_MULTIPLY ) {", - "return blend( a, max( 0.0, a * b ), t );", - "} else if ( blendingMode == BLENDING_LIGHTER ) {", - "return blend( a, max( a, b ), t );", - "} else if ( blendingMode == BLENDING_DARKER ) {", - "return blend( a, min( a, b ), t );", - "} else {", - "return blend( a, b, 1.0 - t );", - "}", + // blend colours + " if ( blendingMode == BLENDING_LINEAR ) {", + " return blend( a, b, 1.0 - t );", + " } else if ( blendingMode == BLENDING_ADD ) {", + " return blend( a, min( 1.0, a + b ), t );", + " } else if ( blendingMode == BLENDING_MULTIPLY ) {", + " return blend( a, max( 0.0, a * b ), t );", + " } else if ( blendingMode == BLENDING_LIGHTER ) {", + " return blend( a, max( a, b ), t );", + " } else if ( blendingMode == BLENDING_DARKER ) {", + " return blend( a, min( a, b ), t );", + " } else {", + " return blend( a, b, 1.0 - t );", + " }", "}", "void main() {", - "if ( ! disable ) {", + " if ( ! disable ) {", - // setup - "vec2 p = vec2( vUV.x * width, vUV.y * height );", - "vec2 origin = vec2( 0, 0 );", - "float aa = ( radius < 2.5 ) ? radius * 0.5 : 1.25;", + // setup + " vec2 p = vec2( vUV.x * width, vUV.y * height );", + " vec2 origin = vec2( 0, 0 );", + " float aa = ( radius < 2.5 ) ? radius * 0.5 : 1.25;", - // get channel samples - "Cell cell_r = getReferenceCell( p, origin, rotateR, radius );", - "Cell cell_g = getReferenceCell( p, origin, rotateG, radius );", - "Cell cell_b = getReferenceCell( p, origin, rotateB, radius );", - "float r = getDotColour( cell_r, p, 0, rotateR, aa );", - "float g = getDotColour( cell_g, p, 1, rotateG, aa );", - "float b = getDotColour( cell_b, p, 2, rotateB, aa );", + // get channel samples + " Cell cell_r = getReferenceCell( p, origin, rotateR, radius );", + " Cell cell_g = getReferenceCell( p, origin, rotateG, radius );", + " Cell cell_b = getReferenceCell( p, origin, rotateB, radius );", + " float r = getDotColour( cell_r, p, 0, rotateR, aa );", + " float g = getDotColour( cell_g, p, 1, rotateG, aa );", + " float b = getDotColour( cell_b, p, 2, rotateB, aa );", - // blend with original - "vec4 colour = texture2D( tDiffuse, vUV );", - "r = blendColour( r, colour.r, blending );", - "g = blendColour( g, colour.g, blending );", - "b = blendColour( b, colour.b, blending );", + // blend with original + " vec4 colour = texture2D( tDiffuse, vUV );", + " r = blendColour( r, colour.r, blending );", + " g = blendColour( g, colour.g, blending );", + " b = blendColour( b, colour.b, blending );", - "if ( greyscale ) {", - "r = g = b = (r + b + g) / 3.0;", - "}", + " if ( greyscale ) {", + " r = g = b = (r + b + g) / 3.0;", + " }", - "gl_FragColor = vec4( r, g, b, 1.0 );", + " gl_FragColor = vec4( r, g, b, 1.0 );", - "} else {", + " } else {", - "gl_FragColor = texture2D( tDiffuse, vUV );", + " gl_FragColor = texture2D( tDiffuse, vUV );", - "}", + " }", "}" diff --git a/examples/js/shaders/HorizontalBlurShader.js b/examples/js/shaders/HorizontalBlurShader.js index 59c3a9fa02d14f..43cb4706efa9e0 100644 --- a/examples/js/shaders/HorizontalBlurShader.js +++ b/examples/js/shaders/HorizontalBlurShader.js @@ -25,8 +25,8 @@ THREE.HorizontalBlurShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -41,19 +41,19 @@ THREE.HorizontalBlurShader = { "void main() {", - "vec4 sum = vec4( 0.0 );", + " vec4 sum = vec4( 0.0 );", - "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;", - "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;", - "gl_FragColor = sum;", + " gl_FragColor = sum;", "}" diff --git a/examples/js/shaders/HorizontalTiltShiftShader.js b/examples/js/shaders/HorizontalTiltShiftShader.js index 5d0d64acc95531..471b0a743fa7a5 100644 --- a/examples/js/shaders/HorizontalTiltShiftShader.js +++ b/examples/js/shaders/HorizontalTiltShiftShader.js @@ -25,8 +25,8 @@ THREE.HorizontalTiltShiftShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -42,21 +42,21 @@ THREE.HorizontalTiltShiftShader = { "void main() {", - "vec4 sum = vec4( 0.0 );", + " vec4 sum = vec4( 0.0 );", - "float hh = h * abs( r - vUv.y );", + " float hh = h * abs( r - vUv.y );", - "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;", - "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;", - "gl_FragColor = sum;", + " gl_FragColor = sum;", "}" diff --git a/examples/js/shaders/HueSaturationShader.js b/examples/js/shaders/HueSaturationShader.js index 8141a1de04a07d..323eb7530617b8 100644 --- a/examples/js/shaders/HueSaturationShader.js +++ b/examples/js/shaders/HueSaturationShader.js @@ -23,9 +23,9 @@ THREE.HueSaturationShader = { "void main() {", - "vUv = uv;", + " vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -41,26 +41,26 @@ THREE.HueSaturationShader = { "void main() {", - "gl_FragColor = texture2D( tDiffuse, vUv );", - - // hue - "float angle = hue * 3.14159265;", - "float s = sin(angle), c = cos(angle);", - "vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;", - "float len = length(gl_FragColor.rgb);", - "gl_FragColor.rgb = vec3(", - "dot(gl_FragColor.rgb, weights.xyz),", - "dot(gl_FragColor.rgb, weights.zxy),", - "dot(gl_FragColor.rgb, weights.yzx)", - ");", - - // saturation - "float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;", - "if (saturation > 0.0) {", - "gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));", - "} else {", - "gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);", - "}", + " gl_FragColor = texture2D( tDiffuse, vUv );", + + // hue + " float angle = hue * 3.14159265;", + " float s = sin(angle), c = cos(angle);", + " vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;", + " float len = length(gl_FragColor.rgb);", + " gl_FragColor.rgb = vec3(", + " dot(gl_FragColor.rgb, weights.xyz),", + " dot(gl_FragColor.rgb, weights.zxy),", + " dot(gl_FragColor.rgb, weights.yzx)", + " );", + + // saturation + " float average = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;", + " if (saturation > 0.0) {", + " gl_FragColor.rgb += (average - gl_FragColor.rgb) * (1.0 - 1.0 / (1.001 - saturation));", + " } else {", + " gl_FragColor.rgb += (average - gl_FragColor.rgb) * (-saturation);", + " }", "}" diff --git a/examples/js/shaders/KaleidoShader.js b/examples/js/shaders/KaleidoShader.js index 459570e2c73c79..36e908f3a24a93 100644 --- a/examples/js/shaders/KaleidoShader.js +++ b/examples/js/shaders/KaleidoShader.js @@ -26,8 +26,8 @@ THREE.KaleidoShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -43,15 +43,15 @@ THREE.KaleidoShader = { "void main() {", - "vec2 p = vUv - 0.5;", - "float r = length(p);", - "float a = atan(p.y, p.x) + angle;", - "float tau = 2. * 3.1416 ;", - "a = mod(a, tau/sides);", - "a = abs(a - tau/sides/2.) ;", - "p = r * vec2(cos(a), sin(a));", - "vec4 color = texture2D(tDiffuse, p + 0.5);", - "gl_FragColor = color;", + " vec2 p = vUv - 0.5;", + " float r = length(p);", + " float a = atan(p.y, p.x) + angle;", + " float tau = 2. * 3.1416 ;", + " a = mod(a, tau/sides);", + " a = abs(a - tau/sides/2.) ;", + " p = r * vec2(cos(a), sin(a));", + " vec4 color = texture2D(tDiffuse, p + 0.5);", + " gl_FragColor = color;", "}" diff --git a/examples/js/shaders/LuminosityHighPassShader.js b/examples/js/shaders/LuminosityHighPassShader.js index 573deb906edc4c..9ffa1386a4ddc2 100644 --- a/examples/js/shaders/LuminosityHighPassShader.js +++ b/examples/js/shaders/LuminosityHighPassShader.js @@ -25,13 +25,13 @@ THREE.LuminosityHighPassShader = { "void main() {", - "vUv = uv;", + " vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" - ].join("\n"), + ].join( "\n" ), fragmentShader: [ @@ -45,20 +45,20 @@ THREE.LuminosityHighPassShader = { "void main() {", - "vec4 texel = texture2D( tDiffuse, vUv );", + " vec4 texel = texture2D( tDiffuse, vUv );", - "vec3 luma = vec3( 0.299, 0.587, 0.114 );", + " vec3 luma = vec3( 0.299, 0.587, 0.114 );", - "float v = dot( texel.xyz, luma );", + " float v = dot( texel.xyz, luma );", - "vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );", + " vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );", - "float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );", + " float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );", - "gl_FragColor = mix( outputColor, texel, alpha );", + " gl_FragColor = mix( outputColor, texel, alpha );", "}" - ].join("\n") + ].join( "\n" ) }; diff --git a/examples/js/shaders/LuminosityShader.js b/examples/js/shaders/LuminosityShader.js index 19dbbfca0fb1a7..da489b462377e0 100644 --- a/examples/js/shaders/LuminosityShader.js +++ b/examples/js/shaders/LuminosityShader.js @@ -19,9 +19,9 @@ THREE.LuminosityShader = { "void main() {", - "vUv = uv;", + " vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -37,11 +37,11 @@ THREE.LuminosityShader = { "void main() {", - "vec4 texel = texture2D( tDiffuse, vUv );", + " vec4 texel = texture2D( tDiffuse, vUv );", - "float l = linearToRelativeLuminance( texel.rgb );", + " float l = linearToRelativeLuminance( texel.rgb );", - "gl_FragColor = vec4( l, l, l, texel.w );", + " gl_FragColor = vec4( l, l, l, texel.w );", "}" diff --git a/examples/js/shaders/MirrorShader.js b/examples/js/shaders/MirrorShader.js index 129919ae71797f..5b0d686321b26b 100644 --- a/examples/js/shaders/MirrorShader.js +++ b/examples/js/shaders/MirrorShader.js @@ -22,8 +22,8 @@ THREE.MirrorShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -38,18 +38,18 @@ THREE.MirrorShader = { "void main() {", - "vec2 p = vUv;", - "if (side == 0){", - "if (p.x > 0.5) p.x = 1.0 - p.x;", - "}else if (side == 1){", - "if (p.x < 0.5) p.x = 1.0 - p.x;", - "}else if (side == 2){", - "if (p.y < 0.5) p.y = 1.0 - p.y;", - "}else if (side == 3){", - "if (p.y > 0.5) p.y = 1.0 - p.y;", - "} ", - "vec4 color = texture2D(tDiffuse, p);", - "gl_FragColor = color;", + " vec2 p = vUv;", + " if (side == 0){", + " if (p.x > 0.5) p.x = 1.0 - p.x;", + " }else if (side == 1){", + " if (p.x < 0.5) p.x = 1.0 - p.x;", + " }else if (side == 2){", + " if (p.y < 0.5) p.y = 1.0 - p.y;", + " }else if (side == 3){", + " if (p.y > 0.5) p.y = 1.0 - p.y;", + " } ", + " vec4 color = texture2D(tDiffuse, p);", + " gl_FragColor = color;", "}" diff --git a/examples/js/shaders/NormalMapShader.js b/examples/js/shaders/NormalMapShader.js index 6e3241fe546fc9..87234c82bac519 100644 --- a/examples/js/shaders/NormalMapShader.js +++ b/examples/js/shaders/NormalMapShader.js @@ -22,8 +22,8 @@ THREE.NormalMapShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -39,12 +39,12 @@ THREE.NormalMapShader = { "void main() {", - "float val = texture2D( heightMap, vUv ).x;", + " float val = texture2D( heightMap, vUv ).x;", - "float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;", - "float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;", + " float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;", + " float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;", - "gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );", + " gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );", "}" diff --git a/examples/js/shaders/OceanShaders.js b/examples/js/shaders/OceanShaders.js index 70d138160eed97..8ca7fef521e564 100644 --- a/examples/js/shaders/OceanShaders.js +++ b/examples/js/shaders/OceanShaders.js @@ -22,18 +22,18 @@ // [7] ocean_main -> Vertex and Fragment shader used to create the final render */ -THREE.OceanShaders = {} -THREE.OceanShaders[ 'ocean_sim_vertex' ] = { +THREE.OceanShaders = {}; +THREE.OceanShaders[ "ocean_sim_vertex" ] = { vertexShader: [ - 'varying vec2 vUV;', + "varying vec2 vUV;", - 'void main (void) {', - 'vUV = position.xy * 0.5 + 0.5;', - 'gl_Position = vec4(position, 1.0 );', - '}' - ].join( '\n' ) + "void main (void) {", + " vUV = position.xy * 0.5 + 0.5;", + " gl_Position = vec4(position, 1.0 );", + "}" + ].join( "\n" ) }; -THREE.OceanShaders[ 'ocean_subtransform' ] = { +THREE.OceanShaders[ "ocean_subtransform" ] = { uniforms: { "u_input": { value: null }, "u_transformSize": { value: 512.0 }, @@ -42,131 +42,131 @@ THREE.OceanShaders[ 'ocean_subtransform' ] = { fragmentShader: [ //GPU FFT using a Stockham formulation - 'precision highp float;', - '#include ', + "precision highp float;", + "#include ", - 'uniform sampler2D u_input;', - 'uniform float u_transformSize;', - 'uniform float u_subtransformSize;', + "uniform sampler2D u_input;", + "uniform float u_transformSize;", + "uniform float u_subtransformSize;", - 'varying vec2 vUV;', + "varying vec2 vUV;", - 'vec2 multiplyComplex (vec2 a, vec2 b) {', - 'return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);', - '}', + "vec2 multiplyComplex (vec2 a, vec2 b) {", + " return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);", + "}", - 'void main (void) {', - '#ifdef HORIZONTAL', - 'float index = vUV.x * u_transformSize - 0.5;', - '#else', - 'float index = vUV.y * u_transformSize - 0.5;', - '#endif', + "void main (void) {", + " #ifdef HORIZONTAL", + " float index = vUV.x * u_transformSize - 0.5;", + " #else", + " float index = vUV.y * u_transformSize - 0.5;", + " #endif", - 'float evenIndex = floor(index / u_subtransformSize) * (u_subtransformSize * 0.5) + mod(index, u_subtransformSize * 0.5);', + " float evenIndex = floor(index / u_subtransformSize) * (u_subtransformSize * 0.5) + mod(index, u_subtransformSize * 0.5);", - //transform two complex sequences simultaneously - '#ifdef HORIZONTAL', - 'vec4 even = texture2D(u_input, vec2(evenIndex + 0.5, gl_FragCoord.y) / u_transformSize).rgba;', - 'vec4 odd = texture2D(u_input, vec2(evenIndex + u_transformSize * 0.5 + 0.5, gl_FragCoord.y) / u_transformSize).rgba;', - '#else', - 'vec4 even = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + 0.5) / u_transformSize).rgba;', - 'vec4 odd = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + u_transformSize * 0.5 + 0.5) / u_transformSize).rgba;', - '#endif', + //transform two complex sequences simultaneously + " #ifdef HORIZONTAL", + " vec4 even = texture2D(u_input, vec2(evenIndex + 0.5, gl_FragCoord.y) / u_transformSize).rgba;", + " vec4 odd = texture2D(u_input, vec2(evenIndex + u_transformSize * 0.5 + 0.5, gl_FragCoord.y) / u_transformSize).rgba;", + " #else", + " vec4 even = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + 0.5) / u_transformSize).rgba;", + " vec4 odd = texture2D(u_input, vec2(gl_FragCoord.x, evenIndex + u_transformSize * 0.5 + 0.5) / u_transformSize).rgba;", + " #endif", - 'float twiddleArgument = -2.0 * PI * (index / u_subtransformSize);', - 'vec2 twiddle = vec2(cos(twiddleArgument), sin(twiddleArgument));', + " float twiddleArgument = -2.0 * PI * (index / u_subtransformSize);", + " vec2 twiddle = vec2(cos(twiddleArgument), sin(twiddleArgument));", - 'vec2 outputA = even.xy + multiplyComplex(twiddle, odd.xy);', - 'vec2 outputB = even.zw + multiplyComplex(twiddle, odd.zw);', + " vec2 outputA = even.xy + multiplyComplex(twiddle, odd.xy);", + " vec2 outputB = even.zw + multiplyComplex(twiddle, odd.zw);", - 'gl_FragColor = vec4(outputA, outputB);', - '}' - ].join( '\n' ) + " gl_FragColor = vec4(outputA, outputB);", + "}" + ].join( "\n" ) }; -THREE.OceanShaders[ 'ocean_initial_spectrum' ] = { +THREE.OceanShaders[ "ocean_initial_spectrum" ] = { uniforms: { "u_wind": { value: new THREE.Vector2( 10.0, 10.0 ) }, "u_resolution": { value: 512.0 }, "u_size": { value: 250.0 } }, vertexShader: [ - 'void main (void) {', - 'gl_Position = vec4(position, 1.0);', - '}' - ].join( '\n' ), + "void main (void) {", + " gl_Position = vec4(position, 1.0);", + "}" + ].join( "\n" ), fragmentShader: [ - 'precision highp float;', - '#include ', + "precision highp float;", + "#include ", - 'const float G = 9.81;', - 'const float KM = 370.0;', - 'const float CM = 0.23;', + "const float G = 9.81;", + "const float KM = 370.0;", + "const float CM = 0.23;", - 'uniform vec2 u_wind;', - 'uniform float u_resolution;', - 'uniform float u_size;', + "uniform vec2 u_wind;", + "uniform float u_resolution;", + "uniform float u_size;", - 'float omega (float k) {', - 'return sqrt(G * k * (1.0 + pow2(k / KM)));', - '}', + "float omega (float k) {", + " return sqrt(G * k * (1.0 + pow2(k / KM)));", + "}", - '#if __VERSION__ == 100', - 'float tanh (float x) {', - 'return (1.0 - exp(-2.0 * x)) / (1.0 + exp(-2.0 * x));', - '}', - '#endif', + "#if __VERSION__ == 100", + "float tanh (float x) {", + " return (1.0 - exp(-2.0 * x)) / (1.0 + exp(-2.0 * x));", + "}", + "#endif", - 'void main (void) {', - 'vec2 coordinates = gl_FragCoord.xy - 0.5;', + "void main (void) {", + " vec2 coordinates = gl_FragCoord.xy - 0.5;", - 'float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;', - 'float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;', + " float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;", + " float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;", - 'vec2 K = (2.0 * PI * vec2(n, m)) / u_size;', - 'float k = length(K);', + " vec2 K = (2.0 * PI * vec2(n, m)) / u_size;", + " float k = length(K);", - 'float l_wind = length(u_wind);', + " float l_wind = length(u_wind);", - 'float Omega = 0.84;', - 'float kp = G * pow2(Omega / l_wind);', + " float Omega = 0.84;", + " float kp = G * pow2(Omega / l_wind);", - 'float c = omega(k) / k;', - 'float cp = omega(kp) / kp;', + " float c = omega(k) / k;", + " float cp = omega(kp) / kp;", - 'float Lpm = exp(-1.25 * pow2(kp / k));', - 'float gamma = 1.7;', - 'float sigma = 0.08 * (1.0 + 4.0 * pow(Omega, -3.0));', - 'float Gamma = exp(-pow2(sqrt(k / kp) - 1.0) / 2.0 * pow2(sigma));', - 'float Jp = pow(gamma, Gamma);', - 'float Fp = Lpm * Jp * exp(-Omega / sqrt(10.0) * (sqrt(k / kp) - 1.0));', - 'float alphap = 0.006 * sqrt(Omega);', - 'float Bl = 0.5 * alphap * cp / c * Fp;', + " float Lpm = exp(-1.25 * pow2(kp / k));", + " float gamma = 1.7;", + " float sigma = 0.08 * (1.0 + 4.0 * pow(Omega, -3.0));", + " float Gamma = exp(-pow2(sqrt(k / kp) - 1.0) / 2.0 * pow2(sigma));", + " float Jp = pow(gamma, Gamma);", + " float Fp = Lpm * Jp * exp(-Omega / sqrt(10.0) * (sqrt(k / kp) - 1.0));", + " float alphap = 0.006 * sqrt(Omega);", + " float Bl = 0.5 * alphap * cp / c * Fp;", - 'float z0 = 0.000037 * pow2(l_wind) / G * pow(l_wind / cp, 0.9);', - 'float uStar = 0.41 * l_wind / log(10.0 / z0);', - 'float alpham = 0.01 * ((uStar < CM) ? (1.0 + log(uStar / CM)) : (1.0 + 3.0 * log(uStar / CM)));', - 'float Fm = exp(-0.25 * pow2(k / KM - 1.0));', - 'float Bh = 0.5 * alpham * CM / c * Fm * Lpm;', + " float z0 = 0.000037 * pow2(l_wind) / G * pow(l_wind / cp, 0.9);", + " float uStar = 0.41 * l_wind / log(10.0 / z0);", + " float alpham = 0.01 * ((uStar < CM) ? (1.0 + log(uStar / CM)) : (1.0 + 3.0 * log(uStar / CM)));", + " float Fm = exp(-0.25 * pow2(k / KM - 1.0));", + " float Bh = 0.5 * alpham * CM / c * Fm * Lpm;", - 'float a0 = log(2.0) / 4.0;', - 'float am = 0.13 * uStar / CM;', - 'float Delta = tanh(a0 + 4.0 * pow(c / cp, 2.5) + am * pow(CM / c, 2.5));', + " float a0 = log(2.0) / 4.0;", + " float am = 0.13 * uStar / CM;", + " float Delta = tanh(a0 + 4.0 * pow(c / cp, 2.5) + am * pow(CM / c, 2.5));", - 'float cosPhi = dot(normalize(u_wind), normalize(K));', + " float cosPhi = dot(normalize(u_wind), normalize(K));", - 'float S = (1.0 / (2.0 * PI)) * pow(k, -4.0) * (Bl + Bh) * (1.0 + Delta * (2.0 * cosPhi * cosPhi - 1.0));', + " float S = (1.0 / (2.0 * PI)) * pow(k, -4.0) * (Bl + Bh) * (1.0 + Delta * (2.0 * cosPhi * cosPhi - 1.0));", - 'float dk = 2.0 * PI / u_size;', - 'float h = sqrt(S / 2.0) * dk;', + " float dk = 2.0 * PI / u_size;", + " float h = sqrt(S / 2.0) * dk;", - 'if (K.x == 0.0 && K.y == 0.0) {', - 'h = 0.0;', //no DC term - '}', - 'gl_FragColor = vec4(h, 0.0, 0.0, 0.0);', - '}' - ].join( '\n' ) + " if (K.x == 0.0 && K.y == 0.0) {", + " h = 0.0;", //no DC term + " }", + " gl_FragColor = vec4(h, 0.0, 0.0, 0.0);", + "}" + ].join( "\n" ) }; -THREE.OceanShaders[ 'ocean_phase' ] = { +THREE.OceanShaders[ "ocean_phase" ] = { uniforms: { "u_phases": { value: null }, "u_deltaTime": { value: null }, @@ -174,39 +174,39 @@ THREE.OceanShaders[ 'ocean_phase' ] = { "u_size": { value: null } }, fragmentShader: [ - 'precision highp float;', - '#include ', + "precision highp float;", + "#include ", - 'const float G = 9.81;', - 'const float KM = 370.0;', + "const float G = 9.81;", + "const float KM = 370.0;", - 'varying vec2 vUV;', + "varying vec2 vUV;", - 'uniform sampler2D u_phases;', - 'uniform float u_deltaTime;', - 'uniform float u_resolution;', - 'uniform float u_size;', + "uniform sampler2D u_phases;", + "uniform float u_deltaTime;", + "uniform float u_resolution;", + "uniform float u_size;", - 'float omega (float k) {', - 'return sqrt(G * k * (1.0 + k * k / KM * KM));', - '}', + "float omega (float k) {", + " return sqrt(G * k * (1.0 + k * k / KM * KM));", + "}", - 'void main (void) {', - 'float deltaTime = 1.0 / 60.0;', - 'vec2 coordinates = gl_FragCoord.xy - 0.5;', - 'float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;', - 'float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;', - 'vec2 waveVector = (2.0 * PI * vec2(n, m)) / u_size;', + "void main (void) {", + " float deltaTime = 1.0 / 60.0;", + " vec2 coordinates = gl_FragCoord.xy - 0.5;", + " float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;", + " float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;", + " vec2 waveVector = (2.0 * PI * vec2(n, m)) / u_size;", - 'float phase = texture2D(u_phases, vUV).r;', - 'float deltaPhase = omega(length(waveVector)) * u_deltaTime;', - 'phase = mod(phase + deltaPhase, 2.0 * PI);', + " float phase = texture2D(u_phases, vUV).r;", + " float deltaPhase = omega(length(waveVector)) * u_deltaTime;", + " phase = mod(phase + deltaPhase, 2.0 * PI);", - 'gl_FragColor = vec4(phase, 0.0, 0.0, 0.0);', - '}' - ].join( '\n' ) + " gl_FragColor = vec4(phase, 0.0, 0.0, 0.0);", + "}" + ].join( "\n" ) }; -THREE.OceanShaders[ 'ocean_spectrum' ] = { +THREE.OceanShaders[ "ocean_spectrum" ] = { uniforms: { "u_size": { value: null }, "u_resolution": { value: null }, @@ -215,96 +215,96 @@ THREE.OceanShaders[ 'ocean_spectrum' ] = { "u_initialSpectrum": { value: null } }, fragmentShader: [ - 'precision highp float;', - '#include ', + "precision highp float;", + "#include ", - 'const float G = 9.81;', - 'const float KM = 370.0;', + "const float G = 9.81;", + "const float KM = 370.0;", - 'varying vec2 vUV;', + "varying vec2 vUV;", - 'uniform float u_size;', - 'uniform float u_resolution;', - 'uniform float u_choppiness;', - 'uniform sampler2D u_phases;', - 'uniform sampler2D u_initialSpectrum;', + "uniform float u_size;", + "uniform float u_resolution;", + "uniform float u_choppiness;", + "uniform sampler2D u_phases;", + "uniform sampler2D u_initialSpectrum;", - 'vec2 multiplyComplex (vec2 a, vec2 b) {', - 'return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);', - '}', + "vec2 multiplyComplex (vec2 a, vec2 b) {", + " return vec2(a[0] * b[0] - a[1] * b[1], a[1] * b[0] + a[0] * b[1]);", + "}", - 'vec2 multiplyByI (vec2 z) {', - 'return vec2(-z[1], z[0]);', - '}', + "vec2 multiplyByI (vec2 z) {", + " return vec2(-z[1], z[0]);", + "}", - 'float omega (float k) {', - 'return sqrt(G * k * (1.0 + k * k / KM * KM));', - '}', + "float omega (float k) {", + " return sqrt(G * k * (1.0 + k * k / KM * KM));", + "}", - 'void main (void) {', - 'vec2 coordinates = gl_FragCoord.xy - 0.5;', - 'float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;', - 'float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;', - 'vec2 waveVector = (2.0 * PI * vec2(n, m)) / u_size;', + "void main (void) {", + " vec2 coordinates = gl_FragCoord.xy - 0.5;", + " float n = (coordinates.x < u_resolution * 0.5) ? coordinates.x : coordinates.x - u_resolution;", + " float m = (coordinates.y < u_resolution * 0.5) ? coordinates.y : coordinates.y - u_resolution;", + " vec2 waveVector = (2.0 * PI * vec2(n, m)) / u_size;", - 'float phase = texture2D(u_phases, vUV).r;', - 'vec2 phaseVector = vec2(cos(phase), sin(phase));', + " float phase = texture2D(u_phases, vUV).r;", + " vec2 phaseVector = vec2(cos(phase), sin(phase));", - 'vec2 h0 = texture2D(u_initialSpectrum, vUV).rg;', - 'vec2 h0Star = texture2D(u_initialSpectrum, vec2(1.0 - vUV + 1.0 / u_resolution)).rg;', - 'h0Star.y *= -1.0;', + " vec2 h0 = texture2D(u_initialSpectrum, vUV).rg;", + " vec2 h0Star = texture2D(u_initialSpectrum, vec2(1.0 - vUV + 1.0 / u_resolution)).rg;", + " h0Star.y *= -1.0;", - 'vec2 h = multiplyComplex(h0, phaseVector) + multiplyComplex(h0Star, vec2(phaseVector.x, -phaseVector.y));', + " vec2 h = multiplyComplex(h0, phaseVector) + multiplyComplex(h0Star, vec2(phaseVector.x, -phaseVector.y));", - 'vec2 hX = -multiplyByI(h * (waveVector.x / length(waveVector))) * u_choppiness;', - 'vec2 hZ = -multiplyByI(h * (waveVector.y / length(waveVector))) * u_choppiness;', + " vec2 hX = -multiplyByI(h * (waveVector.x / length(waveVector))) * u_choppiness;", + " vec2 hZ = -multiplyByI(h * (waveVector.y / length(waveVector))) * u_choppiness;", - //no DC term - 'if (waveVector.x == 0.0 && waveVector.y == 0.0) {', - 'h = vec2(0.0);', - 'hX = vec2(0.0);', - 'hZ = vec2(0.0);', - '}', + //no DC term + " if (waveVector.x == 0.0 && waveVector.y == 0.0) {", + " h = vec2(0.0);", + " hX = vec2(0.0);", + " hZ = vec2(0.0);", + " }", - 'gl_FragColor = vec4(hX + multiplyByI(h), hZ);', - '}' - ].join( '\n' ) + " gl_FragColor = vec4(hX + multiplyByI(h), hZ);", + "}" + ].join( "\n" ) }; -THREE.OceanShaders[ 'ocean_normals' ] = { +THREE.OceanShaders[ "ocean_normals" ] = { uniforms: { "u_displacementMap": { value: null }, "u_resolution": { value: null }, "u_size": { value: null } }, fragmentShader: [ - 'precision highp float;', + "precision highp float;", - 'varying vec2 vUV;', + "varying vec2 vUV;", - 'uniform sampler2D u_displacementMap;', - 'uniform float u_resolution;', - 'uniform float u_size;', + "uniform sampler2D u_displacementMap;", + "uniform float u_resolution;", + "uniform float u_size;", - 'void main (void) {', - 'float texel = 1.0 / u_resolution;', - 'float texelSize = u_size / u_resolution;', + "void main (void) {", + " float texel = 1.0 / u_resolution;", + " float texelSize = u_size / u_resolution;", - 'vec3 center = texture2D(u_displacementMap, vUV).rgb;', - 'vec3 right = vec3(texelSize, 0.0, 0.0) + texture2D(u_displacementMap, vUV + vec2(texel, 0.0)).rgb - center;', - 'vec3 left = vec3(-texelSize, 0.0, 0.0) + texture2D(u_displacementMap, vUV + vec2(-texel, 0.0)).rgb - center;', - 'vec3 top = vec3(0.0, 0.0, -texelSize) + texture2D(u_displacementMap, vUV + vec2(0.0, -texel)).rgb - center;', - 'vec3 bottom = vec3(0.0, 0.0, texelSize) + texture2D(u_displacementMap, vUV + vec2(0.0, texel)).rgb - center;', + " vec3 center = texture2D(u_displacementMap, vUV).rgb;", + " vec3 right = vec3(texelSize, 0.0, 0.0) + texture2D(u_displacementMap, vUV + vec2(texel, 0.0)).rgb - center;", + " vec3 left = vec3(-texelSize, 0.0, 0.0) + texture2D(u_displacementMap, vUV + vec2(-texel, 0.0)).rgb - center;", + " vec3 top = vec3(0.0, 0.0, -texelSize) + texture2D(u_displacementMap, vUV + vec2(0.0, -texel)).rgb - center;", + " vec3 bottom = vec3(0.0, 0.0, texelSize) + texture2D(u_displacementMap, vUV + vec2(0.0, texel)).rgb - center;", - 'vec3 topRight = cross(right, top);', - 'vec3 topLeft = cross(top, left);', - 'vec3 bottomLeft = cross(left, bottom);', - 'vec3 bottomRight = cross(bottom, right);', + " vec3 topRight = cross(right, top);", + " vec3 topLeft = cross(top, left);", + " vec3 bottomLeft = cross(left, bottom);", + " vec3 bottomRight = cross(bottom, right);", - 'gl_FragColor = vec4(normalize(topRight + topLeft + bottomLeft + bottomRight), 1.0);', - '}' - ].join( '\n' ) + " gl_FragColor = vec4(normalize(topRight + topLeft + bottomLeft + bottomRight), 1.0);", + "}" + ].join( "\n" ) }; -THREE.OceanShaders[ 'ocean_main' ] = { +THREE.OceanShaders[ "ocean_main" ] = { uniforms: { "u_displacementMap": { value: null }, "u_normalMap": { value: null }, @@ -319,55 +319,55 @@ THREE.OceanShaders[ 'ocean_main' ] = { "u_exposure": { value: null } }, vertexShader: [ - 'precision highp float;', - - 'varying vec3 vPos;', - 'varying vec2 vUV;', - - 'uniform mat4 u_projectionMatrix;', - 'uniform mat4 u_viewMatrix;', - 'uniform float u_size;', - 'uniform float u_geometrySize;', - 'uniform sampler2D u_displacementMap;', - - 'void main (void) {', - 'vec3 newPos = position + texture2D(u_displacementMap, uv).rgb * (u_geometrySize / u_size);', - 'vPos = newPos;', - 'vUV = uv;', - 'gl_Position = u_projectionMatrix * u_viewMatrix * vec4(newPos, 1.0);', - '}' - ].join( '\n' ), + "precision highp float;", + + "varying vec3 vPos;", + "varying vec2 vUV;", + + "uniform mat4 u_projectionMatrix;", + "uniform mat4 u_viewMatrix;", + "uniform float u_size;", + "uniform float u_geometrySize;", + "uniform sampler2D u_displacementMap;", + + "void main (void) {", + " vec3 newPos = position + texture2D(u_displacementMap, uv).rgb * (u_geometrySize / u_size);", + " vPos = newPos;", + " vUV = uv;", + " gl_Position = u_projectionMatrix * u_viewMatrix * vec4(newPos, 1.0);", + "}" + ].join( "\n" ), fragmentShader: [ - 'precision highp float;', + "precision highp float;", - 'varying vec3 vPos;', - 'varying vec2 vUV;', + "varying vec3 vPos;", + "varying vec2 vUV;", - 'uniform sampler2D u_displacementMap;', - 'uniform sampler2D u_normalMap;', - 'uniform vec3 u_cameraPosition;', - 'uniform vec3 u_oceanColor;', - 'uniform vec3 u_skyColor;', - 'uniform vec3 u_sunDirection;', - 'uniform float u_exposure;', + "uniform sampler2D u_displacementMap;", + "uniform sampler2D u_normalMap;", + "uniform vec3 u_cameraPosition;", + "uniform vec3 u_oceanColor;", + "uniform vec3 u_skyColor;", + "uniform vec3 u_sunDirection;", + "uniform float u_exposure;", - 'vec3 hdr (vec3 color, float exposure) {', - 'return 1.0 - exp(-color * exposure);', - '}', + "vec3 hdr (vec3 color, float exposure) {", + " return 1.0 - exp(-color * exposure);", + "}", - 'void main (void) {', - 'vec3 normal = texture2D(u_normalMap, vUV).rgb;', + "void main (void) {", + " vec3 normal = texture2D(u_normalMap, vUV).rgb;", - 'vec3 view = normalize(u_cameraPosition - vPos);', - 'float fresnel = 0.02 + 0.98 * pow(1.0 - dot(normal, view), 5.0);', - 'vec3 sky = fresnel * u_skyColor;', + " vec3 view = normalize(u_cameraPosition - vPos);", + " float fresnel = 0.02 + 0.98 * pow(1.0 - dot(normal, view), 5.0);", + " vec3 sky = fresnel * u_skyColor;", - 'float diffuse = clamp(dot(normal, normalize(u_sunDirection)), 0.0, 1.0);', - 'vec3 water = (1.0 - fresnel) * u_oceanColor * u_skyColor * diffuse;', + " float diffuse = clamp(dot(normal, normalize(u_sunDirection)), 0.0, 1.0);", + " vec3 water = (1.0 - fresnel) * u_oceanColor * u_skyColor * diffuse;", - 'vec3 color = sky + water;', + " vec3 color = sky + water;", - 'gl_FragColor = vec4(hdr(color, u_exposure), 1.0);', - '}' - ].join( '\n' ) + " gl_FragColor = vec4(hdr(color, u_exposure), 1.0);", + "}" + ].join( "\n" ) }; diff --git a/examples/js/shaders/ParallaxShader.js b/examples/js/shaders/ParallaxShader.js index 5b9531d70df5dc..396bbc6727f848 100644 --- a/examples/js/shaders/ParallaxShader.js +++ b/examples/js/shaders/ParallaxShader.js @@ -6,11 +6,11 @@ THREE.ParallaxShader = { // Ordered from fastest to best quality. modes: { - none: 'NO_PARALLAX', - basic: 'USE_BASIC_PARALLAX', - steep: 'USE_STEEP_PARALLAX', - occlusion: 'USE_OCLUSION_PARALLAX', // a.k.a. POM - relief: 'USE_RELIEF_PARALLAX' + none: "NO_PARALLAX", + basic: "USE_BASIC_PARALLAX", + steep: "USE_STEEP_PARALLAX", + occlusion: "USE_OCLUSION_PARALLAX", // a.k.a. POM + relief: "USE_RELIEF_PARALLAX" }, uniforms: { @@ -28,15 +28,15 @@ THREE.ParallaxShader = { "void main() {", - "vUv = uv;", - "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - "vViewPosition = -mvPosition.xyz;", - "vNormal = normalize( normalMatrix * normal );", - "gl_Position = projectionMatrix * mvPosition;", + " vUv = uv;", + " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + " vViewPosition = -mvPosition.xyz;", + " vNormal = normalize( normalMatrix * normal );", + " gl_Position = projectionMatrix * mvPosition;", "}" - ].join( "\n" ), + ].join( "\n" ), fragmentShader: [ "uniform sampler2D bumpMap;", @@ -52,133 +52,133 @@ THREE.ParallaxShader = { "#ifdef USE_BASIC_PARALLAX", - "vec2 parallaxMap( in vec3 V ) {", + " vec2 parallaxMap( in vec3 V ) {", - "float initialHeight = texture2D( bumpMap, vUv ).r;", + " float initialHeight = texture2D( bumpMap, vUv ).r;", - // No Offset Limitting: messy, floating output at grazing angles. - //"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;", + // No Offset Limitting: messy, floating output at grazing angles. + //"vec2 texCoordOffset = parallaxScale * V.xy / V.z * initialHeight;", - // Offset Limiting - "vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;", - "return vUv - texCoordOffset;", + // Offset Limiting + " vec2 texCoordOffset = parallaxScale * V.xy * initialHeight;", + " return vUv - texCoordOffset;", - "}", + " }", "#else", - "vec2 parallaxMap( in vec3 V ) {", + " vec2 parallaxMap( in vec3 V ) {", - // Determine number of layers from angle between V and N - "float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );", + // Determine number of layers from angle between V and N + " float numLayers = mix( parallaxMaxLayers, parallaxMinLayers, abs( dot( vec3( 0.0, 0.0, 1.0 ), V ) ) );", - "float layerHeight = 1.0 / numLayers;", - "float currentLayerHeight = 0.0;", - // Shift of texture coordinates for each iteration - "vec2 dtex = parallaxScale * V.xy / V.z / numLayers;", + " float layerHeight = 1.0 / numLayers;", + " float currentLayerHeight = 0.0;", + // Shift of texture coordinates for each iteration + " vec2 dtex = parallaxScale * V.xy / V.z / numLayers;", - "vec2 currentTextureCoords = vUv;", + " vec2 currentTextureCoords = vUv;", - "float heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;", + " float heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;", - // while ( heightFromTexture > currentLayerHeight ) - // Infinite loops are not well supported. Do a "large" finite - // loop, but not too large, as it slows down some compilers. - "for ( int i = 0; i < 30; i += 1 ) {", - "if ( heightFromTexture <= currentLayerHeight ) {", - "break;", - "}", - "currentLayerHeight += layerHeight;", - // Shift texture coordinates along vector V - "currentTextureCoords -= dtex;", - "heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;", - "}", + // while ( heightFromTexture > currentLayerHeight ) + // Infinite loops are not well supported. Do a "large" finite + // loop, but not too large, as it slows down some compilers. + " for ( int i = 0; i < 30; i += 1 ) {", + " if ( heightFromTexture <= currentLayerHeight ) {", + " break;", + " }", + " currentLayerHeight += layerHeight;", + // Shift texture coordinates along vector V + " currentTextureCoords -= dtex;", + " heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;", + " }", - "#ifdef USE_STEEP_PARALLAX", + " #ifdef USE_STEEP_PARALLAX", - "return currentTextureCoords;", + " return currentTextureCoords;", - "#elif defined( USE_RELIEF_PARALLAX )", + " #elif defined( USE_RELIEF_PARALLAX )", - "vec2 deltaTexCoord = dtex / 2.0;", - "float deltaHeight = layerHeight / 2.0;", + " vec2 deltaTexCoord = dtex / 2.0;", + " float deltaHeight = layerHeight / 2.0;", - // Return to the mid point of previous layer - "currentTextureCoords += deltaTexCoord;", - "currentLayerHeight -= deltaHeight;", + // Return to the mid point of previous layer + " currentTextureCoords += deltaTexCoord;", + " currentLayerHeight -= deltaHeight;", - // Binary search to increase precision of Steep Parallax Mapping - "const int numSearches = 5;", - "for ( int i = 0; i < numSearches; i += 1 ) {", + // Binary search to increase precision of Steep Parallax Mapping + " const int numSearches = 5;", + " for ( int i = 0; i < numSearches; i += 1 ) {", - "deltaTexCoord /= 2.0;", - "deltaHeight /= 2.0;", - "heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;", - // Shift along or against vector V - "if( heightFromTexture > currentLayerHeight ) {", // Below the surface + " deltaTexCoord /= 2.0;", + " deltaHeight /= 2.0;", + " heightFromTexture = texture2D( bumpMap, currentTextureCoords ).r;", + // Shift along or against vector V + " if( heightFromTexture > currentLayerHeight ) {", // Below the surface - "currentTextureCoords -= deltaTexCoord;", - "currentLayerHeight += deltaHeight;", + " currentTextureCoords -= deltaTexCoord;", + " currentLayerHeight += deltaHeight;", - "} else {", // above the surface + " } else {", // above the surface - "currentTextureCoords += deltaTexCoord;", - "currentLayerHeight -= deltaHeight;", + " currentTextureCoords += deltaTexCoord;", + " currentLayerHeight -= deltaHeight;", - "}", + " }", - "}", - "return currentTextureCoords;", + " }", + " return currentTextureCoords;", - "#elif defined( USE_OCLUSION_PARALLAX )", + " #elif defined( USE_OCLUSION_PARALLAX )", - "vec2 prevTCoords = currentTextureCoords + dtex;", + " vec2 prevTCoords = currentTextureCoords + dtex;", - // Heights for linear interpolation - "float nextH = heightFromTexture - currentLayerHeight;", - "float prevH = texture2D( bumpMap, prevTCoords ).r - currentLayerHeight + layerHeight;", + // Heights for linear interpolation + " float nextH = heightFromTexture - currentLayerHeight;", + " float prevH = texture2D( bumpMap, prevTCoords ).r - currentLayerHeight + layerHeight;", - // Proportions for linear interpolation - "float weight = nextH / ( nextH - prevH );", + // Proportions for linear interpolation + " float weight = nextH / ( nextH - prevH );", - // Interpolation of texture coordinates - "return prevTCoords * weight + currentTextureCoords * ( 1.0 - weight );", + // Interpolation of texture coordinates + " return prevTCoords * weight + currentTextureCoords * ( 1.0 - weight );", - "#else", // NO_PARALLAX + " #else", // NO_PARALLAX - "return vUv;", + " return vUv;", - "#endif", + " #endif", - "}", + " }", "#endif", "vec2 perturbUv( vec3 surfPosition, vec3 surfNormal, vec3 viewPosition ) {", - "vec2 texDx = dFdx( vUv );", - "vec2 texDy = dFdy( vUv );", + " vec2 texDx = dFdx( vUv );", + " vec2 texDy = dFdy( vUv );", - "vec3 vSigmaX = dFdx( surfPosition );", - "vec3 vSigmaY = dFdy( surfPosition );", - "vec3 vR1 = cross( vSigmaY, surfNormal );", - "vec3 vR2 = cross( surfNormal, vSigmaX );", - "float fDet = dot( vSigmaX, vR1 );", + " vec3 vSigmaX = dFdx( surfPosition );", + " vec3 vSigmaY = dFdy( surfPosition );", + " vec3 vR1 = cross( vSigmaY, surfNormal );", + " vec3 vR2 = cross( surfNormal, vSigmaX );", + " float fDet = dot( vSigmaX, vR1 );", - "vec2 vProjVscr = ( 1.0 / fDet ) * vec2( dot( vR1, viewPosition ), dot( vR2, viewPosition ) );", - "vec3 vProjVtex;", - "vProjVtex.xy = texDx * vProjVscr.x + texDy * vProjVscr.y;", - "vProjVtex.z = dot( surfNormal, viewPosition );", + " vec2 vProjVscr = ( 1.0 / fDet ) * vec2( dot( vR1, viewPosition ), dot( vR2, viewPosition ) );", + " vec3 vProjVtex;", + " vProjVtex.xy = texDx * vProjVscr.x + texDy * vProjVscr.y;", + " vProjVtex.z = dot( surfNormal, viewPosition );", - "return parallaxMap( vProjVtex );", + " return parallaxMap( vProjVtex );", "}", "void main() {", - "vec2 mapUv = perturbUv( -vViewPosition, normalize( vNormal ), normalize( vViewPosition ) );", - "gl_FragColor = texture2D( map, mapUv );", + " vec2 mapUv = perturbUv( -vViewPosition, normalize( vNormal ), normalize( vViewPosition ) );", + " gl_FragColor = texture2D( map, mapUv );", "}" - ].join( "\n" ) + ].join( "\n" ) }; diff --git a/examples/js/shaders/RGBShiftShader.js b/examples/js/shaders/RGBShiftShader.js index c88b7fd84e1168..d53f9611b5b731 100644 --- a/examples/js/shaders/RGBShiftShader.js +++ b/examples/js/shaders/RGBShiftShader.js @@ -26,8 +26,8 @@ THREE.RGBShiftShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -43,11 +43,11 @@ THREE.RGBShiftShader = { "void main() {", - "vec2 offset = amount * vec2( cos(angle), sin(angle));", - "vec4 cr = texture2D(tDiffuse, vUv + offset);", - "vec4 cga = texture2D(tDiffuse, vUv);", - "vec4 cb = texture2D(tDiffuse, vUv - offset);", - "gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", + " vec2 offset = amount * vec2( cos(angle), sin(angle));", + " vec4 cr = texture2D(tDiffuse, vUv + offset);", + " vec4 cga = texture2D(tDiffuse, vUv);", + " vec4 cb = texture2D(tDiffuse, vUv - offset);", + " gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);", "}" diff --git a/examples/js/shaders/SAOShader.js b/examples/js/shaders/SAOShader.js index 2221558f69b064..d344f7b0c73d8b 100644 --- a/examples/js/shaders/SAOShader.js +++ b/examples/js/shaders/SAOShader.js @@ -4,32 +4,32 @@ THREE.SAOShader = { defines: { - 'NUM_SAMPLES': 7, - 'NUM_RINGS': 4, - 'NORMAL_TEXTURE': 0, - 'DIFFUSE_TEXTURE': 0, - 'DEPTH_PACKING': 1, - 'PERSPECTIVE_CAMERA': 1 + "NUM_SAMPLES": 7, + "NUM_RINGS": 4, + "NORMAL_TEXTURE": 0, + "DIFFUSE_TEXTURE": 0, + "DEPTH_PACKING": 1, + "PERSPECTIVE_CAMERA": 1 }, uniforms: { - 'tDepth': { value: null }, - 'tDiffuse': { value: null }, - 'tNormal': { value: null }, - 'size': { value: new THREE.Vector2( 512, 512 ) }, + "tDepth": { value: null }, + "tDiffuse": { value: null }, + "tNormal": { value: null }, + "size": { value: new THREE.Vector2( 512, 512 ) }, - 'cameraNear': { value: 1 }, - 'cameraFar': { value: 100 }, - 'cameraProjectionMatrix': { value: new THREE.Matrix4() }, - 'cameraInverseProjectionMatrix': { value: new THREE.Matrix4() }, + "cameraNear": { value: 1 }, + "cameraFar": { value: 100 }, + "cameraProjectionMatrix": { value: new THREE.Matrix4() }, + "cameraInverseProjectionMatrix": { value: new THREE.Matrix4() }, - 'scale': { value: 1.0 }, - 'intensity': { value: 0.1 }, - 'bias': { value: 0.5 }, + "scale": { value: 1.0 }, + "intensity": { value: 0.1 }, + "bias": { value: 0.5 }, - 'minResolution': { value: 0.0 }, - 'kernelRadius': { value: 100.0 }, - 'randomSeed': { value: 0.0 } + "minResolution": { value: 0.0 }, + "kernelRadius": { value: 100.0 }, + "randomSeed": { value: 0.0 } }, vertexShader: [ "varying vec2 vUv;", diff --git a/examples/js/shaders/SMAAShader.js b/examples/js/shaders/SMAAShader.js index aecba4b6a32925..c9e0a26da0c5ee 100644 --- a/examples/js/shaders/SMAAShader.js +++ b/examples/js/shaders/SMAAShader.js @@ -29,18 +29,18 @@ THREE.SMAAEdgesShader = { "varying vec4 vOffset[ 3 ];", "void SMAAEdgeDetectionVS( vec2 texcoord ) {", - "vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 );", // WebGL port note: Changed sign in W component - "vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 );", // WebGL port note: Changed sign in W component - "vOffset[ 2 ] = texcoord.xyxy + resolution.xyxy * vec4( -2.0, 0.0, 0.0, 2.0 );", // WebGL port note: Changed sign in W component + " vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 );", // WebGL port note: Changed sign in W component + " vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 );", // WebGL port note: Changed sign in W component + " vOffset[ 2 ] = texcoord.xyxy + resolution.xyxy * vec4( -2.0, 0.0, 0.0, 2.0 );", // WebGL port note: Changed sign in W component "}", "void main() {", - "vUv = uv;", + " vUv = uv;", - "SMAAEdgeDetectionVS( vUv );", + " SMAAEdgeDetectionVS( vUv );", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -54,60 +54,60 @@ THREE.SMAAEdgesShader = { "varying vec4 vOffset[ 3 ];", "vec4 SMAAColorEdgeDetectionPS( vec2 texcoord, vec4 offset[3], sampler2D colorTex ) {", - "vec2 threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );", + " vec2 threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );", - // Calculate color deltas: - "vec4 delta;", - "vec3 C = texture2D( colorTex, texcoord ).rgb;", + // Calculate color deltas: + " vec4 delta;", + " vec3 C = texture2D( colorTex, texcoord ).rgb;", - "vec3 Cleft = texture2D( colorTex, offset[0].xy ).rgb;", - "vec3 t = abs( C - Cleft );", - "delta.x = max( max( t.r, t.g ), t.b );", + " vec3 Cleft = texture2D( colorTex, offset[0].xy ).rgb;", + " vec3 t = abs( C - Cleft );", + " delta.x = max( max( t.r, t.g ), t.b );", - "vec3 Ctop = texture2D( colorTex, offset[0].zw ).rgb;", - "t = abs( C - Ctop );", - "delta.y = max( max( t.r, t.g ), t.b );", + " vec3 Ctop = texture2D( colorTex, offset[0].zw ).rgb;", + " t = abs( C - Ctop );", + " delta.y = max( max( t.r, t.g ), t.b );", - // We do the usual threshold: - "vec2 edges = step( threshold, delta.xy );", + // We do the usual threshold: + " vec2 edges = step( threshold, delta.xy );", - // Then discard if there is no edge: - "if ( dot( edges, vec2( 1.0, 1.0 ) ) == 0.0 )", - "discard;", + // Then discard if there is no edge: + " if ( dot( edges, vec2( 1.0, 1.0 ) ) == 0.0 )", + " discard;", - // Calculate right and bottom deltas: - "vec3 Cright = texture2D( colorTex, offset[1].xy ).rgb;", - "t = abs( C - Cright );", - "delta.z = max( max( t.r, t.g ), t.b );", + // Calculate right and bottom deltas: + " vec3 Cright = texture2D( colorTex, offset[1].xy ).rgb;", + " t = abs( C - Cright );", + " delta.z = max( max( t.r, t.g ), t.b );", - "vec3 Cbottom = texture2D( colorTex, offset[1].zw ).rgb;", - "t = abs( C - Cbottom );", - "delta.w = max( max( t.r, t.g ), t.b );", + " vec3 Cbottom = texture2D( colorTex, offset[1].zw ).rgb;", + " t = abs( C - Cbottom );", + " delta.w = max( max( t.r, t.g ), t.b );", - // Calculate the maximum delta in the direct neighborhood: - "float maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w );", + // Calculate the maximum delta in the direct neighborhood: + " float maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w );", - // Calculate left-left and top-top deltas: - "vec3 Cleftleft = texture2D( colorTex, offset[2].xy ).rgb;", - "t = abs( C - Cleftleft );", - "delta.z = max( max( t.r, t.g ), t.b );", + // Calculate left-left and top-top deltas: + " vec3 Cleftleft = texture2D( colorTex, offset[2].xy ).rgb;", + " t = abs( C - Cleftleft );", + " delta.z = max( max( t.r, t.g ), t.b );", - "vec3 Ctoptop = texture2D( colorTex, offset[2].zw ).rgb;", - "t = abs( C - Ctoptop );", - "delta.w = max( max( t.r, t.g ), t.b );", + " vec3 Ctoptop = texture2D( colorTex, offset[2].zw ).rgb;", + " t = abs( C - Ctoptop );", + " delta.w = max( max( t.r, t.g ), t.b );", - // Calculate the final maximum delta: - "maxDelta = max( max( maxDelta, delta.z ), delta.w );", + // Calculate the final maximum delta: + " maxDelta = max( max( maxDelta, delta.z ), delta.w );", - // Local contrast adaptation in action: - "edges.xy *= step( 0.5 * maxDelta, delta.xy );", + // Local contrast adaptation in action: + " edges.xy *= step( 0.5 * maxDelta, delta.xy );", - "return vec4( edges, 0.0, 0.0 );", + " return vec4( edges, 0.0, 0.0 );", "}", "void main() {", - "gl_FragColor = SMAAColorEdgeDetectionPS( vUv, vOffset, tDiffuse );", + " gl_FragColor = SMAAColorEdgeDetectionPS( vUv, vOffset, tDiffuse );", "}" @@ -144,24 +144,24 @@ THREE.SMAAWeightsShader = { "varying vec2 vPixcoord;", "void SMAABlendingWeightCalculationVS( vec2 texcoord ) {", - "vPixcoord = texcoord / resolution;", + " vPixcoord = texcoord / resolution;", - // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): - "vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.25, 0.125, 1.25, 0.125 );", // WebGL port note: Changed sign in Y and W components - "vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.125, 0.25, -0.125, -1.25 );", // WebGL port note: Changed sign in Y and W components + // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): + " vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.25, 0.125, 1.25, 0.125 );", // WebGL port note: Changed sign in Y and W components + " vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.125, 0.25, -0.125, -1.25 );", // WebGL port note: Changed sign in Y and W components - // And these for the searches, they indicate the ends of the loops: - "vOffset[ 2 ] = vec4( vOffset[ 0 ].xz, vOffset[ 1 ].yw ) + vec4( -2.0, 2.0, -2.0, 2.0 ) * resolution.xxyy * float( SMAA_MAX_SEARCH_STEPS );", + // And these for the searches, they indicate the ends of the loops: + " vOffset[ 2 ] = vec4( vOffset[ 0 ].xz, vOffset[ 1 ].yw ) + vec4( -2.0, 2.0, -2.0, 2.0 ) * resolution.xxyy * float( SMAA_MAX_SEARCH_STEPS );", "}", "void main() {", - "vUv = uv;", + " vUv = uv;", - "SMAABlendingWeightCalculationVS( vUv );", + " SMAABlendingWeightCalculationVS( vUv );", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -182,190 +182,190 @@ THREE.SMAAWeightsShader = { "#if __VERSION__ == 100", "vec2 round( vec2 x ) {", - "return sign( x ) * floor( abs( x ) + 0.5 );", + " return sign( x ) * floor( abs( x ) + 0.5 );", "}", "#endif", "float SMAASearchLength( sampler2D searchTex, vec2 e, float bias, float scale ) {", - // Not required if searchTex accesses are set to point: - // float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0); - // e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE + - // e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE; - "e.r = bias + e.r * scale;", - "return 255.0 * texture2D( searchTex, e, 0.0 ).r;", + // Not required if searchTex accesses are set to point: + // float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0); + // e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE + + // e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE; + " e.r = bias + e.r * scale;", + " return 255.0 * texture2D( searchTex, e, 0.0 ).r;", "}", "float SMAASearchXLeft( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {", - /** + /** * @PSEUDO_GATHER4 * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to * sample between edge, thus fetching four edges in a row. * Sampling with different offsets in each direction allows to disambiguate * which edges are active from the four fetched ones. */ - "vec2 e = vec2( 0.0, 1.0 );", + " vec2 e = vec2( 0.0, 1.0 );", - "for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for - "e = texture2D( edgesTex, texcoord, 0.0 ).rg;", - "texcoord -= vec2( 2.0, 0.0 ) * resolution;", - "if ( ! ( texcoord.x > end && e.g > 0.8281 && e.r == 0.0 ) ) break;", - "}", + " for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for + " e = texture2D( edgesTex, texcoord, 0.0 ).rg;", + " texcoord -= vec2( 2.0, 0.0 ) * resolution;", + " if ( ! ( texcoord.x > end && e.g > 0.8281 && e.r == 0.0 ) ) break;", + " }", - // We correct the previous (-0.25, -0.125) offset we applied: - "texcoord.x += 0.25 * resolution.x;", + // We correct the previous (-0.25, -0.125) offset we applied: + " texcoord.x += 0.25 * resolution.x;", - // The searches are bias by 1, so adjust the coords accordingly: - "texcoord.x += resolution.x;", + // The searches are bias by 1, so adjust the coords accordingly: + " texcoord.x += resolution.x;", - // Disambiguate the length added by the last step: - "texcoord.x += 2.0 * resolution.x;", // Undo last step - "texcoord.x -= resolution.x * SMAASearchLength(searchTex, e, 0.0, 0.5);", + // Disambiguate the length added by the last step: + " texcoord.x += 2.0 * resolution.x;", // Undo last step + " texcoord.x -= resolution.x * SMAASearchLength(searchTex, e, 0.0, 0.5);", - "return texcoord.x;", + " return texcoord.x;", "}", "float SMAASearchXRight( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {", - "vec2 e = vec2( 0.0, 1.0 );", + " vec2 e = vec2( 0.0, 1.0 );", - "for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for - "e = texture2D( edgesTex, texcoord, 0.0 ).rg;", - "texcoord += vec2( 2.0, 0.0 ) * resolution;", - "if ( ! ( texcoord.x < end && e.g > 0.8281 && e.r == 0.0 ) ) break;", - "}", + " for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for + " e = texture2D( edgesTex, texcoord, 0.0 ).rg;", + " texcoord += vec2( 2.0, 0.0 ) * resolution;", + " if ( ! ( texcoord.x < end && e.g > 0.8281 && e.r == 0.0 ) ) break;", + " }", - "texcoord.x -= 0.25 * resolution.x;", - "texcoord.x -= resolution.x;", - "texcoord.x -= 2.0 * resolution.x;", - "texcoord.x += resolution.x * SMAASearchLength( searchTex, e, 0.5, 0.5 );", + " texcoord.x -= 0.25 * resolution.x;", + " texcoord.x -= resolution.x;", + " texcoord.x -= 2.0 * resolution.x;", + " texcoord.x += resolution.x * SMAASearchLength( searchTex, e, 0.5, 0.5 );", - "return texcoord.x;", + " return texcoord.x;", "}", "float SMAASearchYUp( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {", - "vec2 e = vec2( 1.0, 0.0 );", + " vec2 e = vec2( 1.0, 0.0 );", - "for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for - "e = texture2D( edgesTex, texcoord, 0.0 ).rg;", - "texcoord += vec2( 0.0, 2.0 ) * resolution;", // WebGL port note: Changed sign - "if ( ! ( texcoord.y > end && e.r > 0.8281 && e.g == 0.0 ) ) break;", - "}", + " for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for + " e = texture2D( edgesTex, texcoord, 0.0 ).rg;", + " texcoord += vec2( 0.0, 2.0 ) * resolution;", // WebGL port note: Changed sign + " if ( ! ( texcoord.y > end && e.r > 0.8281 && e.g == 0.0 ) ) break;", + " }", - "texcoord.y -= 0.25 * resolution.y;", // WebGL port note: Changed sign - "texcoord.y -= resolution.y;", // WebGL port note: Changed sign - "texcoord.y -= 2.0 * resolution.y;", // WebGL port note: Changed sign - "texcoord.y += resolution.y * SMAASearchLength( searchTex, e.gr, 0.0, 0.5 );", // WebGL port note: Changed sign + " texcoord.y -= 0.25 * resolution.y;", // WebGL port note: Changed sign + " texcoord.y -= resolution.y;", // WebGL port note: Changed sign + " texcoord.y -= 2.0 * resolution.y;", // WebGL port note: Changed sign + " texcoord.y += resolution.y * SMAASearchLength( searchTex, e.gr, 0.0, 0.5 );", // WebGL port note: Changed sign - "return texcoord.y;", + " return texcoord.y;", "}", "float SMAASearchYDown( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {", - "vec2 e = vec2( 1.0, 0.0 );", + " vec2 e = vec2( 1.0, 0.0 );", - "for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for - "e = texture2D( edgesTex, texcoord, 0.0 ).rg;", - "texcoord -= vec2( 0.0, 2.0 ) * resolution;", // WebGL port note: Changed sign - "if ( ! ( texcoord.y < end && e.r > 0.8281 && e.g == 0.0 ) ) break;", - "}", + " for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for + " e = texture2D( edgesTex, texcoord, 0.0 ).rg;", + " texcoord -= vec2( 0.0, 2.0 ) * resolution;", // WebGL port note: Changed sign + " if ( ! ( texcoord.y < end && e.r > 0.8281 && e.g == 0.0 ) ) break;", + " }", - "texcoord.y += 0.25 * resolution.y;", // WebGL port note: Changed sign - "texcoord.y += resolution.y;", // WebGL port note: Changed sign - "texcoord.y += 2.0 * resolution.y;", // WebGL port note: Changed sign - "texcoord.y -= resolution.y * SMAASearchLength( searchTex, e.gr, 0.5, 0.5 );", // WebGL port note: Changed sign + " texcoord.y += 0.25 * resolution.y;", // WebGL port note: Changed sign + " texcoord.y += resolution.y;", // WebGL port note: Changed sign + " texcoord.y += 2.0 * resolution.y;", // WebGL port note: Changed sign + " texcoord.y -= resolution.y * SMAASearchLength( searchTex, e.gr, 0.5, 0.5 );", // WebGL port note: Changed sign - "return texcoord.y;", + " return texcoord.y;", "}", "vec2 SMAAArea( sampler2D areaTex, vec2 dist, float e1, float e2, float offset ) {", - // Rounding prevents precision errors of bilinear filtering: - "vec2 texcoord = float( SMAA_AREATEX_MAX_DISTANCE ) * round( 4.0 * vec2( e1, e2 ) ) + dist;", + // Rounding prevents precision errors of bilinear filtering: + " vec2 texcoord = float( SMAA_AREATEX_MAX_DISTANCE ) * round( 4.0 * vec2( e1, e2 ) ) + dist;", - // We do a scale and bias for mapping to texel space: - "texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + ( 0.5 * SMAA_AREATEX_PIXEL_SIZE );", + // We do a scale and bias for mapping to texel space: + " texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + ( 0.5 * SMAA_AREATEX_PIXEL_SIZE );", - // Move to proper place, according to the subpixel offset: - "texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;", + // Move to proper place, according to the subpixel offset: + " texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;", - "return texture2D( areaTex, texcoord, 0.0 ).rg;", + " return texture2D( areaTex, texcoord, 0.0 ).rg;", "}", "vec4 SMAABlendingWeightCalculationPS( vec2 texcoord, vec2 pixcoord, vec4 offset[ 3 ], sampler2D edgesTex, sampler2D areaTex, sampler2D searchTex, ivec4 subsampleIndices ) {", - "vec4 weights = vec4( 0.0, 0.0, 0.0, 0.0 );", + " vec4 weights = vec4( 0.0, 0.0, 0.0, 0.0 );", - "vec2 e = texture2D( edgesTex, texcoord ).rg;", + " vec2 e = texture2D( edgesTex, texcoord ).rg;", - "if ( e.g > 0.0 ) {", // Edge at north - "vec2 d;", + " if ( e.g > 0.0 ) {", // Edge at north + " vec2 d;", - // Find the distance to the left: - "vec2 coords;", - "coords.x = SMAASearchXLeft( edgesTex, searchTex, offset[ 0 ].xy, offset[ 2 ].x );", - "coords.y = offset[ 1 ].y;", // offset[1].y = texcoord.y - 0.25 * resolution.y (@CROSSING_OFFSET) - "d.x = coords.x;", + // Find the distance to the left: + " vec2 coords;", + " coords.x = SMAASearchXLeft( edgesTex, searchTex, offset[ 0 ].xy, offset[ 2 ].x );", + " coords.y = offset[ 1 ].y;", // offset[1].y = texcoord.y - 0.25 * resolution.y (@CROSSING_OFFSET) + " d.x = coords.x;", - // Now fetch the left crossing edges, two at a time using bilinear - // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to - // discern what value each edge has: - "float e1 = texture2D( edgesTex, coords, 0.0 ).r;", + // Now fetch the left crossing edges, two at a time using bilinear + // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to + // discern what value each edge has: + " float e1 = texture2D( edgesTex, coords, 0.0 ).r;", - // Find the distance to the right: - "coords.x = SMAASearchXRight( edgesTex, searchTex, offset[ 0 ].zw, offset[ 2 ].y );", - "d.y = coords.x;", + // Find the distance to the right: + " coords.x = SMAASearchXRight( edgesTex, searchTex, offset[ 0 ].zw, offset[ 2 ].y );", + " d.y = coords.x;", - // We want the distances to be in pixel units (doing this here allow to - // better interleave arithmetic and memory accesses): - "d = d / resolution.x - pixcoord.x;", + // We want the distances to be in pixel units (doing this here allow to + // better interleave arithmetic and memory accesses): + " d = d / resolution.x - pixcoord.x;", - // SMAAArea below needs a sqrt, as the areas texture is compressed - // quadratically: - "vec2 sqrt_d = sqrt( abs( d ) );", + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + " vec2 sqrt_d = sqrt( abs( d ) );", - // Fetch the right crossing edges: - "coords.y -= 1.0 * resolution.y;", // WebGL port note: Added - "float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 1, 0 ) ).r;", + // Fetch the right crossing edges: + " coords.y -= 1.0 * resolution.y;", // WebGL port note: Added + " float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 1, 0 ) ).r;", - // Ok, we know how this pattern looks like, now it is time for getting - // the actual area: - "weights.rg = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.y ) );", - "}", + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + " weights.rg = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.y ) );", + " }", - "if ( e.r > 0.0 ) {", // Edge at west - "vec2 d;", + " if ( e.r > 0.0 ) {", // Edge at west + " vec2 d;", - // Find the distance to the top: - "vec2 coords;", + // Find the distance to the top: + " vec2 coords;", - "coords.y = SMAASearchYUp( edgesTex, searchTex, offset[ 1 ].xy, offset[ 2 ].z );", - "coords.x = offset[ 0 ].x;", // offset[1].x = texcoord.x - 0.25 * resolution.x; - "d.x = coords.y;", + " coords.y = SMAASearchYUp( edgesTex, searchTex, offset[ 1 ].xy, offset[ 2 ].z );", + " coords.x = offset[ 0 ].x;", // offset[1].x = texcoord.x - 0.25 * resolution.x; + " d.x = coords.y;", - // Fetch the top crossing edges: - "float e1 = texture2D( edgesTex, coords, 0.0 ).g;", + // Fetch the top crossing edges: + " float e1 = texture2D( edgesTex, coords, 0.0 ).g;", - // Find the distance to the bottom: - "coords.y = SMAASearchYDown( edgesTex, searchTex, offset[ 1 ].zw, offset[ 2 ].w );", - "d.y = coords.y;", + // Find the distance to the bottom: + " coords.y = SMAASearchYDown( edgesTex, searchTex, offset[ 1 ].zw, offset[ 2 ].w );", + " d.y = coords.y;", - // We want the distances to be in pixel units: - "d = d / resolution.y - pixcoord.y;", + // We want the distances to be in pixel units: + " d = d / resolution.y - pixcoord.y;", - // SMAAArea below needs a sqrt, as the areas texture is compressed - // quadratically: - "vec2 sqrt_d = sqrt( abs( d ) );", + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + " vec2 sqrt_d = sqrt( abs( d ) );", - // Fetch the bottom crossing edges: - "coords.y -= 1.0 * resolution.y;", // WebGL port note: Added - "float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 0, 1 ) ).g;", + // Fetch the bottom crossing edges: + " coords.y -= 1.0 * resolution.y;", // WebGL port note: Added + " float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 0, 1 ) ).g;", - // Get the area for this direction: - "weights.ba = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.x ) );", - "}", + // Get the area for this direction: + " weights.ba = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.x ) );", + " }", - "return weights;", + " return weights;", "}", "void main() {", - "gl_FragColor = SMAABlendingWeightCalculationPS( vUv, vPixcoord, vOffset, tDiffuse, tArea, tSearch, ivec4( 0.0 ) );", + " gl_FragColor = SMAABlendingWeightCalculationPS( vUv, vPixcoord, vOffset, tDiffuse, tArea, tSearch, ivec4( 0.0 ) );", "}" @@ -391,17 +391,17 @@ THREE.SMAABlendShader = { "varying vec4 vOffset[ 2 ];", "void SMAANeighborhoodBlendingVS( vec2 texcoord ) {", - "vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 );", // WebGL port note: Changed sign in W component - "vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 );", // WebGL port note: Changed sign in W component + " vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 );", // WebGL port note: Changed sign in W component + " vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 );", // WebGL port note: Changed sign in W component "}", "void main() {", - "vUv = uv;", + " vUv = uv;", - "SMAANeighborhoodBlendingVS( vUv );", + " SMAANeighborhoodBlendingVS( vUv );", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -417,49 +417,49 @@ THREE.SMAABlendShader = { "varying vec4 vOffset[ 2 ];", "vec4 SMAANeighborhoodBlendingPS( vec2 texcoord, vec4 offset[ 2 ], sampler2D colorTex, sampler2D blendTex ) {", - // Fetch the blending weights for current pixel: - "vec4 a;", - "a.xz = texture2D( blendTex, texcoord ).xz;", - "a.y = texture2D( blendTex, offset[ 1 ].zw ).g;", - "a.w = texture2D( blendTex, offset[ 1 ].xy ).a;", - - // Is there any blending weight with a value greater than 0.0? - "if ( dot(a, vec4( 1.0, 1.0, 1.0, 1.0 )) < 1e-5 ) {", - "return texture2D( colorTex, texcoord, 0.0 );", - "} else {", - // Up to 4 lines can be crossing a pixel (one through each edge). We - // favor blending by choosing the line with the maximum weight for each - // direction: - "vec2 offset;", - "offset.x = a.a > a.b ? a.a : -a.b;", // left vs. right - "offset.y = a.g > a.r ? -a.g : a.r;", // top vs. bottom // WebGL port note: Changed signs - - // Then we go in the direction that has the maximum weight: - "if ( abs( offset.x ) > abs( offset.y )) {", // horizontal vs. vertical - "offset.y = 0.0;", - "} else {", - "offset.x = 0.0;", - "}", - - // Fetch the opposite color and lerp by hand: - "vec4 C = texture2D( colorTex, texcoord, 0.0 );", - "texcoord += sign( offset ) * resolution;", - "vec4 Cop = texture2D( colorTex, texcoord, 0.0 );", - "float s = abs( offset.x ) > abs( offset.y ) ? abs( offset.x ) : abs( offset.y );", - - // WebGL port note: Added gamma correction - "C.xyz = pow(C.xyz, vec3(2.2));", - "Cop.xyz = pow(Cop.xyz, vec3(2.2));", - "vec4 mixed = mix(C, Cop, s);", - "mixed.xyz = pow(mixed.xyz, vec3(1.0 / 2.2));", - - "return mixed;", - "}", + // Fetch the blending weights for current pixel: + " vec4 a;", + " a.xz = texture2D( blendTex, texcoord ).xz;", + " a.y = texture2D( blendTex, offset[ 1 ].zw ).g;", + " a.w = texture2D( blendTex, offset[ 1 ].xy ).a;", + + // Is there any blending weight with a value greater than 0.0? + " if ( dot(a, vec4( 1.0, 1.0, 1.0, 1.0 )) < 1e-5 ) {", + " return texture2D( colorTex, texcoord, 0.0 );", + " } else {", + // Up to 4 lines can be crossing a pixel (one through each edge). We + // favor blending by choosing the line with the maximum weight for each + // direction: + " vec2 offset;", + " offset.x = a.a > a.b ? a.a : -a.b;", // left vs. right + " offset.y = a.g > a.r ? -a.g : a.r;", // top vs. bottom // WebGL port note: Changed signs + + // Then we go in the direction that has the maximum weight: + " if ( abs( offset.x ) > abs( offset.y )) {", // horizontal vs. vertical + " offset.y = 0.0;", + " } else {", + " offset.x = 0.0;", + " }", + + // Fetch the opposite color and lerp by hand: + " vec4 C = texture2D( colorTex, texcoord, 0.0 );", + " texcoord += sign( offset ) * resolution;", + " vec4 Cop = texture2D( colorTex, texcoord, 0.0 );", + " float s = abs( offset.x ) > abs( offset.y ) ? abs( offset.x ) : abs( offset.y );", + + // WebGL port note: Added gamma correction + " C.xyz = pow(C.xyz, vec3(2.2));", + " Cop.xyz = pow(Cop.xyz, vec3(2.2));", + " vec4 mixed = mix(C, Cop, s);", + " mixed.xyz = pow(mixed.xyz, vec3(1.0 / 2.2));", + + " return mixed;", + " }", "}", "void main() {", - "gl_FragColor = SMAANeighborhoodBlendingPS( vUv, vOffset, tColor, tDiffuse );", + " gl_FragColor = SMAANeighborhoodBlendingPS( vUv, vOffset, tColor, tDiffuse );", "}" diff --git a/examples/js/shaders/SepiaShader.js b/examples/js/shaders/SepiaShader.js index 9792d7f70d1d30..6b10eb25897b11 100644 --- a/examples/js/shaders/SepiaShader.js +++ b/examples/js/shaders/SepiaShader.js @@ -21,8 +21,8 @@ THREE.SepiaShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -38,14 +38,14 @@ THREE.SepiaShader = { "void main() {", - "vec4 color = texture2D( tDiffuse, vUv );", - "vec3 c = color.rgb;", + " vec4 color = texture2D( tDiffuse, vUv );", + " vec3 c = color.rgb;", - "color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );", - "color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );", - "color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );", + " color.r = dot( c, vec3( 1.0 - 0.607 * amount, 0.769 * amount, 0.189 * amount ) );", + " color.g = dot( c, vec3( 0.349 * amount, 1.0 - 0.314 * amount, 0.168 * amount ) );", + " color.b = dot( c, vec3( 0.272 * amount, 0.534 * amount, 1.0 - 0.869 * amount ) );", - "gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );", + " gl_FragColor = vec4( min( vec3( 1.0 ), color.rgb ), color.a );", "}" diff --git a/examples/js/shaders/SkinShader.js b/examples/js/shaders/SkinShader.js deleted file mode 100644 index 89758ce7c8aba9..00000000000000 --- a/examples/js/shaders/SkinShader.js +++ /dev/null @@ -1,686 +0,0 @@ -/** - * @author alteredq / http://alteredqualia.com/ - * - */ - -/* ------------------------------------------------------------------------------------------ -// Basic skin shader -// - per-pixel Blinn-Phong diffuse term mixed with half-Lambert wrap-around term (per color component) -// - physically based specular term (Kelemen/Szirmay-Kalos specular reflectance) -// -// - diffuse map -// - bump map -// - specular map -// - point, directional and hemisphere lights (use with "lights: true" material option) -// - fog (use with "fog: true" material option) -// -// ------------------------------------------------------------------------------------------ */ - -THREE.SkinShaderBasic = { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ], - - { - - "enableBump": { value: 0 }, - "enableSpecular": { value: 0 }, - - "tDiffuse": { value: null }, - "tBeckmann": { value: null }, - - "diffuse": { value: new THREE.Color( 0xeeeeee ) }, - "specular": { value: new THREE.Color( 0x111111 ) }, - "opacity": { value: 1 }, - - "uRoughness": { value: 0.15 }, - "uSpecularBrightness": { value: 0.75 }, - - "bumpMap": { value: null }, - "bumpScale": { value: 1 }, - - "specularMap": { value: null }, - - "offsetRepeat": { value: new THREE.Vector4( 0, 0, 1, 1 ) }, - - "uWrapRGB": { value: new THREE.Vector3( 0.75, 0.375, 0.1875 ) } - - } - - ] ), - - vertexShader: [ - - "uniform vec4 offsetRepeat;", - - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "lights_pars_begin" ], - THREE.ShaderChunk[ "fog_pars_vertex" ], - - "void main() {", - - " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - " vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", - - " vViewPosition = -mvPosition.xyz;", - - " vNormal = normalize( normalMatrix * normal );", - - " vUv = uv * offsetRepeat.zw + offsetRepeat.xy;", - - " gl_Position = projectionMatrix * mvPosition;", - - THREE.ShaderChunk[ "fog_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "#define USE_BUMPMAP", - - "uniform bool enableBump;", - "uniform bool enableSpecular;", - - "uniform vec3 diffuse;", - "uniform vec3 specular;", - "uniform float opacity;", - - "uniform float uRoughness;", - "uniform float uSpecularBrightness;", - - "uniform vec3 uWrapRGB;", - - "uniform sampler2D tDiffuse;", - "uniform sampler2D tBeckmann;", - - "uniform sampler2D specularMap;", - - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "packing" ], - THREE.ShaderChunk[ "lights_pars_begin" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "bumpmap_pars_fragment" ], - - // Fresnel term - - "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {", - - " float base = 1.0 - dot( V, H );", - " float exponential = pow( base, 5.0 );", - - " return exponential + F0 * ( 1.0 - exponential );", - - "}", - - // Kelemen/Szirmay-Kalos specular BRDF - - "float KS_Skin_Specular( vec3 N,", // Bumped surface normal - " vec3 L,", // Points to light - " vec3 V,", // Points to eye - " float m,", // Roughness - " float rho_s", // Specular brightness - " ) {", - - " float result = 0.0;", - " float ndotl = dot( N, L );", - - " if( ndotl > 0.0 ) {", - - " vec3 h = L + V;", // Unnormalized half-way vector - " vec3 H = normalize( h );", - - " float ndoth = dot( N, H );", - - " float PH = pow( 2.0 * texture2D( tBeckmann, vec2( ndoth, m ) ).x, 10.0 );", - - " float F = fresnelReflectance( H, V, 0.028 );", - " float frSpec = max( PH * F / dot( h, h ), 0.0 );", - - " result = ndotl * rho_s * frSpec;", // BRDF * dot(N,L) * rho_s - - " }", - - " return result;", - - "}", - - "void main() {", - - " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does - " vec4 diffuseColor = vec4( diffuse, opacity );", - - " vec4 colDiffuse = texture2D( tDiffuse, vUv );", - " colDiffuse.rgb *= colDiffuse.rgb;", - - " diffuseColor = diffuseColor * colDiffuse;", - - " vec3 normal = normalize( vNormal );", - " vec3 viewerDirection = normalize( vViewPosition );", - - " float specularStrength;", - - " if ( enableSpecular ) {", - - " vec4 texelSpecular = texture2D( specularMap, vUv );", - " specularStrength = texelSpecular.r;", - - " } else {", - - " specularStrength = 1.0;", - - " }", - - " #ifdef USE_BUMPMAP", - - " if ( enableBump ) normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );", - - " #endif", - - // point lights - - " vec3 totalSpecularLight = vec3( 0.0 );", - " vec3 totalDiffuseLight = vec3( 0.0 );", - - " #if NUM_POINT_LIGHTS > 0", - - " for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {", - - " vec3 lVector = pointLights[ i ].position + vViewPosition.xyz;", - - " float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", - - " lVector = normalize( lVector );", - - " float pointDiffuseWeightFull = max( dot( normal, lVector ), 0.0 );", - " float pointDiffuseWeightHalf = max( 0.5 * dot( normal, lVector ) + 0.5, 0.0 );", - " vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), uWrapRGB );", - - " float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );", - - " totalDiffuseLight += pointLight[ i ].color * ( pointDiffuseWeight * attenuation );", - " totalSpecularLight += pointLight[ i ].color * specular * ( pointSpecularWeight * specularStrength * attenuation );", - - " }", - - " #endif", - - // directional lights - - " #if NUM_DIR_LIGHTS > 0", - - " for( int i = 0; i < NUM_DIR_LIGHTS; i++ ) {", - - " vec3 dirVector = directionalLights[ i ].direction;", - - " float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );", - " float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );", - " vec3 dirDiffuseWeight = mix( vec3 ( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), uWrapRGB );", - - " float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );", - - " totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;", - " totalSpecularLight += directionalLights[ i ].color * ( dirSpecularWeight * specularStrength );", - - " }", - - " #endif", - - // hemisphere lights - - " #if NUM_HEMI_LIGHTS > 0", - - " for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {", - - " vec3 lVector = hemisphereLightDirection[ i ];", - - " float dotProduct = dot( normal, lVector );", - " float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - - " totalDiffuseLight += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", - - // specular (sky light) - - " float hemiSpecularWeight = 0.0;", - " hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewerDirection, uRoughness, uSpecularBrightness );", - - // specular (ground light) - - " vec3 lVectorGround = -lVector;", - " hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewerDirection, uRoughness, uSpecularBrightness );", - - " vec3 hemiSpecularColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );", - - " totalSpecularLight += hemiSpecularColor * specular * ( hemiSpecularWeight * specularStrength );", - - " }", - - " #endif", - - " outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;", - - " gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects - - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join( "\n" ) - -}; - -/* ------------------------------------------------------------------------------------------ -// Skin shader -// - Blinn-Phong diffuse term (using normal + diffuse maps) -// - subsurface scattering approximation by four blur layers -// - physically based specular term (Kelemen/Szirmay-Kalos specular reflectance) -// -// - point and directional lights (use with "lights: true" material option) -// -// - based on Nvidia Advanced Skin Rendering GDC 2007 presentation -// and GPU Gems 3 Chapter 14. Advanced Techniques for Realistic Real-Time Skin Rendering -// -// http://developer.download.nvidia.com/presentations/2007/gdc/Advanced_Skin.pdf -// http://http.developer.nvidia.com/GPUGems3/gpugems3_ch14.html -// ------------------------------------------------------------------------------------------ */ - -THREE.SkinShaderAdvanced = { - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ], - - { - "passID": { value: 0 }, - - "tDiffuse": { value: null }, - "tNormal": { value: null }, - - "tBlur1": { value: null }, - "tBlur2": { value: null }, - "tBlur3": { value: null }, - "tBlur4": { value: null }, - - "tBeckmann": { value: null }, - - "uNormalScale": { value: 1.0 }, - - "diffuse": { value: new THREE.Color( 0xeeeeee ) }, - "specular": { value: new THREE.Color( 0x111111 ) }, - "opacity": { value: 1 }, - - "uRoughness": { value: 0.15 }, - "uSpecularBrightness": { value: 0.75 } - - } - - ] ), - - vertexShader: [ - - "#ifdef VERTEX_TEXTURES", - - " uniform sampler2D tDisplacement;", - " uniform float uDisplacementScale;", - " uniform float uDisplacementBias;", - - "#endif", - - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "fog_pars_vertex" ], - - "void main() {", - - " vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", - - " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - - " vViewPosition = -mvPosition.xyz;", - - " vNormal = normalize( normalMatrix * normal );", - - " vUv = uv;", - - // displacement mapping - - " #ifdef VERTEX_TEXTURES", - - " vec3 dv = texture2D( tDisplacement, uv ).xyz;", - " float df = uDisplacementScale * dv.x + uDisplacementBias;", - " vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;", - " gl_Position = projectionMatrix * displacedPosition;", - - " #else", - - " gl_Position = projectionMatrix * mvPosition;", - - " #endif", - - THREE.ShaderChunk[ "fog_vertex" ], - - "}", - - - ].join( "\n" ), - - vertexShaderUV: [ - - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "common" ], - - "void main() {", - - " vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", - - " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - - " vViewPosition = -mvPosition.xyz;", - - " vNormal = normalize( normalMatrix * normal );", - - " vUv = uv;", - - " gl_Position = vec4( uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0, 0.0, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform vec3 specular;", - "uniform float opacity;", - - "uniform float uRoughness;", - "uniform float uSpecularBrightness;", - - "uniform int passID;", - - "uniform sampler2D tDiffuse;", - "uniform sampler2D tNormal;", - - "uniform sampler2D tBlur1;", - "uniform sampler2D tBlur2;", - "uniform sampler2D tBlur3;", - "uniform sampler2D tBlur4;", - - "uniform sampler2D tBeckmann;", - - "uniform float uNormalScale;", - - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "lights_pars_begin" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - - "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {", - - " float base = 1.0 - dot( V, H );", - " float exponential = pow( base, 5.0 );", - - " return exponential + F0 * ( 1.0 - exponential );", - - "}", - - // Kelemen/Szirmay-Kalos specular BRDF - - "float KS_Skin_Specular( vec3 N,", // Bumped surface normal - " vec3 L,", // Points to light - " vec3 V,", // Points to eye - " float m,", // Roughness - " float rho_s", // Specular brightness - " ) {", - - " float result = 0.0;", - " float ndotl = dot( N, L );", - - " if( ndotl > 0.0 ) {", - - " vec3 h = L + V;", // Unnormalized half-way vector - " vec3 H = normalize( h );", - - " float ndoth = dot( N, H );", - - " float PH = pow( 2.0 * texture2D( tBeckmann, vec2( ndoth, m ) ).x, 10.0 );", - " float F = fresnelReflectance( H, V, 0.028 );", - " float frSpec = max( PH * F / dot( h, h ), 0.0 );", - - " result = ndotl * rho_s * frSpec;", // BRDF * dot(N,L) * rho_s - - " }", - - " return result;", - - "}", - - "void main() {", - - " vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does - " vec4 diffuseColor = vec4( diffuse, opacity );", - - " vec4 mSpecular = vec4( specular, opacity );", - - " vec4 colDiffuse = texture2D( tDiffuse, vUv );", - " colDiffuse *= colDiffuse;", - - " diffuseColor *= colDiffuse;", - - // normal mapping - - " vec4 posAndU = vec4( -vViewPosition, vUv.x );", - " vec4 posAndU_dx = dFdx( posAndU ), posAndU_dy = dFdy( posAndU );", - " vec3 tangent = posAndU_dx.w * posAndU_dx.xyz + posAndU_dy.w * posAndU_dy.xyz;", - " vec3 normal = normalize( vNormal );", - " vec3 binormal = normalize( cross( tangent, normal ) );", - " tangent = cross( normal, binormal );", // no normalization required - " mat3 tsb = mat3( tangent, binormal, normal );", - - " vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;", - " normalTex.xy *= uNormalScale;", - " normalTex = normalize( normalTex );", - - " vec3 finalNormal = tsb * normalTex;", - " normal = normalize( finalNormal );", - - " vec3 viewerDirection = normalize( vViewPosition );", - - // point lights - - " vec3 totalDiffuseLight = vec3( 0.0 );", - " vec3 totalSpecularLight = vec3( 0.0 );", - - " #if NUM_POINT_LIGHTS > 0", - - " for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {", - - " vec3 pointVector = normalize( pointLights[ i ].direction );", - " float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", - - " float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );", - - " totalDiffuseLight += pointLightColor[ i ] * ( pointDiffuseWeight * attenuation );", - - " if ( passID == 1 ) {", - - " float pointSpecularWeight = KS_Skin_Specular( normal, pointVector, viewerDirection, uRoughness, uSpecularBrightness );", - - " totalSpecularLight += pointLightColor[ i ] * mSpecular.xyz * ( pointSpecularWeight * attenuation );", - - " }", - - " }", - - " #endif", - - // directional lights - - " #if NUM_DIR_LIGHTS > 0", - - " for( int i = 0; i < NUM_DIR_LIGHTS; i++ ) {", - - " vec3 dirVector = directionalLights[ i ].direction;", - - " float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", - - - " totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;", - - " if ( passID == 1 ) {", - - " float dirSpecularWeight = KS_Skin_Specular( normal, dirVector, viewerDirection, uRoughness, uSpecularBrightness );", - - " totalSpecularLight += directionalLights[ i ].color * mSpecular.xyz * dirSpecularWeight;", - - " }", - - " }", - - " #endif", - - " outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalSpecularLight );", - - " if ( passID == 0 ) {", - - " outgoingLight = sqrt( outgoingLight );", - - " } else if ( passID == 1 ) {", - - //"#define VERSION1", - - " #ifdef VERSION1", - - " vec3 nonblurColor = sqrt(outgoingLight );", - - " #else", - - " vec3 nonblurColor = outgoingLight;", - - " #endif", - - " vec3 blur1Color = texture2D( tBlur1, vUv ).xyz;", - " vec3 blur2Color = texture2D( tBlur2, vUv ).xyz;", - " vec3 blur3Color = texture2D( tBlur3, vUv ).xyz;", - " vec3 blur4Color = texture2D( tBlur4, vUv ).xyz;", - - - //"gl_FragColor = vec4( blur1Color, gl_FragColor.w );", - - //"gl_FragColor = vec4( vec3( 0.22, 0.5, 0.7 ) * nonblurColor + vec3( 0.2, 0.5, 0.3 ) * blur1Color + vec3( 0.58, 0.0, 0.0 ) * blur2Color, gl_FragColor.w );", - - //"gl_FragColor = vec4( vec3( 0.25, 0.6, 0.8 ) * nonblurColor + vec3( 0.15, 0.25, 0.2 ) * blur1Color + vec3( 0.15, 0.15, 0.0 ) * blur2Color + vec3( 0.45, 0.0, 0.0 ) * blur3Color, gl_FragColor.w );", - - " outgoingLight = vec3( vec3( 0.22, 0.437, 0.635 ) * nonblurColor + ", - " vec3( 0.101, 0.355, 0.365 ) * blur1Color + ", - " vec3( 0.119, 0.208, 0.0 ) * blur2Color + ", - " vec3( 0.114, 0.0, 0.0 ) * blur3Color + ", - " vec3( 0.444, 0.0, 0.0 ) * blur4Color );", - - " outgoingLight *= sqrt( colDiffuse.xyz );", - - " outgoingLight += ambientLightColor * diffuse * colDiffuse.xyz + totalSpecularLight;", - - " #ifndef VERSION1", - - " outgoingLight = sqrt( outgoingLight );", - - " #endif", - - " }", - - " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects - - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join( "\n" ) - -}; - -/* ------------------------------------------------------------------------------------------ -// Beckmann distribution function -// - to be used in specular term of skin shader -// - render a screen-aligned quad to precompute a 512 x 512 texture -// -// - from http://developer.nvidia.com/node/171 - ------------------------------------------------------------------------------------------ */ - -THREE.SkinShaderBeckmann = { - - uniforms: {}, - - vertexShader: [ - - "varying vec2 vUv;", - - "void main() {", - - " vUv = uv;", - " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "varying vec2 vUv;", - - "float PHBeckmann( float ndoth, float m ) {", - - " float alpha = acos( ndoth );", - " float ta = tan( alpha );", - - " float val = 1.0 / ( m * m * pow( ndoth, 4.0 ) ) * exp( -( ta * ta ) / ( m * m ) );", - " return val;", - - "}", - - "float KSTextureCompute( vec2 tex ) {", - - // Scale the value to fit within [0,1] invert upon lookup. - - " return 0.5 * pow( PHBeckmann( tex.x, tex.y ), 0.1 );", - - "}", - - "void main() {", - - " float x = KSTextureCompute( vUv );", - - " gl_FragColor = vec4( x, x, x, 1.0 );", - - "}" - - ].join( "\n" ) - -}; diff --git a/examples/js/shaders/SobelOperatorShader.js b/examples/js/shaders/SobelOperatorShader.js index 7a5284140a466a..f33b634be3c036 100644 --- a/examples/js/shaders/SobelOperatorShader.js +++ b/examples/js/shaders/SobelOperatorShader.js @@ -22,9 +22,9 @@ THREE.SobelOperatorShader = { "void main() {", - "vUv = uv;", + " vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -38,50 +38,50 @@ THREE.SobelOperatorShader = { "void main() {", - "vec2 texel = vec2( 1.0 / resolution.x, 1.0 / resolution.y );", + " vec2 texel = vec2( 1.0 / resolution.x, 1.0 / resolution.y );", - // kernel definition (in glsl matrices are filled in column-major order) + // kernel definition (in glsl matrices are filled in column-major order) - "const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 );", // x direction kernel - "const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 );", // y direction kernel + " const mat3 Gx = mat3( -1, -2, -1, 0, 0, 0, 1, 2, 1 );", // x direction kernel + " const mat3 Gy = mat3( -1, 0, 1, -2, 0, 2, -1, 0, 1 );", // y direction kernel - // fetch the 3x3 neighbourhood of a fragment + // fetch the 3x3 neighbourhood of a fragment - // first column + // first column - "float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -1, -1 ) ).r;", - "float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -1, 0 ) ).r;", - "float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -1, 1 ) ).r;", + " float tx0y0 = texture2D( tDiffuse, vUv + texel * vec2( -1, -1 ) ).r;", + " float tx0y1 = texture2D( tDiffuse, vUv + texel * vec2( -1, 0 ) ).r;", + " float tx0y2 = texture2D( tDiffuse, vUv + texel * vec2( -1, 1 ) ).r;", - // second column + // second column - "float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2( 0, -1 ) ).r;", - "float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2( 0, 0 ) ).r;", - "float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2( 0, 1 ) ).r;", + " float tx1y0 = texture2D( tDiffuse, vUv + texel * vec2( 0, -1 ) ).r;", + " float tx1y1 = texture2D( tDiffuse, vUv + texel * vec2( 0, 0 ) ).r;", + " float tx1y2 = texture2D( tDiffuse, vUv + texel * vec2( 0, 1 ) ).r;", - // third column + // third column - "float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2( 1, -1 ) ).r;", - "float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2( 1, 0 ) ).r;", - "float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2( 1, 1 ) ).r;", + " float tx2y0 = texture2D( tDiffuse, vUv + texel * vec2( 1, -1 ) ).r;", + " float tx2y1 = texture2D( tDiffuse, vUv + texel * vec2( 1, 0 ) ).r;", + " float tx2y2 = texture2D( tDiffuse, vUv + texel * vec2( 1, 1 ) ).r;", - // gradient value in x direction + // gradient value in x direction - "float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 + ", - "Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 + ", - "Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2; ", + " float valueGx = Gx[0][0] * tx0y0 + Gx[1][0] * tx1y0 + Gx[2][0] * tx2y0 + ", + " Gx[0][1] * tx0y1 + Gx[1][1] * tx1y1 + Gx[2][1] * tx2y1 + ", + " Gx[0][2] * tx0y2 + Gx[1][2] * tx1y2 + Gx[2][2] * tx2y2; ", - // gradient value in y direction + // gradient value in y direction - "float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 + ", - "Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 + ", - "Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2; ", + " float valueGy = Gy[0][0] * tx0y0 + Gy[1][0] * tx1y0 + Gy[2][0] * tx2y0 + ", + " Gy[0][1] * tx0y1 + Gy[1][1] * tx1y1 + Gy[2][1] * tx2y1 + ", + " Gy[0][2] * tx0y2 + Gy[1][2] * tx1y2 + Gy[2][2] * tx2y2; ", - // magnitute of the total gradient + // magnitute of the total gradient - "float G = sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );", + " float G = sqrt( ( valueGx * valueGx ) + ( valueGy * valueGy ) );", - "gl_FragColor = vec4( vec3( G ), 1 );", + " gl_FragColor = vec4( vec3( G ), 1 );", "}" diff --git a/examples/js/shaders/TechnicolorShader.js b/examples/js/shaders/TechnicolorShader.js index ba1c8e7136a5d8..36b6548972f01b 100644 --- a/examples/js/shaders/TechnicolorShader.js +++ b/examples/js/shaders/TechnicolorShader.js @@ -21,8 +21,8 @@ THREE.TechnicolorShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -35,10 +35,10 @@ THREE.TechnicolorShader = { "void main() {", - "vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );", - "vec4 newTex = vec4(tex.r, (tex.g + tex.b) * .5, (tex.g + tex.b) * .5, 1.0);", + " vec4 tex = texture2D( tDiffuse, vec2( vUv.x, vUv.y ) );", + " vec4 newTex = vec4(tex.r, (tex.g + tex.b) * .5, (tex.g + tex.b) * .5, 1.0);", - "gl_FragColor = newTex;", + " gl_FragColor = newTex;", "}" diff --git a/examples/js/shaders/TerrainShader.js b/examples/js/shaders/TerrainShader.js deleted file mode 100644 index bc1e2e8857f6d0..00000000000000 --- a/examples/js/shaders/TerrainShader.js +++ /dev/null @@ -1,320 +0,0 @@ -/** - * @author alteredq / http://alteredqualia.com/ - * - */ - -THREE.TerrainShader = { - - /* ------------------------------------------------------------------------- - // Dynamic terrain shader - // - Blinn-Phong - // - height + normal + diffuse1 + diffuse2 + specular + detail maps - // - point, directional and hemisphere lights (use with "lights: true" material option) - // - shadow maps receiving - ------------------------------------------------------------------------- */ - - uniforms: THREE.UniformsUtils.merge( [ - - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "lights" ], - - { - - "enableDiffuse1": { value: 0 }, - "enableDiffuse2": { value: 0 }, - "enableSpecular": { value: 0 }, - "enableReflection": { value: 0 }, - - "tDiffuse1": { value: null }, - "tDiffuse2": { value: null }, - "tDetail": { value: null }, - "tNormal": { value: null }, - "tSpecular": { value: null }, - "tDisplacement": { value: null }, - - "uNormalScale": { value: 1.0 }, - - "uDisplacementBias": { value: 0.0 }, - "uDisplacementScale": { value: 1.0 }, - - "diffuse": { value: new THREE.Color( 0xeeeeee ) }, - "specular": { value: new THREE.Color( 0x111111 ) }, - "shininess": { value: 30 }, - "opacity": { value: 1 }, - - "uRepeatBase": { value: new THREE.Vector2( 1, 1 ) }, - "uRepeatOverlay": { value: new THREE.Vector2( 1, 1 ) }, - - "uOffset": { value: new THREE.Vector2( 0, 0 ) } - - } - - ] ), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform vec3 specular;", - "uniform float shininess;", - "uniform float opacity;", - - "uniform bool enableDiffuse1;", - "uniform bool enableDiffuse2;", - "uniform bool enableSpecular;", - - "uniform sampler2D tDiffuse1;", - "uniform sampler2D tDiffuse2;", - "uniform sampler2D tDetail;", - "uniform sampler2D tNormal;", - "uniform sampler2D tSpecular;", - "uniform sampler2D tDisplacement;", - - "uniform float uNormalScale;", - - "uniform vec2 uRepeatOverlay;", - "uniform vec2 uRepeatBase;", - - "uniform vec2 uOffset;", - - "varying vec3 vTangent;", - "varying vec3 vBinormal;", - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights_pars_begin" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - - "float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) {", - "if ( decayExponent > 0.0 ) {", - "return pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );", - "}", - "return 1.0;", - "}", - - "void main() {", - - "vec3 outgoingLight = vec3( 0.0 );", // outgoing light does not have an alpha, the surface does - "vec4 diffuseColor = vec4( diffuse, opacity );", - - "vec3 specularTex = vec3( 1.0 );", - - "vec2 uvOverlay = uRepeatOverlay * vUv + uOffset;", - "vec2 uvBase = uRepeatBase * vUv;", - - "vec3 normalTex = texture2D( tDetail, uvOverlay ).xyz * 2.0 - 1.0;", - "normalTex.xy *= uNormalScale;", - "normalTex = normalize( normalTex );", - - "if( enableDiffuse1 && enableDiffuse2 ) {", - - "vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );", - "vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );", - - "colDiffuse1 = GammaToLinear( colDiffuse1, float( GAMMA_FACTOR ) );", - "colDiffuse2 = GammaToLinear( colDiffuse2, float( GAMMA_FACTOR ) );", - - "diffuseColor *= mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );", - - " } else if( enableDiffuse1 ) {", - - "diffuseColor *= texture2D( tDiffuse1, uvOverlay );", - - "} else if( enableDiffuse2 ) {", - - "diffuseColor *= texture2D( tDiffuse2, uvOverlay );", - - "}", - - "if( enableSpecular )", - "specularTex = texture2D( tSpecular, uvOverlay ).xyz;", - - "mat3 tsb = mat3( vTangent, vBinormal, vNormal );", - "vec3 finalNormal = tsb * normalTex;", - - "vec3 normal = normalize( finalNormal );", - "vec3 viewPosition = normalize( vViewPosition );", - - "vec3 totalDiffuseLight = vec3( 0.0 );", - "vec3 totalSpecularLight = vec3( 0.0 );", - - // point lights - - "#if NUM_POINT_LIGHTS > 0", - - "for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {", - - "vec3 lVector = pointLights[ i ].position + vViewPosition.xyz;", - - "float attenuation = calcLightAttenuation( length( lVector ), pointLights[ i ].distance, pointLights[ i ].decay );", - - "lVector = normalize( lVector );", - - "vec3 pointHalfVector = normalize( lVector + viewPosition );", - - "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );", - "float pointDiffuseWeight = max( dot( normal, lVector ), 0.0 );", - - "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, shininess ), 0.0 );", - - "totalDiffuseLight += attenuation * pointLights[ i ].color * pointDiffuseWeight;", - "totalSpecularLight += attenuation * pointLights[ i ].color * specular * pointSpecularWeight * pointDiffuseWeight;", - - "}", - - "#endif", - - // directional lights - - "#if NUM_DIR_LIGHTS > 0", - - "vec3 dirDiffuse = vec3( 0.0 );", - "vec3 dirSpecular = vec3( 0.0 );", - - "for( int i = 0; i < NUM_DIR_LIGHTS; i++ ) {", - - "vec3 dirVector = directionalLights[ i ].direction;", - "vec3 dirHalfVector = normalize( dirVector + viewPosition );", - - "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );", - "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", - - "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, shininess ), 0.0 );", - - "totalDiffuseLight += directionalLights[ i ].color * dirDiffuseWeight;", - "totalSpecularLight += directionalLights[ i ].color * specular * dirSpecularWeight * dirDiffuseWeight;", - - "}", - - "#endif", - - // hemisphere lights - - "#if NUM_HEMI_LIGHTS > 0", - - "vec3 hemiDiffuse = vec3( 0.0 );", - "vec3 hemiSpecular = vec3( 0.0 );", - - "for( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {", - - "vec3 lVector = hemisphereLightDirection[ i ];", - - // diffuse - - "float dotProduct = dot( normal, lVector );", - "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;", - - "totalDiffuseLight += mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight );", - - // specular (sky light) - - "float hemiSpecularWeight = 0.0;", - - "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );", - "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;", - "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );", - - // specular (ground light) - - "vec3 lVectorGround = -lVector;", - - "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );", - "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;", - "hemiSpecularWeight += specularTex.r * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );", - - "totalSpecularLight += specular * mix( hemisphereLights[ i ].groundColor, hemisphereLights[ i ].skyColor, hemiDiffuseWeight ) * hemiSpecularWeight * hemiDiffuseWeight;", - - "}", - - "#endif", - - "outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );", - - "gl_FragColor = vec4( outgoingLight, diffuseColor.a );", // TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects - - THREE.ShaderChunk[ "fog_fragment" ], - - "}" - - ].join( "\n" ), - - vertexShader: [ - - "attribute vec4 tangent;", - - "uniform vec2 uRepeatBase;", - - "uniform sampler2D tNormal;", - - "#ifdef VERTEX_TEXTURES", - - "uniform sampler2D tDisplacement;", - "uniform float uDisplacementScale;", - "uniform float uDisplacementBias;", - - "#endif", - - "varying vec3 vTangent;", - "varying vec3 vBinormal;", - "varying vec3 vNormal;", - "varying vec2 vUv;", - - "varying vec3 vViewPosition;", - - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "fog_pars_vertex" ], - - "void main() {", - - "vNormal = normalize( normalMatrix * normal );", - - // tangent and binormal vectors - - "vTangent = normalize( normalMatrix * tangent.xyz );", - - "vBinormal = cross( vNormal, vTangent ) * tangent.w;", - "vBinormal = normalize( vBinormal );", - - // texture coordinates - - "vUv = uv;", - - "vec2 uvBase = uv * uRepeatBase;", - - // displacement mapping - - "#ifdef VERTEX_TEXTURES", - - "vec3 dv = texture2D( tDisplacement, uvBase ).xyz;", - "float df = uDisplacementScale * dv.x + uDisplacementBias;", - "vec3 displacedPosition = normal * df + position;", - - "vec4 worldPosition = modelMatrix * vec4( displacedPosition, 1.0 );", - "vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );", - - "#else", - - "vec4 worldPosition = modelMatrix * vec4( position, 1.0 );", - "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - - "#endif", - - "gl_Position = projectionMatrix * mvPosition;", - - "vViewPosition = -mvPosition.xyz;", - - "vec3 normalTex = texture2D( tNormal, uvBase ).xyz * 2.0 - 1.0;", - "vNormal = normalMatrix * normalTex;", - - THREE.ShaderChunk[ "shadowmap_vertex" ], - THREE.ShaderChunk[ "fog_vertex" ], - - "}" - - ].join( "\n" ) - -}; diff --git a/examples/js/shaders/ToneMapShader.js b/examples/js/shaders/ToneMapShader.js index 80916a28c2f0ad..6094cb69815842 100644 --- a/examples/js/shaders/ToneMapShader.js +++ b/examples/js/shaders/ToneMapShader.js @@ -22,8 +22,8 @@ THREE.ToneMapShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -41,34 +41,34 @@ THREE.ToneMapShader = { "uniform float minLuminance;", "uniform float maxLuminance;", "#ifdef ADAPTED_LUMINANCE", - "uniform sampler2D luminanceMap;", + " uniform sampler2D luminanceMap;", "#else", - "uniform float averageLuminance;", + " uniform float averageLuminance;", "#endif", "vec3 ToneMap( vec3 vColor ) {", - "#ifdef ADAPTED_LUMINANCE", - // Get the calculated average luminance - "float fLumAvg = texture2D(luminanceMap, vec2(0.5, 0.5)).r;", - "#else", - "float fLumAvg = averageLuminance;", - "#endif", + " #ifdef ADAPTED_LUMINANCE", + // Get the calculated average luminance + " float fLumAvg = texture2D(luminanceMap, vec2(0.5, 0.5)).r;", + " #else", + " float fLumAvg = averageLuminance;", + " #endif", - // Calculate the luminance of the current pixel - "float fLumPixel = linearToRelativeLuminance( vColor );", + // Calculate the luminance of the current pixel + " float fLumPixel = linearToRelativeLuminance( vColor );", - // Apply the modified operator (Eq. 4) - "float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg );", + // Apply the modified operator (Eq. 4) + " float fLumScaled = (fLumPixel * middleGrey) / max( minLuminance, fLumAvg );", - "float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (maxLuminance * maxLuminance)))) / (1.0 + fLumScaled);", - "return fLumCompressed * vColor;", + " float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (maxLuminance * maxLuminance)))) / (1.0 + fLumScaled);", + " return fLumCompressed * vColor;", "}", "void main() {", - "vec4 texel = texture2D( tDiffuse, vUv );", + " vec4 texel = texture2D( tDiffuse, vUv );", - "gl_FragColor = vec4( ToneMap( texel.xyz ), texel.w );", + " gl_FragColor = vec4( ToneMap( texel.xyz ), texel.w );", "}" diff --git a/examples/js/shaders/TranslucentShader.js b/examples/js/shaders/TranslucentShader.js index d3839290aeb5ef..d2ee7416d40707 100644 --- a/examples/js/shaders/TranslucentShader.js +++ b/examples/js/shaders/TranslucentShader.js @@ -127,7 +127,7 @@ THREE.TranslucentShader = { " PointLight pointLight;", - " #pragma unroll_loop", + " #pragma unroll_loop_start", " for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {", " pointLight = pointLights[ i ];", " getPointDirectLightIrradiance( pointLight, geometry, directLight );", @@ -142,6 +142,7 @@ THREE.TranslucentShader = { " RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);", " #endif", " }", + " #pragma unroll_loop_end", " #endif", @@ -149,7 +150,7 @@ THREE.TranslucentShader = { " DirectionalLight directionalLight;", - " #pragma unroll_loop", + " #pragma unroll_loop_start", " for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {", " directionalLight = directionalLights[ i ];", " getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );", @@ -164,6 +165,7 @@ THREE.TranslucentShader = { " RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);", " #endif", " }", + " #pragma unroll_loop_end", " #endif", @@ -173,12 +175,13 @@ THREE.TranslucentShader = { " #if ( NUM_HEMI_LIGHTS > 0 )", - " #pragma unroll_loop", + " #pragma unroll_loop_start", " for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {", " irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );", " }", + " #pragma unroll_loop_end", " #endif", @@ -187,7 +190,7 @@ THREE.TranslucentShader = { " #if defined( RE_IndirectSpecular )", " vec3 radiance = vec3( 0.0 );", - " vec3 clearCoatRadiance = vec3( 0.0 );", + " vec3 clearcoatRadiance = vec3( 0.0 );", " #endif", THREE.ShaderChunk[ "lights_fragment_end" ], diff --git a/examples/js/shaders/TriangleBlurShader.js b/examples/js/shaders/TriangleBlurShader.js index b61244911d24b1..bd5341af6522b7 100644 --- a/examples/js/shaders/TriangleBlurShader.js +++ b/examples/js/shaders/TriangleBlurShader.js @@ -25,8 +25,8 @@ THREE.TriangleBlurShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -45,25 +45,25 @@ THREE.TriangleBlurShader = { "void main() {", - "vec4 color = vec4( 0.0 );", + " vec4 color = vec4( 0.0 );", - "float total = 0.0;", + " float total = 0.0;", - // randomize the lookup values to hide the fixed number of samples + // randomize the lookup values to hide the fixed number of samples - "float offset = rand( vUv );", + " float offset = rand( vUv );", - "for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {", + " for ( float t = -ITERATIONS; t <= ITERATIONS; t ++ ) {", - "float percent = ( t + offset - 0.5 ) / ITERATIONS;", - "float weight = 1.0 - abs( percent );", + " float percent = ( t + offset - 0.5 ) / ITERATIONS;", + " float weight = 1.0 - abs( percent );", - "color += texture2D( texture, vUv + delta * percent ) * weight;", - "total += weight;", + " color += texture2D( texture, vUv + delta * percent ) * weight;", + " total += weight;", - "}", + " }", - "gl_FragColor = color / total;", + " gl_FragColor = color / total;", "}" diff --git a/examples/js/shaders/UnpackDepthRGBAShader.js b/examples/js/shaders/UnpackDepthRGBAShader.js index 6a9c774ca70bc6..6d91bc7279a203 100644 --- a/examples/js/shaders/UnpackDepthRGBAShader.js +++ b/examples/js/shaders/UnpackDepthRGBAShader.js @@ -20,8 +20,8 @@ THREE.UnpackDepthRGBAShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -39,8 +39,8 @@ THREE.UnpackDepthRGBAShader = { "void main() {", - "float depth = 1.0 - unpackRGBAToDepth( texture2D( tDiffuse, vUv ) );", - "gl_FragColor = vec4( vec3( depth ), opacity );", + " float depth = 1.0 - unpackRGBAToDepth( texture2D( tDiffuse, vUv ) );", + " gl_FragColor = vec4( vec3( depth ), opacity );", "}" diff --git a/examples/js/shaders/VerticalBlurShader.js b/examples/js/shaders/VerticalBlurShader.js index 34f49a53380462..7fdaf267eca82e 100644 --- a/examples/js/shaders/VerticalBlurShader.js +++ b/examples/js/shaders/VerticalBlurShader.js @@ -25,8 +25,8 @@ THREE.VerticalBlurShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -41,19 +41,19 @@ THREE.VerticalBlurShader = { "void main() {", - "vec4 sum = vec4( 0.0 );", + " vec4 sum = vec4( 0.0 );", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;", - "gl_FragColor = sum;", + " gl_FragColor = sum;", "}" diff --git a/examples/js/shaders/VerticalTiltShiftShader.js b/examples/js/shaders/VerticalTiltShiftShader.js index a6443505cab97c..ff56d4fc0cc4dc 100644 --- a/examples/js/shaders/VerticalTiltShiftShader.js +++ b/examples/js/shaders/VerticalTiltShiftShader.js @@ -25,8 +25,8 @@ THREE.VerticalTiltShiftShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -42,21 +42,21 @@ THREE.VerticalTiltShiftShader = { "void main() {", - "vec4 sum = vec4( 0.0 );", + " vec4 sum = vec4( 0.0 );", - "float vv = v * abs( r - vUv.y );", + " float vv = v * abs( r - vUv.y );", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;", - "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;", + " sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;", - "gl_FragColor = sum;", + " gl_FragColor = sum;", "}" diff --git a/examples/js/shaders/VignetteShader.js b/examples/js/shaders/VignetteShader.js index 8547fa52a389a8..739d86bdb7ccca 100644 --- a/examples/js/shaders/VignetteShader.js +++ b/examples/js/shaders/VignetteShader.js @@ -22,8 +22,8 @@ THREE.VignetteShader = { "void main() {", - "vUv = uv;", - "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + " vUv = uv;", + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}" @@ -40,21 +40,21 @@ THREE.VignetteShader = { "void main() {", - // Eskil's vignette + // Eskil's vignette - "vec4 texel = texture2D( tDiffuse, vUv );", - "vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );", - "gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );", + " vec4 texel = texture2D( tDiffuse, vUv );", + " vec2 uv = ( vUv - vec2( 0.5 ) ) * vec2( offset );", + " gl_FragColor = vec4( mix( texel.rgb, vec3( 1.0 - darkness ), dot( uv, uv ) ), texel.a );", - /* - // alternative version from glfx.js - // this one makes more "dusty" look (as opposed to "burned") + /* + // alternative version from glfx.js + // this one makes more "dusty" look (as opposed to "burned") - "vec4 color = texture2D( tDiffuse, vUv );", - "float dist = distance( vUv, vec2( 0.5 ) );", - "color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );", - "gl_FragColor = color;", - */ + " vec4 color = texture2D( tDiffuse, vUv );", + " float dist = distance( vUv, vec2( 0.5 ) );", + " color.rgb *= smoothstep( 0.8, offset * 0.799, dist *( darkness + offset ) );", + " gl_FragColor = color;", + */ "}" diff --git a/examples/js/shaders/VolumeShader.js b/examples/js/shaders/VolumeShader.js index f5b2a4582a94cf..675d869845eb87 100644 --- a/examples/js/shaders/VolumeShader.js +++ b/examples/js/shaders/VolumeShader.js @@ -8,317 +8,317 @@ THREE.VolumeRenderShader1 = { uniforms: { - "u_size": { value: new THREE.Vector3( 1, 1, 1 ) }, - "u_renderstyle": { value: 0 }, - "u_renderthreshold": { value: 0.5 }, - "u_clim": { value: new THREE.Vector2( 1, 1 ) }, - "u_data": { value: null }, - "u_cmdata": { value: null } - }, - vertexShader: [ - 'varying vec4 v_nearpos;', - 'varying vec4 v_farpos;', - 'varying vec3 v_position;', - - 'mat4 inversemat(mat4 m) {', - // Taken from https://github.com/stackgl/glsl-inverse/blob/master/index.glsl - // This function is licenced by the MIT license to Mikola Lysenko - 'float', - 'a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],', - 'a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],', - 'a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],', - 'a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],', - - 'b00 = a00 * a11 - a01 * a10,', - 'b01 = a00 * a12 - a02 * a10,', - 'b02 = a00 * a13 - a03 * a10,', - 'b03 = a01 * a12 - a02 * a11,', - 'b04 = a01 * a13 - a03 * a11,', - 'b05 = a02 * a13 - a03 * a12,', - 'b06 = a20 * a31 - a21 * a30,', - 'b07 = a20 * a32 - a22 * a30,', - 'b08 = a20 * a33 - a23 * a30,', - 'b09 = a21 * a32 - a22 * a31,', - 'b10 = a21 * a33 - a23 * a31,', - 'b11 = a22 * a33 - a23 * a32,', - - 'det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;', - - 'return mat4(', - 'a11 * b11 - a12 * b10 + a13 * b09,', - 'a02 * b10 - a01 * b11 - a03 * b09,', - 'a31 * b05 - a32 * b04 + a33 * b03,', - 'a22 * b04 - a21 * b05 - a23 * b03,', - 'a12 * b08 - a10 * b11 - a13 * b07,', - 'a00 * b11 - a02 * b08 + a03 * b07,', - 'a32 * b02 - a30 * b05 - a33 * b01,', - 'a20 * b05 - a22 * b02 + a23 * b01,', - 'a10 * b10 - a11 * b08 + a13 * b06,', - 'a01 * b08 - a00 * b10 - a03 * b06,', - 'a30 * b04 - a31 * b02 + a33 * b00,', - 'a21 * b02 - a20 * b04 - a23 * b00,', - 'a11 * b07 - a10 * b09 - a12 * b06,', - 'a00 * b09 - a01 * b07 + a02 * b06,', - 'a31 * b01 - a30 * b03 - a32 * b00,', - 'a20 * b03 - a21 * b01 + a22 * b00) / det;', - '}', - - - 'void main() {', - // Prepare transforms to map to "camera view". See also: - // https://threejs.org/docs/#api/renderers/webgl/WebGLProgram - 'mat4 viewtransformf = viewMatrix;', - 'mat4 viewtransformi = inversemat(viewMatrix);', - - // Project local vertex coordinate to camera position. Then do a step - // backward (in cam coords) to the near clipping plane, and project back. Do - // the same for the far clipping plane. This gives us all the information we - // need to calculate the ray and truncate it to the viewing cone. - 'vec4 position4 = vec4(position, 1.0);', - 'vec4 pos_in_cam = viewtransformf * position4;', - - // Intersection of ray and near clipping plane (z = -1 in clip coords) - 'pos_in_cam.z = -pos_in_cam.w;', - 'v_nearpos = viewtransformi * pos_in_cam;', - - // Intersection of ray and far clipping plane (z = +1 in clip coords) - 'pos_in_cam.z = pos_in_cam.w;', - 'v_farpos = viewtransformi * pos_in_cam;', - - // Set varyings and output pos - 'v_position = position;', - 'gl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;', - '}', - ].join( '\n' ), + "u_size": { value: new THREE.Vector3( 1, 1, 1 ) }, + "u_renderstyle": { value: 0 }, + "u_renderthreshold": { value: 0.5 }, + "u_clim": { value: new THREE.Vector2( 1, 1 ) }, + "u_data": { value: null }, + "u_cmdata": { value: null } + }, + vertexShader: [ + " varying vec4 v_nearpos;", + " varying vec4 v_farpos;", + " varying vec3 v_position;", + + " mat4 inversemat(mat4 m) {", + // Taken from https://github.com/stackgl/glsl-inverse/blob/master/index.glsl + // This function is licenced by the MIT license to Mikola Lysenko + " float", + " a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],", + " a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],", + " a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],", + " a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],", + + " b00 = a00 * a11 - a01 * a10,", + " b01 = a00 * a12 - a02 * a10,", + " b02 = a00 * a13 - a03 * a10,", + " b03 = a01 * a12 - a02 * a11,", + " b04 = a01 * a13 - a03 * a11,", + " b05 = a02 * a13 - a03 * a12,", + " b06 = a20 * a31 - a21 * a30,", + " b07 = a20 * a32 - a22 * a30,", + " b08 = a20 * a33 - a23 * a30,", + " b09 = a21 * a32 - a22 * a31,", + " b10 = a21 * a33 - a23 * a31,", + " b11 = a22 * a33 - a23 * a32,", + + " det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;", + + " return mat4(", + " a11 * b11 - a12 * b10 + a13 * b09,", + " a02 * b10 - a01 * b11 - a03 * b09,", + " a31 * b05 - a32 * b04 + a33 * b03,", + " a22 * b04 - a21 * b05 - a23 * b03,", + " a12 * b08 - a10 * b11 - a13 * b07,", + " a00 * b11 - a02 * b08 + a03 * b07,", + " a32 * b02 - a30 * b05 - a33 * b01,", + " a20 * b05 - a22 * b02 + a23 * b01,", + " a10 * b10 - a11 * b08 + a13 * b06,", + " a01 * b08 - a00 * b10 - a03 * b06,", + " a30 * b04 - a31 * b02 + a33 * b00,", + " a21 * b02 - a20 * b04 - a23 * b00,", + " a11 * b07 - a10 * b09 - a12 * b06,", + " a00 * b09 - a01 * b07 + a02 * b06,", + " a31 * b01 - a30 * b03 - a32 * b00,", + " a20 * b03 - a21 * b01 + a22 * b00) / det;", + " }", + + + " void main() {", + // Prepare transforms to map to "camera view". See also: + // https://threejs.org/docs/#api/renderers/webgl/WebGLProgram + " mat4 viewtransformf = modelViewMatrix;", + " mat4 viewtransformi = inversemat(modelViewMatrix);", + + // Project local vertex coordinate to camera position. Then do a step + // backward (in cam coords) to the near clipping plane, and project back. Do + // the same for the far clipping plane. This gives us all the information we + // need to calculate the ray and truncate it to the viewing cone. + " vec4 position4 = vec4(position, 1.0);", + " vec4 pos_in_cam = viewtransformf * position4;", + + // Intersection of ray and near clipping plane (z = -1 in clip coords) + " pos_in_cam.z = -pos_in_cam.w;", + " v_nearpos = viewtransformi * pos_in_cam;", + + // Intersection of ray and far clipping plane (z = +1 in clip coords) + " pos_in_cam.z = pos_in_cam.w;", + " v_farpos = viewtransformi * pos_in_cam;", + + // Set varyings and output pos + " v_position = position;", + " gl_Position = projectionMatrix * viewMatrix * modelMatrix * position4;", + " }", + ].join( "\n" ), fragmentShader: [ - 'precision highp float;', - 'precision mediump sampler3D;', - - 'uniform vec3 u_size;', - 'uniform int u_renderstyle;', - 'uniform float u_renderthreshold;', - 'uniform vec2 u_clim;', - - 'uniform sampler3D u_data;', - 'uniform sampler2D u_cmdata;', - - 'varying vec3 v_position;', - 'varying vec4 v_nearpos;', - 'varying vec4 v_farpos;', - - // The maximum distance through our rendering volume is sqrt(3). - 'const int MAX_STEPS = 887; // 887 for 512^3, 1774 for 1024^3', - 'const int REFINEMENT_STEPS = 4;', - 'const float relative_step_size = 1.0;', - 'const vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);', - 'const vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);', - 'const vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);', - 'const float shininess = 40.0;', - - 'void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);', - 'void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);', - - 'float sample1(vec3 texcoords);', - 'vec4 apply_colormap(float val);', - 'vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);', - - - 'void main() {', - // Normalize clipping plane info - 'vec3 farpos = v_farpos.xyz / v_farpos.w;', - 'vec3 nearpos = v_nearpos.xyz / v_nearpos.w;', - - // Calculate unit vector pointing in the view direction through this fragment. - 'vec3 view_ray = normalize(nearpos.xyz - farpos.xyz);', - - // Compute the (negative) distance to the front surface or near clipping plane. - // v_position is the back face of the cuboid, so the initial distance calculated in the dot - // product below is the distance from near clip plane to the back of the cuboid - 'float distance = dot(nearpos - v_position, view_ray);', - 'distance = max(distance, min((-0.5 - v_position.x) / view_ray.x,', - '(u_size.x - 0.5 - v_position.x) / view_ray.x));', - 'distance = max(distance, min((-0.5 - v_position.y) / view_ray.y,', - '(u_size.y - 0.5 - v_position.y) / view_ray.y));', - 'distance = max(distance, min((-0.5 - v_position.z) / view_ray.z,', - '(u_size.z - 0.5 - v_position.z) / view_ray.z));', - - // Now we have the starting position on the front surface - 'vec3 front = v_position + view_ray * distance;', - - // Decide how many steps to take - 'int nsteps = int(-distance / relative_step_size + 0.5);', - 'if ( nsteps < 1 )', - 'discard;', - - // Get starting location and step vector in texture coordinates - 'vec3 step = ((v_position - front) / u_size) / float(nsteps);', - 'vec3 start_loc = front / u_size;', - - // For testing: show the number of steps. This helps to establish - // whether the rays are correctly oriented - //'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);', - //'return;', - - 'if (u_renderstyle == 0)', - 'cast_mip(start_loc, step, nsteps, view_ray);', - 'else if (u_renderstyle == 1)', - 'cast_iso(start_loc, step, nsteps, view_ray);', - - 'if (gl_FragColor.a < 0.05)', - 'discard;', - '}', - - - 'float sample1(vec3 texcoords) {', - '/* Sample float value from a 3D texture. Assumes intensity data. */', - 'return texture(u_data, texcoords.xyz).r;', - '}', - - - 'vec4 apply_colormap(float val) {', - 'val = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);', - 'return texture2D(u_cmdata, vec2(val, 0.5));', - '}', - - - 'void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {', - - 'float max_val = -1e6;', - 'int max_i = 100;', - 'vec3 loc = start_loc;', - - // Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with - // non-constant expression. So we use a hard-coded max, and an additional condition - // inside the loop. - 'for (int iter=0; iter= nsteps)', - 'break;', - // Sample from the 3D texture - 'float val = sample1(loc);', - // Apply MIP operation - 'if (val > max_val) {', - 'max_val = val;', - 'max_i = iter;', - '}', - // Advance location deeper into the volume - 'loc += step;', - '}', - - // Refine location, gives crispier images - 'vec3 iloc = start_loc + step * (float(max_i) - 0.5);', - 'vec3 istep = step / float(REFINEMENT_STEPS);', - 'for (int i=0; i= nsteps)', - 'break;', - - // Sample from the 3D texture - 'float val = sample1(loc);', - - 'if (val > low_threshold) {', - // Take the last interval in smaller steps - 'vec3 iloc = loc - 0.5 * step;', - 'vec3 istep = step / float(REFINEMENT_STEPS);', - 'for (int i=0; i u_renderthreshold) {', - 'gl_FragColor = add_lighting(val, iloc, dstep, view_ray);', - 'return;', - '}', - 'iloc += istep;', - '}', - '}', - - // Advance location deeper into the volume - 'loc += step;', - '}', - '}', - - - 'vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)', - '{', - // Calculate color by incorporating lighting - - // View direction - 'vec3 V = normalize(view_ray);', - - // calculate normal vector from gradient - 'vec3 N;', - 'float val1, val2;', - 'val1 = sample1(loc + vec3(-step[0], 0.0, 0.0));', - 'val2 = sample1(loc + vec3(+step[0], 0.0, 0.0));', - 'N[0] = val1 - val2;', - 'val = max(max(val1, val2), val);', - 'val1 = sample1(loc + vec3(0.0, -step[1], 0.0));', - 'val2 = sample1(loc + vec3(0.0, +step[1], 0.0));', - 'N[1] = val1 - val2;', - 'val = max(max(val1, val2), val);', - 'val1 = sample1(loc + vec3(0.0, 0.0, -step[2]));', - 'val2 = sample1(loc + vec3(0.0, 0.0, +step[2]));', - 'N[2] = val1 - val2;', - 'val = max(max(val1, val2), val);', - - 'float gm = length(N); // gradient magnitude', - 'N = normalize(N);', - - // Flip normal so it points towards viewer - 'float Nselect = float(dot(N, V) > 0.0);', - 'N = (2.0 * Nselect - 1.0) * N; // == Nselect * N - (1.0-Nselect)*N;', - - // Init colors - 'vec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);', - 'vec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);', - 'vec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);', - - // note: could allow multiple lights - 'for (int i=0; i<1; i++)', - '{', + " precision highp float;", + " precision mediump sampler3D;", + + " uniform vec3 u_size;", + " uniform int u_renderstyle;", + " uniform float u_renderthreshold;", + " uniform vec2 u_clim;", + + " uniform sampler3D u_data;", + " uniform sampler2D u_cmdata;", + + " varying vec3 v_position;", + " varying vec4 v_nearpos;", + " varying vec4 v_farpos;", + + // The maximum distance through our rendering volume is sqrt(3). + " const int MAX_STEPS = 887; // 887 for 512^3, 1774 for 1024^3", + " const int REFINEMENT_STEPS = 4;", + " const float relative_step_size = 1.0;", + " const vec4 ambient_color = vec4(0.2, 0.4, 0.2, 1.0);", + " const vec4 diffuse_color = vec4(0.8, 0.2, 0.2, 1.0);", + " const vec4 specular_color = vec4(1.0, 1.0, 1.0, 1.0);", + " const float shininess = 40.0;", + + " void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);", + " void cast_iso(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray);", + + " float sample1(vec3 texcoords);", + " vec4 apply_colormap(float val);", + " vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray);", + + + " void main() {", + // Normalize clipping plane info + " vec3 farpos = v_farpos.xyz / v_farpos.w;", + " vec3 nearpos = v_nearpos.xyz / v_nearpos.w;", + + // Calculate unit vector pointing in the view direction through this fragment. + " vec3 view_ray = normalize(nearpos.xyz - farpos.xyz);", + + // Compute the (negative) distance to the front surface or near clipping plane. + // v_position is the back face of the cuboid, so the initial distance calculated in the dot + // product below is the distance from near clip plane to the back of the cuboid + " float distance = dot(nearpos - v_position, view_ray);", + " distance = max(distance, min((-0.5 - v_position.x) / view_ray.x,", + " (u_size.x - 0.5 - v_position.x) / view_ray.x));", + " distance = max(distance, min((-0.5 - v_position.y) / view_ray.y,", + " (u_size.y - 0.5 - v_position.y) / view_ray.y));", + " distance = max(distance, min((-0.5 - v_position.z) / view_ray.z,", + " (u_size.z - 0.5 - v_position.z) / view_ray.z));", + + // Now we have the starting position on the front surface + " vec3 front = v_position + view_ray * distance;", + + // Decide how many steps to take + " int nsteps = int(-distance / relative_step_size + 0.5);", + " if ( nsteps < 1 )", + " discard;", + + // Get starting location and step vector in texture coordinates + " vec3 step = ((v_position - front) / u_size) / float(nsteps);", + " vec3 start_loc = front / u_size;", + + // For testing: show the number of steps. This helps to establish + // whether the rays are correctly oriented + //'gl_FragColor = vec4(0.0, float(nsteps) / 1.0 / u_size.x, 1.0, 1.0);', + //'return;', + + " if (u_renderstyle == 0)", + " cast_mip(start_loc, step, nsteps, view_ray);", + " else if (u_renderstyle == 1)", + " cast_iso(start_loc, step, nsteps, view_ray);", + + " if (gl_FragColor.a < 0.05)", + " discard;", + " }", + + + " float sample1(vec3 texcoords) {", + " /* Sample float value from a 3D texture. Assumes intensity data. */", + " return texture(u_data, texcoords.xyz).r;", + " }", + + + " vec4 apply_colormap(float val) {", + " val = (val - u_clim[0]) / (u_clim[1] - u_clim[0]);", + " return texture2D(u_cmdata, vec2(val, 0.5));", + " }", + + + " void cast_mip(vec3 start_loc, vec3 step, int nsteps, vec3 view_ray) {", + + " float max_val = -1e6;", + " int max_i = 100;", + " vec3 loc = start_loc;", + + // Enter the raycasting loop. In WebGL 1 the loop index cannot be compared with + // non-constant expression. So we use a hard-coded max, and an additional condition + // inside the loop. + " for (int iter=0; iter= nsteps)", + " break;", + // Sample from the 3D texture + " float val = sample1(loc);", + // Apply MIP operation + " if (val > max_val) {", + " max_val = val;", + " max_i = iter;", + " }", + // Advance location deeper into the volume + " loc += step;", + " }", + + // Refine location, gives crispier images + " vec3 iloc = start_loc + step * (float(max_i) - 0.5);", + " vec3 istep = step / float(REFINEMENT_STEPS);", + " for (int i=0; i= nsteps)", + " break;", + + // Sample from the 3D texture + " float val = sample1(loc);", + + " if (val > low_threshold) {", + // Take the last interval in smaller steps + " vec3 iloc = loc - 0.5 * step;", + " vec3 istep = step / float(REFINEMENT_STEPS);", + " for (int i=0; i u_renderthreshold) {", + " gl_FragColor = add_lighting(val, iloc, dstep, view_ray);", + " return;", + " }", + " iloc += istep;", + " }", + " }", + + // Advance location deeper into the volume + " loc += step;", + " }", + " }", + + + " vec4 add_lighting(float val, vec3 loc, vec3 step, vec3 view_ray)", + " {", + // Calculate color by incorporating lighting + + // View direction + " vec3 V = normalize(view_ray);", + + // calculate normal vector from gradient + " vec3 N;", + " float val1, val2;", + " val1 = sample1(loc + vec3(-step[0], 0.0, 0.0));", + " val2 = sample1(loc + vec3(+step[0], 0.0, 0.0));", + " N[0] = val1 - val2;", + " val = max(max(val1, val2), val);", + " val1 = sample1(loc + vec3(0.0, -step[1], 0.0));", + " val2 = sample1(loc + vec3(0.0, +step[1], 0.0));", + " N[1] = val1 - val2;", + " val = max(max(val1, val2), val);", + " val1 = sample1(loc + vec3(0.0, 0.0, -step[2]));", + " val2 = sample1(loc + vec3(0.0, 0.0, +step[2]));", + " N[2] = val1 - val2;", + " val = max(max(val1, val2), val);", + + " float gm = length(N); // gradient magnitude", + " N = normalize(N);", + + // Flip normal so it points towards viewer + " float Nselect = float(dot(N, V) > 0.0);", + " N = (2.0 * Nselect - 1.0) * N; // == Nselect * N - (1.0-Nselect)*N;", + + // Init colors + " vec4 ambient_color = vec4(0.0, 0.0, 0.0, 0.0);", + " vec4 diffuse_color = vec4(0.0, 0.0, 0.0, 0.0);", + " vec4 specular_color = vec4(0.0, 0.0, 0.0, 0.0);", + + // note: could allow multiple lights + " for (int i=0; i<1; i++)", + " {", // Get light direction (make sure to prevent zero devision) - 'vec3 L = normalize(view_ray); //lightDirs[i];', - 'float lightEnabled = float( length(L) > 0.0 );', - 'L = normalize(L + (1.0 - lightEnabled));', - - // Calculate lighting properties - 'float lambertTerm = clamp(dot(N, L), 0.0, 1.0);', - 'vec3 H = normalize(L+V); // Halfway vector', - 'float specularTerm = pow(max(dot(H, N), 0.0), shininess);', - - // Calculate mask - 'float mask1 = lightEnabled;', - - // Calculate colors - 'ambient_color += mask1 * ambient_color; // * gl_LightSource[i].ambient;', - 'diffuse_color += mask1 * lambertTerm;', - 'specular_color += mask1 * specularTerm * specular_color;', - '}', - - // Calculate final color by componing different components - 'vec4 final_color;', - 'vec4 color = apply_colormap(val);', - 'final_color = color * (ambient_color + diffuse_color) + specular_color;', - 'final_color.a = color.a;', - 'return final_color;', - '}', - ].join( '\n' ) + " vec3 L = normalize(view_ray); //lightDirs[i];", + " float lightEnabled = float( length(L) > 0.0 );", + " L = normalize(L + (1.0 - lightEnabled));", + + // Calculate lighting properties + " float lambertTerm = clamp(dot(N, L), 0.0, 1.0);", + " vec3 H = normalize(L+V); // Halfway vector", + " float specularTerm = pow(max(dot(H, N), 0.0), shininess);", + + // Calculate mask + " float mask1 = lightEnabled;", + + // Calculate colors + " ambient_color += mask1 * ambient_color; // * gl_LightSource[i].ambient;", + " diffuse_color += mask1 * lambertTerm;", + " specular_color += mask1 * specularTerm * specular_color;", + " }", + + // Calculate final color by componing different components + " vec4 final_color;", + " vec4 color = apply_colormap(val);", + " final_color = color * (ambient_color + diffuse_color) + specular_color;", + " final_color.a = color.a;", + " return final_color;", + " }", + ].join( "\n" ) }; diff --git a/examples/js/shaders/WaterRefractionShader.js b/examples/js/shaders/WaterRefractionShader.js index 6796fd4b59b7c4..9512fca6d4a8d9 100644 --- a/examples/js/shaders/WaterRefractionShader.js +++ b/examples/js/shaders/WaterRefractionShader.js @@ -7,23 +7,23 @@ THREE.WaterRefractionShader = { uniforms: { - 'color': { + "color": { value: null }, - 'time': { + "time": { value: 0 }, - 'tDiffuse': { + "tDiffuse": { value: null }, - 'tDudv': { + "tDudv": { value: null }, - 'textureMatrix': { + "textureMatrix": { value: null } @@ -31,66 +31,66 @@ THREE.WaterRefractionShader = { vertexShader: [ - 'uniform mat4 textureMatrix;', + "uniform mat4 textureMatrix;", - 'varying vec2 vUv;', - 'varying vec4 vUvRefraction;', + "varying vec2 vUv;", + "varying vec4 vUvRefraction;", - 'void main() {', + "void main() {", - ' vUv = uv;', + " vUv = uv;", - ' vUvRefraction = textureMatrix * vec4( position, 1.0 );', + " vUvRefraction = textureMatrix * vec4( position, 1.0 );", - ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', + " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - '}' + "}" - ].join( '\n' ), + ].join( "\n" ), fragmentShader: [ - 'uniform vec3 color;', - 'uniform float time;', - 'uniform sampler2D tDiffuse;', - 'uniform sampler2D tDudv;', + "uniform vec3 color;", + "uniform float time;", + "uniform sampler2D tDiffuse;", + "uniform sampler2D tDudv;", - 'varying vec2 vUv;', - 'varying vec4 vUvRefraction;', + "varying vec2 vUv;", + "varying vec4 vUvRefraction;", - 'float blendOverlay( float base, float blend ) {', + "float blendOverlay( float base, float blend ) {", - ' return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );', + " return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );", - '}', + "}", - 'vec3 blendOverlay( vec3 base, vec3 blend ) {', + "vec3 blendOverlay( vec3 base, vec3 blend ) {", - ' return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ),blendOverlay( base.b, blend.b ) );', + " return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ),blendOverlay( base.b, blend.b ) );", - '}', + "}", - 'void main() {', + "void main() {", - ' float waveStrength = 0.1;', - ' float waveSpeed = 0.03;', + " float waveStrength = 0.1;", + " float waveSpeed = 0.03;", // simple distortion (ripple) via dudv map (see https://www.youtube.com/watch?v=6B7IF6GOu7s) - ' vec2 distortedUv = texture2D( tDudv, vec2( vUv.x + time * waveSpeed, vUv.y ) ).rg * waveStrength;', - ' distortedUv = vUv.xy + vec2( distortedUv.x, distortedUv.y + time * waveSpeed );', - ' vec2 distortion = ( texture2D( tDudv, distortedUv ).rg * 2.0 - 1.0 ) * waveStrength;', + " vec2 distortedUv = texture2D( tDudv, vec2( vUv.x + time * waveSpeed, vUv.y ) ).rg * waveStrength;", + " distortedUv = vUv.xy + vec2( distortedUv.x, distortedUv.y + time * waveSpeed );", + " vec2 distortion = ( texture2D( tDudv, distortedUv ).rg * 2.0 - 1.0 ) * waveStrength;", // new uv coords - ' vec4 uv = vec4( vUvRefraction );', - ' uv.xy += distortion;', + " vec4 uv = vec4( vUvRefraction );", + " uv.xy += distortion;", - ' vec4 base = texture2DProj( tDiffuse, uv );', + " vec4 base = texture2DProj( tDiffuse, uv );", - ' gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );', + " gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );", - '}' + "}" - ].join( '\n' ) + ].join( "\n" ) }; diff --git a/examples/js/utils/BufferGeometryUtils.js b/examples/js/utils/BufferGeometryUtils.js index 473d48661d36fb..c24d7fa5684bd5 100644 --- a/examples/js/utils/BufferGeometryUtils.js +++ b/examples/js/utils/BufferGeometryUtils.js @@ -31,7 +31,7 @@ THREE.BufferGeometryUtils = { if ( attributes.tangent === undefined ) { - geometry.addAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) ); + geometry.setAttribute( 'tangent', new THREE.BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) ); } @@ -67,34 +67,20 @@ THREE.BufferGeometryUtils = { uvB.fromArray( uvs, b * 2 ); uvC.fromArray( uvs, c * 2 ); - var x1 = vB.x - vA.x; - var x2 = vC.x - vA.x; + vB.sub( vA ); + vC.sub( vA ); - var y1 = vB.y - vA.y; - var y2 = vC.y - vA.y; + uvB.sub( uvA ); + uvC.sub( uvA ); - var z1 = vB.z - vA.z; - var z2 = vC.z - vA.z; + var r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y ); - var s1 = uvB.x - uvA.x; - var s2 = uvC.x - uvA.x; + // silently ignore degenerate uv triangles having coincident or colinear vertices - var t1 = uvB.y - uvA.y; - var t2 = uvC.y - uvA.y; + if ( ! isFinite( r ) ) return; - var r = 1.0 / ( s1 * t2 - s2 * t1 ); - - sdir.set( - ( t2 * x1 - t1 * x2 ) * r, - ( t2 * y1 - t1 * y2 ) * r, - ( t2 * z1 - t1 * z2 ) * r - ); - - tdir.set( - ( s1 * x2 - s2 * x1 ) * r, - ( s1 * y2 - s2 * y1 ) * r, - ( s1 * z2 - s2 * z1 ) * r - ); + sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r ); + tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r ); tan1[ a ].add( sdir ); tan1[ b ].add( sdir ); @@ -199,6 +185,8 @@ THREE.BufferGeometryUtils = { var attributes = {}; var morphAttributes = {}; + var morphTargetsRelative = geometries[ 0 ].morphTargetsRelative; + var mergedGeometry = new THREE.BufferGeometry(); var offset = 0; @@ -225,6 +213,8 @@ THREE.BufferGeometryUtils = { // gather morph attributes, exit early if they're different + if ( morphTargetsRelative !== geometry.morphTargetsRelative ) return null; + for ( var name in geometry.morphAttributes ) { if ( ! morphAttributesUsed.has( name ) ) return null; @@ -299,7 +289,7 @@ THREE.BufferGeometryUtils = { if ( ! mergedAttribute ) return null; - mergedGeometry.addAttribute( name, mergedAttribute ); + mergedGeometry.setAttribute( name, mergedAttribute ); } @@ -589,29 +579,21 @@ THREE.BufferGeometryUtils = { var name = attributeNames[ i ]; var oldAttribute = geometry.getAttribute( name ); - var attribute; var buffer = new oldAttribute.array.constructor( attrArrays[ name ] ); - if ( oldAttribute.isInterleavedBufferAttribute ) { - - attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.itemSize ); - - } else { - - attribute = geometry.getAttribute( name ).clone(); - attribute.setArray( buffer ); - - } + var attribute = new THREE.BufferAttribute( buffer, oldAttribute.itemSize, oldAttribute.normalized ); - result.addAttribute( name, attribute ); + result.setAttribute( name, attribute ); // Update the attribute arrays if ( name in morphAttrsArrays ) { for ( var j = 0; j < morphAttrsArrays[ name ].length; j ++ ) { - var morphAttribute = geometry.morphAttributes[ name ][ j ].clone(); - morphAttribute.setArray( new morphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ) ); + var oldMorphAttribute = geometry.morphAttributes[ name ][ j ]; + + var buffer = new oldMorphAttribute.array.constructor( morphAttrsArrays[ name ][ j ] ); + var morphAttribute = new THREE.BufferAttribute( buffer, oldMorphAttribute.itemSize, oldMorphAttribute.normalized ); result.morphAttributes[ name ][ j ] = morphAttribute; } @@ -620,27 +602,122 @@ THREE.BufferGeometryUtils = { } - // Generate an index buffer typed array - var cons = Uint8Array; - if ( newIndices.length >= Math.pow( 2, 8 ) ) cons = Uint16Array; - if ( newIndices.length >= Math.pow( 2, 16 ) ) cons = Uint32Array; + // indices - var newIndexBuffer = new cons( newIndices ); - var newIndices = null; - if ( indices === null ) { + result.setIndex( newIndices ); - newIndices = new THREE.BufferAttribute( newIndexBuffer, 1 ); + return result; - } else { + }, + + /** + * @param {THREE.BufferGeometry} geometry + * @param {number} drawMode + * @return {THREE.BufferGeometry>} + */ + toTrianglesDrawMode: function ( geometry, drawMode ) { + + if ( drawMode === THREE.TrianglesDrawMode ) { - newIndices = geometry.getIndex().clone(); - newIndices.setArray( newIndexBuffer ); + console.warn( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.' ); + return geometry; } - result.setIndex( newIndices ); + if ( drawMode === THREE.TriangleFanDrawMode || drawMode === THREE.TriangleStripDrawMode ) { - return result; + var index = geometry.getIndex(); + + // generate index if not present + + if ( index === null ) { + + var indices = []; + + var position = geometry.getAttribute( 'position' ); + + if ( position !== undefined ) { + + for ( var i = 0; i < position.count; i ++ ) { + + indices.push( i ); + + } + + geometry.setIndex( indices ); + index = geometry.getIndex(); + + } else { + + console.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' ); + return geometry; + + } + + } + + // + + var numberOfTriangles = index.count - 2; + var newIndices = []; + + if ( drawMode === THREE.TriangleFanDrawMode ) { + + // gl.TRIANGLE_FAN + + for ( var i = 1; i <= numberOfTriangles; i ++ ) { + + newIndices.push( index.getX( 0 ) ); + newIndices.push( index.getX( i ) ); + newIndices.push( index.getX( i + 1 ) ); + + } + + } else { + + // gl.TRIANGLE_STRIP + + for ( var i = 0; i < numberOfTriangles; i ++ ) { + + if ( i % 2 === 0 ) { + + newIndices.push( index.getX( i ) ); + newIndices.push( index.getX( i + 1 ) ); + newIndices.push( index.getX( i + 2 ) ); + + + } else { + + newIndices.push( index.getX( i + 2 ) ); + newIndices.push( index.getX( i + 1 ) ); + newIndices.push( index.getX( i ) ); + + } + + } + + } + + if ( ( newIndices.length / 3 ) !== numberOfTriangles ) { + + console.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' ); + + } + + // build final geometry + + var newGeometry = geometry.clone(); + newGeometry.setIndex( newIndices ); + newGeometry.clearGroups(); + + return newGeometry; + + } else { + + console.error( 'THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:', drawMode ); + return geometry; + + } } diff --git a/examples/js/utils/GeometryUtils.js b/examples/js/utils/GeometryUtils.js index d16426fc17736e..79803aeb785740 100644 --- a/examples/js/utils/GeometryUtils.js +++ b/examples/js/utils/GeometryUtils.js @@ -5,298 +5,6 @@ THREE.GeometryUtils = { - // Merge two geometries or geometry and geometry from object (using object's transform) - - merge: function ( geometry1, geometry2, materialIndexOffset ) { - - console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' ); - - var matrix; - - if ( geometry2 instanceof THREE.Mesh ) { - - geometry2.matrixAutoUpdate && geometry2.updateMatrix(); - - matrix = geometry2.matrix; - geometry2 = geometry2.geometry; - - } - - geometry1.merge( geometry2, matrix, materialIndexOffset ); - - }, - - // Get random point in triangle (via barycentric coordinates) - // (uniform distribution) - // http://www.cgafaq.info/wiki/Random_Point_In_Triangle - - randomPointInTriangle: function () { - - var vector = new THREE.Vector3(); - - return function ( vectorA, vectorB, vectorC ) { - - var point = new THREE.Vector3(); - - var a = Math.random(); - var b = Math.random(); - - if ( ( a + b ) > 1 ) { - - a = 1 - a; - b = 1 - b; - - } - - var c = 1 - a - b; - - point.copy( vectorA ); - point.multiplyScalar( a ); - - vector.copy( vectorB ); - vector.multiplyScalar( b ); - - point.add( vector ); - - vector.copy( vectorC ); - vector.multiplyScalar( c ); - - point.add( vector ); - - return point; - - }; - - }(), - - // Get random point in face (triangle) - // (uniform distribution) - - randomPointInFace: function ( face, geometry ) { - - var vA, vB, vC; - - vA = geometry.vertices[ face.a ]; - vB = geometry.vertices[ face.b ]; - vC = geometry.vertices[ face.c ]; - - return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC ); - - }, - - // Get uniformly distributed random points in mesh - // - create array with cumulative sums of face areas - // - pick random number from 0 to total area - // - find corresponding place in area array by binary search - // - get random point in face - - randomPointsInGeometry: function ( geometry, n ) { - - var face, i, - faces = geometry.faces, - vertices = geometry.vertices, - il = faces.length, - totalArea = 0, - cumulativeAreas = [], - vA, vB, vC; - - // precompute face areas - - for ( i = 0; i < il; i ++ ) { - - face = faces[ i ]; - - vA = vertices[ face.a ]; - vB = vertices[ face.b ]; - vC = vertices[ face.c ]; - - face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC ); - - totalArea += face._area; - - cumulativeAreas[ i ] = totalArea; - - } - - // binary search cumulative areas array - - function binarySearchIndices( value ) { - - function binarySearch( start, end ) { - - // return closest larger index - // if exact number is not found - - if ( end < start ) - return start; - - var mid = start + Math.floor( ( end - start ) / 2 ); - - if ( cumulativeAreas[ mid ] > value ) { - - return binarySearch( start, mid - 1 ); - - } else if ( cumulativeAreas[ mid ] < value ) { - - return binarySearch( mid + 1, end ); - - } else { - - return mid; - - } - - } - - var result = binarySearch( 0, cumulativeAreas.length - 1 ); - return result; - - } - - // pick random face weighted by face area - - var r, index, - result = []; - - var stats = {}; - - for ( i = 0; i < n; i ++ ) { - - r = Math.random() * totalArea; - - index = binarySearchIndices( r ); - - result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry ); - - if ( ! stats[ index ] ) { - - stats[ index ] = 1; - - } else { - - stats[ index ] += 1; - - } - - } - - return result; - - }, - - randomPointsInBufferGeometry: function ( geometry, n ) { - - var i, - vertices = geometry.attributes.position.array, - totalArea = 0, - cumulativeAreas = [], - vA, vB, vC; - - // precompute face areas - vA = new THREE.Vector3(); - vB = new THREE.Vector3(); - vC = new THREE.Vector3(); - - // geometry._areas = []; - var il = vertices.length / 9; - - for ( i = 0; i < il; i ++ ) { - - vA.set( vertices[ i * 9 + 0 ], vertices[ i * 9 + 1 ], vertices[ i * 9 + 2 ] ); - vB.set( vertices[ i * 9 + 3 ], vertices[ i * 9 + 4 ], vertices[ i * 9 + 5 ] ); - vC.set( vertices[ i * 9 + 6 ], vertices[ i * 9 + 7 ], vertices[ i * 9 + 8 ] ); - - totalArea += THREE.GeometryUtils.triangleArea( vA, vB, vC ); - - cumulativeAreas.push( totalArea ); - - } - - // binary search cumulative areas array - - function binarySearchIndices( value ) { - - function binarySearch( start, end ) { - - // return closest larger index - // if exact number is not found - - if ( end < start ) - return start; - - var mid = start + Math.floor( ( end - start ) / 2 ); - - if ( cumulativeAreas[ mid ] > value ) { - - return binarySearch( start, mid - 1 ); - - } else if ( cumulativeAreas[ mid ] < value ) { - - return binarySearch( mid + 1, end ); - - } else { - - return mid; - - } - - } - - var result = binarySearch( 0, cumulativeAreas.length - 1 ); - return result; - - } - - // pick random face weighted by face area - - var r, index, - result = []; - - for ( i = 0; i < n; i ++ ) { - - r = Math.random() * totalArea; - - index = binarySearchIndices( r ); - - // result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry, true ); - vA.set( vertices[ index * 9 + 0 ], vertices[ index * 9 + 1 ], vertices[ index * 9 + 2 ] ); - vB.set( vertices[ index * 9 + 3 ], vertices[ index * 9 + 4 ], vertices[ index * 9 + 5 ] ); - vC.set( vertices[ index * 9 + 6 ], vertices[ index * 9 + 7 ], vertices[ index * 9 + 8 ] ); - result[ i ] = THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC ); - - } - - return result; - - }, - - // Get triangle area (half of parallelogram) - // http://mathworld.wolfram.com/TriangleArea.html - - triangleArea: function () { - - var vector1 = new THREE.Vector3(); - var vector2 = new THREE.Vector3(); - - return function ( vectorA, vectorB, vectorC ) { - - vector1.subVectors( vectorB, vectorA ); - vector2.subVectors( vectorC, vectorA ); - vector1.cross( vector2 ); - - return 0.5 * vector1.length(); - - }; - - }(), - - center: function ( geometry ) { - - console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' ); - return geometry.center(); - - }, - /** * Generates 2D-Coordinates in a very fast way. * diff --git a/examples/js/utils/MathUtils.js b/examples/js/utils/MathUtils.js deleted file mode 100644 index ac25a4373c28a1..00000000000000 --- a/examples/js/utils/MathUtils.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @author WestLangley / http://github.com/WestLangley - * @author thezwap / http://github.com/thezwap - */ - -THREE.MathUtils = { - - setQuaternionFromProperEuler: function ( q, a, b, c, order ) { - - // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles - - // rotations are applied to the axes in the order specified by 'order' - // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' - // angles are in radians - - var cos = Math.cos; - var sin = Math.sin; - - var c2 = cos( b / 2 ); - var s2 = sin( b / 2 ); - - var c13 = cos( ( a + c ) / 2 ); - var s13 = sin( ( a + c ) / 2 ); - - var c1_3 = cos( ( a - c ) / 2 ); - var s1_3 = sin( ( a - c ) / 2 ); - - var c3_1 = cos( ( c - a ) / 2 ); - var s3_1 = sin( ( c - a ) / 2 ); - - if ( order === 'XYX' ) { - - q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 ); - - } else if ( order === 'YZY' ) { - - q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 ); - - } else if ( order === 'ZXZ' ) { - - q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 ); - - } else if ( order === 'XZX' ) { - - q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 ); - - } else if ( order === 'YXY' ) { - - q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 ); - - } else if ( order === 'ZYZ' ) { - - q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 ); - - } else { - - console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order.' ); - - } - - } - -}; diff --git a/examples/js/utils/SceneUtils.js b/examples/js/utils/SceneUtils.js index 2e22b84920d658..c7367dc56e47dc 100644 --- a/examples/js/utils/SceneUtils.js +++ b/examples/js/utils/SceneUtils.js @@ -4,6 +4,32 @@ THREE.SceneUtils = { + createMeshesFromInstancedMesh: function ( instancedMesh ) { + + var group = new THREE.Group(); + + var count = instancedMesh.count; + var geometry = instancedMesh.geometry; + var material = instancedMesh.material; + + for ( var i = 0; i < count; i ++ ) { + + var mesh = new THREE.Mesh( geometry, material ); + + instancedMesh.getMatrixAt( i, mesh.matrix ); + mesh.matrix.decompose( mesh.position, mesh.quaternion, mesh.scale ); + + group.add( mesh ); + + } + + group.copy( instancedMesh ); + group.updateMatrixWorld(); // ensure correct world matrices of meshes + + return group; + + }, + createMultiMaterialObject: function ( geometry, materials ) { var group = new THREE.Group(); diff --git a/examples/js/utils/ShadowMapViewer.js b/examples/js/utils/ShadowMapViewer.js index e944234c04274e..06a0c126303903 100644 --- a/examples/js/utils/ShadowMapViewer.js +++ b/examples/js/utils/ShadowMapViewer.js @@ -2,19 +2,19 @@ * @author arya-s / https://github.com/arya-s * * This is a helper for visualising a given light's shadow map. - * It works for shadow casting lights: THREE.DirectionalLight and THREE.SpotLight. + * It works for shadow casting lights: DirectionalLight and SpotLight. * It renders out the shadow map and displays it on a HUD. * * Example usage: - * 1) Include + + diff --git a/examples/misc_animation_groups.html b/examples/misc_animation_groups.html index edaf8031c0b123..4600b8283ea37e 100644 --- a/examples/misc_animation_groups.html +++ b/examples/misc_animation_groups.html @@ -9,7 +9,7 @@
        - three.js webgl - animation - groups + three.js webgl - animation - groups
        - - - diff --git a/examples/misc_controls_transform.html b/examples/misc_controls_transform.html index 234d7b0d238bbf..9d158afb137c37 100644 --- a/examples/misc_controls_transform.html +++ b/examples/misc_controls_transform.html @@ -10,7 +10,7 @@
        "W" translate | "E" rotate | "R" scale | "+" increase size | "-" decrease size
        - "Q" toggle world/local space | Hold "Ctrl" down to snap to grid
        + "Q" toggle world/local space | Hold "Shift" down to snap to grid
        "X" toggle X | "Y" toggle Y | "Z" toggle Z | "Spacebar" toggle enabled
        @@ -81,9 +81,10 @@ control.setSpace( control.space === "local" ? "world" : "local" ); break; - case 17: // Ctrl + case 16: // Shift control.setTranslationSnap( 100 ); - control.setRotationSnap( THREE.Math.degToRad( 15 ) ); + control.setRotationSnap( THREE.MathUtils.degToRad( 15 ) ); + control.setScaleSnap( 0.25 ); break; case 87: // W @@ -135,6 +136,7 @@ case 17: // Ctrl control.setTranslationSnap( null ); control.setRotationSnap( null ); + control.setScaleSnap( null ); break; } diff --git a/examples/misc_exporter_collada.html b/examples/misc_exporter_collada.html index 4d40f6abcdd22e..8a09d59e630da4 100644 --- a/examples/misc_exporter_collada.html +++ b/examples/misc_exporter_collada.html @@ -8,7 +8,7 @@
        - three.js webgl - exporter - collada

        + three.js webgl - exporter - collada

        @@ -73,8 +73,7 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( canvasWidth, canvasHeight ); - renderer.gammaInput = true; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; container.appendChild( renderer.domElement ); // EVENTS @@ -88,16 +87,18 @@ var textureMap = new THREE.TextureLoader().load( 'textures/uv_grid_opengl.jpg' ); textureMap.wrapS = textureMap.wrapT = THREE.RepeatWrapping; textureMap.anisotropy = 16; + textureMap.encoding = THREE.sRGBEncoding; // REFLECTION MAP - var path = "textures/cube/skybox/"; + var path = "textures/cube/pisa/"; var urls = [ - path + "px.jpg", path + "nx.jpg", - path + "py.jpg", path + "ny.jpg", - path + "pz.jpg", path + "nz.jpg" + path + "px.png", path + "nx.png", + path + "py.png", path + "ny.png", + path + "pz.png", path + "nz.png" ]; textureCube = new THREE.CubeTextureLoader().load( urls ); + textureCube.encoding = THREE.sRGBEncoding; // MATERIALS var materialColor = new THREE.Color(); diff --git a/examples/misc_exporter_draco.html b/examples/misc_exporter_draco.html index 3d079f96471aeb..43e3396f6d426a 100644 --- a/examples/misc_exporter_draco.html +++ b/examples/misc_exporter_draco.html @@ -18,7 +18,7 @@
        - three.js webgl - exporter - draco

        + three.js webgl - exporter - draco

        | diff --git a/examples/misc_exporter_gltf.html b/examples/misc_exporter_gltf.html index fe8868e89691ca..85e961077f948c 100644 --- a/examples/misc_exporter_gltf.html +++ b/examples/misc_exporter_gltf.html @@ -8,7 +8,7 @@
        - three.js webgl - exporter - gltf

        + three.js webgl - exporter - gltf


        @@ -22,6 +22,7 @@ +
        + + + diff --git a/examples/misc_exporter_stl.html b/examples/misc_exporter_stl.html index e6e5e0211a3436..a63ec9ab8bf9a1 100644 --- a/examples/misc_exporter_stl.html +++ b/examples/misc_exporter_stl.html @@ -8,7 +8,7 @@
        - three.js webgl - exporter - stl

        + three.js webgl - exporter - stl

        diff --git a/examples/misc_fps.html b/examples/misc_fps.html deleted file mode 100644 index f7b379647f39b1..00000000000000 --- a/examples/misc_fps.html +++ /dev/null @@ -1,341 +0,0 @@ - - - - three.js - platformer demo - - - - - - -
        three.js - platformer demo. cubemap by Jochum Skoglund.
        Use arrow keys to look around, WASD to move and SPACE to jump.
        - - - - diff --git a/examples/misc_lookat.html b/examples/misc_lookat.html index c377330fab1759..8cae8d1af5d9b6 100644 --- a/examples/misc_lookat.html +++ b/examples/misc_lookat.html @@ -17,7 +17,7 @@ -
        three.js - Object3D.lookAt() example
        +
        three.js - Object3D.lookAt() example
        + + + diff --git a/examples/raytracing_sandbox.html b/examples/raytracing_sandbox.html deleted file mode 100644 index 9b7580742f9775..00000000000000 --- a/examples/raytracing_sandbox.html +++ /dev/null @@ -1,320 +0,0 @@ - - - - three.js - raytracing renderer with web workers - - - - - - -
        - three.js - raytracing renderer (using - web workers)
        - -
        - - - - - diff --git a/examples/screenshots/css2d_label.png b/examples/screenshots/css2d_label.png new file mode 100644 index 00000000000000..d012c2fe2dffcd Binary files /dev/null and b/examples/screenshots/css2d_label.png differ diff --git a/examples/screenshots/css3d_molecules.png b/examples/screenshots/css3d_molecules.png new file mode 100644 index 00000000000000..dffb0f97a3b696 Binary files /dev/null and b/examples/screenshots/css3d_molecules.png differ diff --git a/examples/screenshots/css3d_orthographic.png b/examples/screenshots/css3d_orthographic.png new file mode 100644 index 00000000000000..ed144813261564 Binary files /dev/null and b/examples/screenshots/css3d_orthographic.png differ diff --git a/examples/screenshots/css3d_panorama.png b/examples/screenshots/css3d_panorama.png new file mode 100644 index 00000000000000..4e60337d2e79d7 Binary files /dev/null and b/examples/screenshots/css3d_panorama.png differ diff --git a/examples/screenshots/css3d_panorama_deviceorientation.png b/examples/screenshots/css3d_panorama_deviceorientation.png new file mode 100644 index 00000000000000..b3fe209da7a819 Binary files /dev/null and b/examples/screenshots/css3d_panorama_deviceorientation.png differ diff --git a/examples/screenshots/css3d_periodictable.png b/examples/screenshots/css3d_periodictable.png new file mode 100644 index 00000000000000..8ea864c489a7ac Binary files /dev/null and b/examples/screenshots/css3d_periodictable.png differ diff --git a/examples/screenshots/css3d_sandbox.png b/examples/screenshots/css3d_sandbox.png new file mode 100644 index 00000000000000..2c8d6253a05b3a Binary files /dev/null and b/examples/screenshots/css3d_sandbox.png differ diff --git a/examples/screenshots/css3d_sprites.png b/examples/screenshots/css3d_sprites.png new file mode 100644 index 00000000000000..3995eb9077e194 Binary files /dev/null and b/examples/screenshots/css3d_sprites.png differ diff --git a/examples/screenshots/css3d_youtube.png b/examples/screenshots/css3d_youtube.png new file mode 100644 index 00000000000000..67e77458cd52a8 Binary files /dev/null and b/examples/screenshots/css3d_youtube.png differ diff --git a/examples/screenshots/misc_animation_authoring.png b/examples/screenshots/misc_animation_authoring.png new file mode 100644 index 00000000000000..723dc7f738e993 Binary files /dev/null and b/examples/screenshots/misc_animation_authoring.png differ diff --git a/examples/screenshots/misc_animation_groups.png b/examples/screenshots/misc_animation_groups.png new file mode 100644 index 00000000000000..73b96024c4dfaa Binary files /dev/null and b/examples/screenshots/misc_animation_groups.png differ diff --git a/examples/screenshots/misc_animation_keys.png b/examples/screenshots/misc_animation_keys.png new file mode 100644 index 00000000000000..fba0b66d70a793 Binary files /dev/null and b/examples/screenshots/misc_animation_keys.png differ diff --git a/examples/screenshots/misc_boxselection.png b/examples/screenshots/misc_boxselection.png new file mode 100644 index 00000000000000..20d71b8089a31d Binary files /dev/null and b/examples/screenshots/misc_boxselection.png differ diff --git a/examples/screenshots/misc_controls_deviceorientation.png b/examples/screenshots/misc_controls_deviceorientation.png new file mode 100644 index 00000000000000..7fc37e5746d738 Binary files /dev/null and b/examples/screenshots/misc_controls_deviceorientation.png differ diff --git a/examples/screenshots/misc_controls_drag.png b/examples/screenshots/misc_controls_drag.png new file mode 100644 index 00000000000000..52f4da218ec965 Binary files /dev/null and b/examples/screenshots/misc_controls_drag.png differ diff --git a/examples/screenshots/misc_controls_fly.png b/examples/screenshots/misc_controls_fly.png new file mode 100644 index 00000000000000..5beee88b5cd3ea Binary files /dev/null and b/examples/screenshots/misc_controls_fly.png differ diff --git a/examples/screenshots/misc_controls_map.png b/examples/screenshots/misc_controls_map.png new file mode 100644 index 00000000000000..455e0ae6b2dc1f Binary files /dev/null and b/examples/screenshots/misc_controls_map.png differ diff --git a/examples/screenshots/misc_controls_orbit.png b/examples/screenshots/misc_controls_orbit.png new file mode 100644 index 00000000000000..349b7fdcde8688 Binary files /dev/null and b/examples/screenshots/misc_controls_orbit.png differ diff --git a/examples/screenshots/misc_controls_pointerlock.png b/examples/screenshots/misc_controls_pointerlock.png new file mode 100644 index 00000000000000..532bec28bdaa4a Binary files /dev/null and b/examples/screenshots/misc_controls_pointerlock.png differ diff --git a/examples/screenshots/misc_controls_trackball.png b/examples/screenshots/misc_controls_trackball.png new file mode 100644 index 00000000000000..5a759066d456ff Binary files /dev/null and b/examples/screenshots/misc_controls_trackball.png differ diff --git a/examples/screenshots/misc_controls_transform.png b/examples/screenshots/misc_controls_transform.png new file mode 100644 index 00000000000000..7f591e5f25b45a Binary files /dev/null and b/examples/screenshots/misc_controls_transform.png differ diff --git a/examples/screenshots/misc_exporter_collada.png b/examples/screenshots/misc_exporter_collada.png new file mode 100644 index 00000000000000..6368b9443e5bb5 Binary files /dev/null and b/examples/screenshots/misc_exporter_collada.png differ diff --git a/examples/screenshots/misc_exporter_draco.png b/examples/screenshots/misc_exporter_draco.png new file mode 100644 index 00000000000000..0e0de5a8e8590b Binary files /dev/null and b/examples/screenshots/misc_exporter_draco.png differ diff --git a/examples/screenshots/misc_exporter_gltf.png b/examples/screenshots/misc_exporter_gltf.png new file mode 100644 index 00000000000000..f3bd7e40f8c532 Binary files /dev/null and b/examples/screenshots/misc_exporter_gltf.png differ diff --git a/examples/screenshots/misc_exporter_obj.png b/examples/screenshots/misc_exporter_obj.png new file mode 100644 index 00000000000000..ae429b7d1ce72a Binary files /dev/null and b/examples/screenshots/misc_exporter_obj.png differ diff --git a/examples/screenshots/misc_exporter_ply.png b/examples/screenshots/misc_exporter_ply.png new file mode 100644 index 00000000000000..899aa8292e075d Binary files /dev/null and b/examples/screenshots/misc_exporter_ply.png differ diff --git a/examples/screenshots/misc_exporter_stl.png b/examples/screenshots/misc_exporter_stl.png new file mode 100644 index 00000000000000..899aa8292e075d Binary files /dev/null and b/examples/screenshots/misc_exporter_stl.png differ diff --git a/examples/screenshots/misc_lookat.png b/examples/screenshots/misc_lookat.png new file mode 100644 index 00000000000000..a1b44e5e24d66a Binary files /dev/null and b/examples/screenshots/misc_lookat.png differ diff --git a/examples/screenshots/misc_uv_tests.png b/examples/screenshots/misc_uv_tests.png new file mode 100644 index 00000000000000..64595e5e372d80 Binary files /dev/null and b/examples/screenshots/misc_uv_tests.png differ diff --git a/examples/screenshots/physics_ammo_break.png b/examples/screenshots/physics_ammo_break.png new file mode 100644 index 00000000000000..02033c92dca9b5 Binary files /dev/null and b/examples/screenshots/physics_ammo_break.png differ diff --git a/examples/screenshots/physics_ammo_cloth.png b/examples/screenshots/physics_ammo_cloth.png new file mode 100644 index 00000000000000..d25f196bdb5858 Binary files /dev/null and b/examples/screenshots/physics_ammo_cloth.png differ diff --git a/examples/screenshots/physics_ammo_rope.png b/examples/screenshots/physics_ammo_rope.png new file mode 100644 index 00000000000000..cbb65de1a42fd1 Binary files /dev/null and b/examples/screenshots/physics_ammo_rope.png differ diff --git a/examples/screenshots/physics_ammo_terrain.png b/examples/screenshots/physics_ammo_terrain.png new file mode 100644 index 00000000000000..fc2eca2349c389 Binary files /dev/null and b/examples/screenshots/physics_ammo_terrain.png differ diff --git a/examples/screenshots/physics_ammo_volume.png b/examples/screenshots/physics_ammo_volume.png new file mode 100644 index 00000000000000..e66197a85b5711 Binary files /dev/null and b/examples/screenshots/physics_ammo_volume.png differ diff --git a/examples/screenshots/physics_cannon_instancing.png b/examples/screenshots/physics_cannon_instancing.png new file mode 100644 index 00000000000000..6d640018a5fbbd Binary files /dev/null and b/examples/screenshots/physics_cannon_instancing.png differ diff --git a/examples/screenshots/svg_lines.png b/examples/screenshots/svg_lines.png new file mode 100644 index 00000000000000..b488cb0620c4b8 Binary files /dev/null and b/examples/screenshots/svg_lines.png differ diff --git a/examples/screenshots/svg_sandbox.png b/examples/screenshots/svg_sandbox.png new file mode 100644 index 00000000000000..243ee7f81a7f07 Binary files /dev/null and b/examples/screenshots/svg_sandbox.png differ diff --git a/examples/screenshots/webaudio_orientation.png b/examples/screenshots/webaudio_orientation.png new file mode 100644 index 00000000000000..5a1473c67dfc46 Binary files /dev/null and b/examples/screenshots/webaudio_orientation.png differ diff --git a/examples/screenshots/webaudio_sandbox.png b/examples/screenshots/webaudio_sandbox.png new file mode 100644 index 00000000000000..317f3ebd9c50b0 Binary files /dev/null and b/examples/screenshots/webaudio_sandbox.png differ diff --git a/examples/screenshots/webaudio_timing.png b/examples/screenshots/webaudio_timing.png new file mode 100644 index 00000000000000..71a54bdb53fb88 Binary files /dev/null and b/examples/screenshots/webaudio_timing.png differ diff --git a/examples/screenshots/webaudio_visualizer.png b/examples/screenshots/webaudio_visualizer.png new file mode 100644 index 00000000000000..1e0b70dab90009 Binary files /dev/null and b/examples/screenshots/webaudio_visualizer.png differ diff --git a/examples/screenshots/webgl2_materials_texture2darray.png b/examples/screenshots/webgl2_materials_texture2darray.png new file mode 100644 index 00000000000000..586ad78ae71484 Binary files /dev/null and b/examples/screenshots/webgl2_materials_texture2darray.png differ diff --git a/examples/screenshots/webgl2_materials_texture3d.png b/examples/screenshots/webgl2_materials_texture3d.png new file mode 100644 index 00000000000000..08a44251439a85 Binary files /dev/null and b/examples/screenshots/webgl2_materials_texture3d.png differ diff --git a/examples/screenshots/webgl2_multisampled_renderbuffers.png b/examples/screenshots/webgl2_multisampled_renderbuffers.png new file mode 100644 index 00000000000000..f415da981c96e0 Binary files /dev/null and b/examples/screenshots/webgl2_multisampled_renderbuffers.png differ diff --git a/examples/screenshots/webgl2_sandbox.png b/examples/screenshots/webgl2_sandbox.png new file mode 100644 index 00000000000000..c607817c1cdeff Binary files /dev/null and b/examples/screenshots/webgl2_sandbox.png differ diff --git a/examples/screenshots/webgl_animation_cloth.png b/examples/screenshots/webgl_animation_cloth.png new file mode 100644 index 00000000000000..85b9c254ca0ed8 Binary files /dev/null and b/examples/screenshots/webgl_animation_cloth.png differ diff --git a/examples/screenshots/webgl_animation_keyframes.png b/examples/screenshots/webgl_animation_keyframes.png new file mode 100644 index 00000000000000..3494cc02471267 Binary files /dev/null and b/examples/screenshots/webgl_animation_keyframes.png differ diff --git a/examples/screenshots/webgl_animation_multiple.png b/examples/screenshots/webgl_animation_multiple.png new file mode 100644 index 00000000000000..5a7d5115ad6941 Binary files /dev/null and b/examples/screenshots/webgl_animation_multiple.png differ diff --git a/examples/screenshots/webgl_animation_skinning_blending.png b/examples/screenshots/webgl_animation_skinning_blending.png new file mode 100644 index 00000000000000..7af934a72629d0 Binary files /dev/null and b/examples/screenshots/webgl_animation_skinning_blending.png differ diff --git a/examples/screenshots/webgl_animation_skinning_morph.png b/examples/screenshots/webgl_animation_skinning_morph.png new file mode 100644 index 00000000000000..306dc901c20842 Binary files /dev/null and b/examples/screenshots/webgl_animation_skinning_morph.png differ diff --git a/examples/screenshots/webgl_buffergeometry.png b/examples/screenshots/webgl_buffergeometry.png new file mode 100644 index 00000000000000..40d0b60f25238f Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry.png differ diff --git a/examples/screenshots/webgl_buffergeometry_compression.png b/examples/screenshots/webgl_buffergeometry_compression.png new file mode 100644 index 00000000000000..149bc2d34910d5 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_compression.png differ diff --git a/examples/screenshots/webgl_buffergeometry_constructed_from_geometry.png b/examples/screenshots/webgl_buffergeometry_constructed_from_geometry.png new file mode 100644 index 00000000000000..27d315b5921ec3 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_constructed_from_geometry.png differ diff --git a/examples/screenshots/webgl_buffergeometry_custom_attributes_particles.png b/examples/screenshots/webgl_buffergeometry_custom_attributes_particles.png new file mode 100644 index 00000000000000..503ae05486cc09 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_custom_attributes_particles.png differ diff --git a/examples/screenshots/webgl_buffergeometry_drawrange.png b/examples/screenshots/webgl_buffergeometry_drawrange.png new file mode 100644 index 00000000000000..fa4d511eaca7ee Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_drawrange.png differ diff --git a/examples/screenshots/webgl_buffergeometry_indexed.png b/examples/screenshots/webgl_buffergeometry_indexed.png new file mode 100644 index 00000000000000..5102da936aa023 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_indexed.png differ diff --git a/examples/screenshots/webgl_buffergeometry_instancing.png b/examples/screenshots/webgl_buffergeometry_instancing.png new file mode 100644 index 00000000000000..bf1e0812ea24ad Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_instancing.png differ diff --git a/examples/screenshots/webgl_buffergeometry_instancing_billboards.png b/examples/screenshots/webgl_buffergeometry_instancing_billboards.png new file mode 100644 index 00000000000000..08c201115b85aa Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_instancing_billboards.png differ diff --git a/examples/screenshots/webgl_buffergeometry_instancing_interleaved.png b/examples/screenshots/webgl_buffergeometry_instancing_interleaved.png new file mode 100644 index 00000000000000..69d3ac50f44adf Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_instancing_interleaved.png differ diff --git a/examples/screenshots/webgl_buffergeometry_instancing_lambert.png b/examples/screenshots/webgl_buffergeometry_instancing_lambert.png new file mode 100644 index 00000000000000..44fb6b162026a1 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_instancing_lambert.png differ diff --git a/examples/screenshots/webgl_buffergeometry_lines.png b/examples/screenshots/webgl_buffergeometry_lines.png new file mode 100644 index 00000000000000..afbe2160fd3b82 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_lines.png differ diff --git a/examples/screenshots/webgl_buffergeometry_lines_indexed.png b/examples/screenshots/webgl_buffergeometry_lines_indexed.png new file mode 100644 index 00000000000000..16196c2fa6aa38 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_lines_indexed.png differ diff --git a/examples/screenshots/webgl_buffergeometry_morphtargets.png b/examples/screenshots/webgl_buffergeometry_morphtargets.png new file mode 100644 index 00000000000000..d2def1d1e3f3f4 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_morphtargets.png differ diff --git a/examples/screenshots/webgl_buffergeometry_points.png b/examples/screenshots/webgl_buffergeometry_points.png new file mode 100644 index 00000000000000..a50b40b018b2b8 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_points.png differ diff --git a/examples/screenshots/webgl_buffergeometry_points_interleaved.png b/examples/screenshots/webgl_buffergeometry_points_interleaved.png new file mode 100644 index 00000000000000..bcac60fccdd8f8 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_points_interleaved.png differ diff --git a/examples/screenshots/webgl_buffergeometry_rawshader.png b/examples/screenshots/webgl_buffergeometry_rawshader.png new file mode 100644 index 00000000000000..cd8ac653024326 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_rawshader.png differ diff --git a/examples/screenshots/webgl_buffergeometry_selective_draw.png b/examples/screenshots/webgl_buffergeometry_selective_draw.png new file mode 100644 index 00000000000000..58b4ccf904a903 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_selective_draw.png differ diff --git a/examples/screenshots/webgl_buffergeometry_uint.png b/examples/screenshots/webgl_buffergeometry_uint.png new file mode 100644 index 00000000000000..c0a36d5f13a406 Binary files /dev/null and b/examples/screenshots/webgl_buffergeometry_uint.png differ diff --git a/examples/screenshots/webgl_camera.png b/examples/screenshots/webgl_camera.png new file mode 100644 index 00000000000000..db6403eede3000 Binary files /dev/null and b/examples/screenshots/webgl_camera.png differ diff --git a/examples/screenshots/webgl_camera_array.png b/examples/screenshots/webgl_camera_array.png new file mode 100644 index 00000000000000..a03eef85d1e9a0 Binary files /dev/null and b/examples/screenshots/webgl_camera_array.png differ diff --git a/examples/screenshots/webgl_camera_cinematic.png b/examples/screenshots/webgl_camera_cinematic.png new file mode 100644 index 00000000000000..f0fa0ddf380bb0 Binary files /dev/null and b/examples/screenshots/webgl_camera_cinematic.png differ diff --git a/examples/screenshots/webgl_camera_logarithmicdepthbuffer.png b/examples/screenshots/webgl_camera_logarithmicdepthbuffer.png new file mode 100644 index 00000000000000..1a29c80b234f64 Binary files /dev/null and b/examples/screenshots/webgl_camera_logarithmicdepthbuffer.png differ diff --git a/examples/screenshots/webgl_clipping.png b/examples/screenshots/webgl_clipping.png new file mode 100644 index 00000000000000..5f2578fcdc417b Binary files /dev/null and b/examples/screenshots/webgl_clipping.png differ diff --git a/examples/screenshots/webgl_clipping_advanced.png b/examples/screenshots/webgl_clipping_advanced.png new file mode 100644 index 00000000000000..eb4ca928db3af4 Binary files /dev/null and b/examples/screenshots/webgl_clipping_advanced.png differ diff --git a/examples/screenshots/webgl_clipping_intersection.png b/examples/screenshots/webgl_clipping_intersection.png new file mode 100644 index 00000000000000..624c70a065810f Binary files /dev/null and b/examples/screenshots/webgl_clipping_intersection.png differ diff --git a/examples/screenshots/webgl_clipping_stencil.png b/examples/screenshots/webgl_clipping_stencil.png new file mode 100644 index 00000000000000..2096e3178f7da3 Binary files /dev/null and b/examples/screenshots/webgl_clipping_stencil.png differ diff --git a/examples/screenshots/webgl_custom_attributes.png b/examples/screenshots/webgl_custom_attributes.png new file mode 100644 index 00000000000000..decea25e4b219d Binary files /dev/null and b/examples/screenshots/webgl_custom_attributes.png differ diff --git a/examples/screenshots/webgl_custom_attributes_lines.png b/examples/screenshots/webgl_custom_attributes_lines.png new file mode 100644 index 00000000000000..fb84e8aad0bf12 Binary files /dev/null and b/examples/screenshots/webgl_custom_attributes_lines.png differ diff --git a/examples/screenshots/webgl_custom_attributes_points.png b/examples/screenshots/webgl_custom_attributes_points.png new file mode 100644 index 00000000000000..af4d666c5f1c5e Binary files /dev/null and b/examples/screenshots/webgl_custom_attributes_points.png differ diff --git a/examples/screenshots/webgl_custom_attributes_points2.png b/examples/screenshots/webgl_custom_attributes_points2.png new file mode 100644 index 00000000000000..555cc968e77941 Binary files /dev/null and b/examples/screenshots/webgl_custom_attributes_points2.png differ diff --git a/examples/screenshots/webgl_custom_attributes_points3.png b/examples/screenshots/webgl_custom_attributes_points3.png new file mode 100644 index 00000000000000..619e63f3a11a32 Binary files /dev/null and b/examples/screenshots/webgl_custom_attributes_points3.png differ diff --git a/examples/screenshots/webgl_decals.png b/examples/screenshots/webgl_decals.png new file mode 100644 index 00000000000000..ec30804a992a7a Binary files /dev/null and b/examples/screenshots/webgl_decals.png differ diff --git a/examples/screenshots/webgl_depth_texture.png b/examples/screenshots/webgl_depth_texture.png new file mode 100644 index 00000000000000..fbeccfccfbf17e Binary files /dev/null and b/examples/screenshots/webgl_depth_texture.png differ diff --git a/examples/screenshots/webgl_effects_anaglyph.png b/examples/screenshots/webgl_effects_anaglyph.png new file mode 100644 index 00000000000000..26f8dafb5af1ce Binary files /dev/null and b/examples/screenshots/webgl_effects_anaglyph.png differ diff --git a/examples/screenshots/webgl_effects_ascii.png b/examples/screenshots/webgl_effects_ascii.png new file mode 100644 index 00000000000000..8a87d7675a141c Binary files /dev/null and b/examples/screenshots/webgl_effects_ascii.png differ diff --git a/examples/screenshots/webgl_effects_parallaxbarrier.png b/examples/screenshots/webgl_effects_parallaxbarrier.png new file mode 100644 index 00000000000000..bd5917e46f742e Binary files /dev/null and b/examples/screenshots/webgl_effects_parallaxbarrier.png differ diff --git a/examples/screenshots/webgl_effects_peppersghost.png b/examples/screenshots/webgl_effects_peppersghost.png new file mode 100644 index 00000000000000..4975eb06fcfb6b Binary files /dev/null and b/examples/screenshots/webgl_effects_peppersghost.png differ diff --git a/examples/screenshots/webgl_effects_stereo.png b/examples/screenshots/webgl_effects_stereo.png new file mode 100644 index 00000000000000..ab3e7cb529f8a5 Binary files /dev/null and b/examples/screenshots/webgl_effects_stereo.png differ diff --git a/examples/screenshots/webgl_fire.png b/examples/screenshots/webgl_fire.png new file mode 100644 index 00000000000000..e8763076131159 Binary files /dev/null and b/examples/screenshots/webgl_fire.png differ diff --git a/examples/screenshots/webgl_framebuffer_texture.png b/examples/screenshots/webgl_framebuffer_texture.png new file mode 100644 index 00000000000000..4302f0e7b0c71c Binary files /dev/null and b/examples/screenshots/webgl_framebuffer_texture.png differ diff --git a/examples/screenshots/webgl_furnace_test.png b/examples/screenshots/webgl_furnace_test.png new file mode 100644 index 00000000000000..a15edf5c1593d5 Binary files /dev/null and b/examples/screenshots/webgl_furnace_test.png differ diff --git a/examples/screenshots/webgl_geometries.png b/examples/screenshots/webgl_geometries.png new file mode 100644 index 00000000000000..6adf174ea731bd Binary files /dev/null and b/examples/screenshots/webgl_geometries.png differ diff --git a/examples/screenshots/webgl_geometries_parametric.png b/examples/screenshots/webgl_geometries_parametric.png new file mode 100644 index 00000000000000..e8c4d433c43a01 Binary files /dev/null and b/examples/screenshots/webgl_geometries_parametric.png differ diff --git a/examples/screenshots/webgl_geometry_colors.png b/examples/screenshots/webgl_geometry_colors.png new file mode 100644 index 00000000000000..bed8cd7f834b7b Binary files /dev/null and b/examples/screenshots/webgl_geometry_colors.png differ diff --git a/examples/screenshots/webgl_geometry_colors_lookuptable.png b/examples/screenshots/webgl_geometry_colors_lookuptable.png new file mode 100644 index 00000000000000..b9c410899ff50f Binary files /dev/null and b/examples/screenshots/webgl_geometry_colors_lookuptable.png differ diff --git a/examples/screenshots/webgl_geometry_convex.png b/examples/screenshots/webgl_geometry_convex.png new file mode 100644 index 00000000000000..7f4de097ec2f27 Binary files /dev/null and b/examples/screenshots/webgl_geometry_convex.png differ diff --git a/examples/screenshots/webgl_geometry_cube.png b/examples/screenshots/webgl_geometry_cube.png new file mode 100644 index 00000000000000..d1592a3fe94190 Binary files /dev/null and b/examples/screenshots/webgl_geometry_cube.png differ diff --git a/examples/screenshots/webgl_geometry_dynamic.png b/examples/screenshots/webgl_geometry_dynamic.png new file mode 100644 index 00000000000000..ed25a0e25a2429 Binary files /dev/null and b/examples/screenshots/webgl_geometry_dynamic.png differ diff --git a/examples/screenshots/webgl_geometry_extrude_shapes.png b/examples/screenshots/webgl_geometry_extrude_shapes.png new file mode 100644 index 00000000000000..bdf0a45a81fde4 Binary files /dev/null and b/examples/screenshots/webgl_geometry_extrude_shapes.png differ diff --git a/examples/screenshots/webgl_geometry_extrude_shapes2.png b/examples/screenshots/webgl_geometry_extrude_shapes2.png new file mode 100644 index 00000000000000..6376fb79327cb0 Binary files /dev/null and b/examples/screenshots/webgl_geometry_extrude_shapes2.png differ diff --git a/examples/screenshots/webgl_geometry_extrude_splines.png b/examples/screenshots/webgl_geometry_extrude_splines.png new file mode 100644 index 00000000000000..d5c4d6d8883649 Binary files /dev/null and b/examples/screenshots/webgl_geometry_extrude_splines.png differ diff --git a/examples/screenshots/webgl_geometry_hierarchy.png b/examples/screenshots/webgl_geometry_hierarchy.png new file mode 100644 index 00000000000000..fc3f49be22c4bd Binary files /dev/null and b/examples/screenshots/webgl_geometry_hierarchy.png differ diff --git a/examples/screenshots/webgl_geometry_hierarchy2.png b/examples/screenshots/webgl_geometry_hierarchy2.png new file mode 100644 index 00000000000000..0fb9985581ccce Binary files /dev/null and b/examples/screenshots/webgl_geometry_hierarchy2.png differ diff --git a/examples/screenshots/webgl_geometry_minecraft.png b/examples/screenshots/webgl_geometry_minecraft.png new file mode 100644 index 00000000000000..ca99a65a0825cc Binary files /dev/null and b/examples/screenshots/webgl_geometry_minecraft.png differ diff --git a/examples/screenshots/webgl_geometry_minecraft_ao.png b/examples/screenshots/webgl_geometry_minecraft_ao.png new file mode 100644 index 00000000000000..75ee037b035cef Binary files /dev/null and b/examples/screenshots/webgl_geometry_minecraft_ao.png differ diff --git a/examples/screenshots/webgl_geometry_normals.png b/examples/screenshots/webgl_geometry_normals.png new file mode 100644 index 00000000000000..92acdcc352ba8a Binary files /dev/null and b/examples/screenshots/webgl_geometry_normals.png differ diff --git a/examples/screenshots/webgl_geometry_nurbs.png b/examples/screenshots/webgl_geometry_nurbs.png new file mode 100644 index 00000000000000..2bcf8412a68f25 Binary files /dev/null and b/examples/screenshots/webgl_geometry_nurbs.png differ diff --git a/examples/screenshots/webgl_geometry_shapes.png b/examples/screenshots/webgl_geometry_shapes.png new file mode 100644 index 00000000000000..4386f63328988b Binary files /dev/null and b/examples/screenshots/webgl_geometry_shapes.png differ diff --git a/examples/screenshots/webgl_geometry_spline_editor.png b/examples/screenshots/webgl_geometry_spline_editor.png new file mode 100644 index 00000000000000..a2542f622f0183 Binary files /dev/null and b/examples/screenshots/webgl_geometry_spline_editor.png differ diff --git a/examples/screenshots/webgl_geometry_teapot.png b/examples/screenshots/webgl_geometry_teapot.png new file mode 100644 index 00000000000000..6368b9443e5bb5 Binary files /dev/null and b/examples/screenshots/webgl_geometry_teapot.png differ diff --git a/examples/screenshots/webgl_geometry_terrain.png b/examples/screenshots/webgl_geometry_terrain.png new file mode 100644 index 00000000000000..575eb5b7f33119 Binary files /dev/null and b/examples/screenshots/webgl_geometry_terrain.png differ diff --git a/examples/screenshots/webgl_geometry_terrain_fog.png b/examples/screenshots/webgl_geometry_terrain_fog.png new file mode 100644 index 00000000000000..7b18f830eeebe6 Binary files /dev/null and b/examples/screenshots/webgl_geometry_terrain_fog.png differ diff --git a/examples/screenshots/webgl_geometry_terrain_raycast.png b/examples/screenshots/webgl_geometry_terrain_raycast.png new file mode 100644 index 00000000000000..f227b9d584452f Binary files /dev/null and b/examples/screenshots/webgl_geometry_terrain_raycast.png differ diff --git a/examples/screenshots/webgl_geometry_text.png b/examples/screenshots/webgl_geometry_text.png new file mode 100644 index 00000000000000..68779acbe5873a Binary files /dev/null and b/examples/screenshots/webgl_geometry_text.png differ diff --git a/examples/screenshots/webgl_geometry_text_shapes.png b/examples/screenshots/webgl_geometry_text_shapes.png new file mode 100644 index 00000000000000..54d4e762ba622f Binary files /dev/null and b/examples/screenshots/webgl_geometry_text_shapes.png differ diff --git a/examples/screenshots/webgl_geometry_text_stroke.png b/examples/screenshots/webgl_geometry_text_stroke.png new file mode 100644 index 00000000000000..60b4e5b5907dcd Binary files /dev/null and b/examples/screenshots/webgl_geometry_text_stroke.png differ diff --git a/examples/screenshots/webgl_gpgpu_birds.png b/examples/screenshots/webgl_gpgpu_birds.png new file mode 100644 index 00000000000000..cdef73122a01e4 Binary files /dev/null and b/examples/screenshots/webgl_gpgpu_birds.png differ diff --git a/examples/screenshots/webgl_gpgpu_protoplanet.png b/examples/screenshots/webgl_gpgpu_protoplanet.png new file mode 100644 index 00000000000000..29f0cad7d6422a Binary files /dev/null and b/examples/screenshots/webgl_gpgpu_protoplanet.png differ diff --git a/examples/screenshots/webgl_gpgpu_water.png b/examples/screenshots/webgl_gpgpu_water.png new file mode 100644 index 00000000000000..c4e740fabde282 Binary files /dev/null and b/examples/screenshots/webgl_gpgpu_water.png differ diff --git a/examples/screenshots/webgl_helpers.png b/examples/screenshots/webgl_helpers.png new file mode 100644 index 00000000000000..fd90203687690e Binary files /dev/null and b/examples/screenshots/webgl_helpers.png differ diff --git a/examples/screenshots/webgl_instancing_dynamic.png b/examples/screenshots/webgl_instancing_dynamic.png new file mode 100644 index 00000000000000..7aa393775cbde5 Binary files /dev/null and b/examples/screenshots/webgl_instancing_dynamic.png differ diff --git a/examples/screenshots/webgl_instancing_modified.png b/examples/screenshots/webgl_instancing_modified.png new file mode 100644 index 00000000000000..dc1e0d7cbb2b0b Binary files /dev/null and b/examples/screenshots/webgl_instancing_modified.png differ diff --git a/examples/screenshots/webgl_instancing_performance.png b/examples/screenshots/webgl_instancing_performance.png new file mode 100644 index 00000000000000..3d1ba876931230 Binary files /dev/null and b/examples/screenshots/webgl_instancing_performance.png differ diff --git a/examples/screenshots/webgl_instancing_raycast.png b/examples/screenshots/webgl_instancing_raycast.png new file mode 100644 index 00000000000000..7b728e2eab0572 Binary files /dev/null and b/examples/screenshots/webgl_instancing_raycast.png differ diff --git a/examples/screenshots/webgl_instancing_scatter.png b/examples/screenshots/webgl_instancing_scatter.png new file mode 100644 index 00000000000000..aabe1d814c8413 Binary files /dev/null and b/examples/screenshots/webgl_instancing_scatter.png differ diff --git a/examples/screenshots/webgl_interactive_buffergeometry.png b/examples/screenshots/webgl_interactive_buffergeometry.png new file mode 100644 index 00000000000000..1332b451f4ce68 Binary files /dev/null and b/examples/screenshots/webgl_interactive_buffergeometry.png differ diff --git a/examples/screenshots/webgl_interactive_cubes.png b/examples/screenshots/webgl_interactive_cubes.png new file mode 100644 index 00000000000000..9d7ef812907513 Binary files /dev/null and b/examples/screenshots/webgl_interactive_cubes.png differ diff --git a/examples/screenshots/webgl_interactive_cubes_gpu.png b/examples/screenshots/webgl_interactive_cubes_gpu.png new file mode 100644 index 00000000000000..d0da0926a02693 Binary files /dev/null and b/examples/screenshots/webgl_interactive_cubes_gpu.png differ diff --git a/examples/screenshots/webgl_interactive_cubes_ortho.png b/examples/screenshots/webgl_interactive_cubes_ortho.png new file mode 100644 index 00000000000000..f2a2ea475fc5d2 Binary files /dev/null and b/examples/screenshots/webgl_interactive_cubes_ortho.png differ diff --git a/examples/screenshots/webgl_interactive_lines.png b/examples/screenshots/webgl_interactive_lines.png new file mode 100644 index 00000000000000..9af4720b03a887 Binary files /dev/null and b/examples/screenshots/webgl_interactive_lines.png differ diff --git a/examples/screenshots/webgl_interactive_points.png b/examples/screenshots/webgl_interactive_points.png new file mode 100644 index 00000000000000..d5e3c5d7eba135 Binary files /dev/null and b/examples/screenshots/webgl_interactive_points.png differ diff --git a/examples/screenshots/webgl_interactive_raycasting_points.png b/examples/screenshots/webgl_interactive_raycasting_points.png new file mode 100644 index 00000000000000..c6569bc6d4c69e Binary files /dev/null and b/examples/screenshots/webgl_interactive_raycasting_points.png differ diff --git a/examples/screenshots/webgl_interactive_voxelpainter.png b/examples/screenshots/webgl_interactive_voxelpainter.png new file mode 100644 index 00000000000000..8c990ce943ea83 Binary files /dev/null and b/examples/screenshots/webgl_interactive_voxelpainter.png differ diff --git a/examples/screenshots/webgl_kinect.png b/examples/screenshots/webgl_kinect.png new file mode 100644 index 00000000000000..4370fdc06ff70e Binary files /dev/null and b/examples/screenshots/webgl_kinect.png differ diff --git a/examples/screenshots/webgl_layers.png b/examples/screenshots/webgl_layers.png new file mode 100644 index 00000000000000..f0f28424cc9d41 Binary files /dev/null and b/examples/screenshots/webgl_layers.png differ diff --git a/examples/screenshots/webgl_lensflares.png b/examples/screenshots/webgl_lensflares.png new file mode 100644 index 00000000000000..71ad5e249bbea5 Binary files /dev/null and b/examples/screenshots/webgl_lensflares.png differ diff --git a/examples/screenshots/webgl_lightningstrike.png b/examples/screenshots/webgl_lightningstrike.png new file mode 100644 index 00000000000000..b0dd1c4d29d345 Binary files /dev/null and b/examples/screenshots/webgl_lightningstrike.png differ diff --git a/examples/screenshots/webgl_lightprobe.png b/examples/screenshots/webgl_lightprobe.png new file mode 100644 index 00000000000000..05d1caa808bb4f Binary files /dev/null and b/examples/screenshots/webgl_lightprobe.png differ diff --git a/examples/screenshots/webgl_lightprobe_cubecamera.png b/examples/screenshots/webgl_lightprobe_cubecamera.png new file mode 100644 index 00000000000000..756e35033509bc Binary files /dev/null and b/examples/screenshots/webgl_lightprobe_cubecamera.png differ diff --git a/examples/screenshots/webgl_lights_hemisphere.png b/examples/screenshots/webgl_lights_hemisphere.png new file mode 100644 index 00000000000000..4cae10d7cc15d5 Binary files /dev/null and b/examples/screenshots/webgl_lights_hemisphere.png differ diff --git a/examples/screenshots/webgl_lights_physical.png b/examples/screenshots/webgl_lights_physical.png new file mode 100644 index 00000000000000..0a75f0fdb0ea7e Binary files /dev/null and b/examples/screenshots/webgl_lights_physical.png differ diff --git a/examples/screenshots/webgl_lights_pointlights.png b/examples/screenshots/webgl_lights_pointlights.png new file mode 100644 index 00000000000000..fb42a635d554b7 Binary files /dev/null and b/examples/screenshots/webgl_lights_pointlights.png differ diff --git a/examples/screenshots/webgl_lights_pointlights2.png b/examples/screenshots/webgl_lights_pointlights2.png new file mode 100644 index 00000000000000..f574f7817b2014 Binary files /dev/null and b/examples/screenshots/webgl_lights_pointlights2.png differ diff --git a/examples/screenshots/webgl_lights_rectarealight.png b/examples/screenshots/webgl_lights_rectarealight.png new file mode 100644 index 00000000000000..45bcb15db2a4a6 Binary files /dev/null and b/examples/screenshots/webgl_lights_rectarealight.png differ diff --git a/examples/screenshots/webgl_lights_spotlight.png b/examples/screenshots/webgl_lights_spotlight.png new file mode 100644 index 00000000000000..d2dd4cb6302d23 Binary files /dev/null and b/examples/screenshots/webgl_lights_spotlight.png differ diff --git a/examples/screenshots/webgl_lights_spotlights.png b/examples/screenshots/webgl_lights_spotlights.png new file mode 100644 index 00000000000000..de6b6af276bf8f Binary files /dev/null and b/examples/screenshots/webgl_lights_spotlights.png differ diff --git a/examples/screenshots/webgl_lightshafts.png b/examples/screenshots/webgl_lightshafts.png new file mode 100644 index 00000000000000..54f2363ad36a9a Binary files /dev/null and b/examples/screenshots/webgl_lightshafts.png differ diff --git a/examples/screenshots/webgl_lines_colors.png b/examples/screenshots/webgl_lines_colors.png new file mode 100644 index 00000000000000..7927fc0ffbd92d Binary files /dev/null and b/examples/screenshots/webgl_lines_colors.png differ diff --git a/examples/screenshots/webgl_lines_dashed.png b/examples/screenshots/webgl_lines_dashed.png new file mode 100644 index 00000000000000..307b78bcb50425 Binary files /dev/null and b/examples/screenshots/webgl_lines_dashed.png differ diff --git a/examples/screenshots/webgl_lines_fat.png b/examples/screenshots/webgl_lines_fat.png new file mode 100644 index 00000000000000..23c8707e9382a2 Binary files /dev/null and b/examples/screenshots/webgl_lines_fat.png differ diff --git a/examples/screenshots/webgl_lines_fat_wireframe.png b/examples/screenshots/webgl_lines_fat_wireframe.png new file mode 100644 index 00000000000000..686303d6edf950 Binary files /dev/null and b/examples/screenshots/webgl_lines_fat_wireframe.png differ diff --git a/examples/screenshots/webgl_lines_sphere.png b/examples/screenshots/webgl_lines_sphere.png new file mode 100644 index 00000000000000..79428df323a95f Binary files /dev/null and b/examples/screenshots/webgl_lines_sphere.png differ diff --git a/examples/screenshots/webgl_loader_3ds.png b/examples/screenshots/webgl_loader_3ds.png new file mode 100644 index 00000000000000..11c9dcf8bbd5d5 Binary files /dev/null and b/examples/screenshots/webgl_loader_3ds.png differ diff --git a/examples/screenshots/webgl_loader_3mf.png b/examples/screenshots/webgl_loader_3mf.png new file mode 100644 index 00000000000000..a3e852e1b0b244 Binary files /dev/null and b/examples/screenshots/webgl_loader_3mf.png differ diff --git a/examples/screenshots/webgl_loader_3mf_materials.png b/examples/screenshots/webgl_loader_3mf_materials.png new file mode 100644 index 00000000000000..746bcab06811fb Binary files /dev/null and b/examples/screenshots/webgl_loader_3mf_materials.png differ diff --git a/examples/screenshots/webgl_loader_amf.png b/examples/screenshots/webgl_loader_amf.png new file mode 100644 index 00000000000000..9374bd9b7f3fbc Binary files /dev/null and b/examples/screenshots/webgl_loader_amf.png differ diff --git a/examples/screenshots/webgl_loader_assimp.png b/examples/screenshots/webgl_loader_assimp.png new file mode 100644 index 00000000000000..6acdc55c8ef013 Binary files /dev/null and b/examples/screenshots/webgl_loader_assimp.png differ diff --git a/examples/screenshots/webgl_loader_bvh.png b/examples/screenshots/webgl_loader_bvh.png new file mode 100644 index 00000000000000..d2c0846ae91a74 Binary files /dev/null and b/examples/screenshots/webgl_loader_bvh.png differ diff --git a/examples/screenshots/webgl_loader_collada.png b/examples/screenshots/webgl_loader_collada.png new file mode 100644 index 00000000000000..ee3f5dcdaae3ee Binary files /dev/null and b/examples/screenshots/webgl_loader_collada.png differ diff --git a/examples/screenshots/webgl_loader_collada_kinematics.png b/examples/screenshots/webgl_loader_collada_kinematics.png new file mode 100644 index 00000000000000..9f24f4f31a34ee Binary files /dev/null and b/examples/screenshots/webgl_loader_collada_kinematics.png differ diff --git a/examples/screenshots/webgl_loader_collada_skinning.png b/examples/screenshots/webgl_loader_collada_skinning.png new file mode 100644 index 00000000000000..f4b43555781cd0 Binary files /dev/null and b/examples/screenshots/webgl_loader_collada_skinning.png differ diff --git a/examples/screenshots/webgl_loader_draco.png b/examples/screenshots/webgl_loader_draco.png new file mode 100644 index 00000000000000..54de604546b62e Binary files /dev/null and b/examples/screenshots/webgl_loader_draco.png differ diff --git a/examples/screenshots/webgl_loader_fbx.png b/examples/screenshots/webgl_loader_fbx.png new file mode 100644 index 00000000000000..e105b55a47c9b9 Binary files /dev/null and b/examples/screenshots/webgl_loader_fbx.png differ diff --git a/examples/screenshots/webgl_loader_fbx_nurbs.png b/examples/screenshots/webgl_loader_fbx_nurbs.png new file mode 100644 index 00000000000000..035c925bf7aea8 Binary files /dev/null and b/examples/screenshots/webgl_loader_fbx_nurbs.png differ diff --git a/examples/screenshots/webgl_loader_gcode.png b/examples/screenshots/webgl_loader_gcode.png new file mode 100644 index 00000000000000..5684d107b613fb Binary files /dev/null and b/examples/screenshots/webgl_loader_gcode.png differ diff --git a/examples/screenshots/webgl_loader_gltf.png b/examples/screenshots/webgl_loader_gltf.png new file mode 100644 index 00000000000000..238e0d2ae4d5bd Binary files /dev/null and b/examples/screenshots/webgl_loader_gltf.png differ diff --git a/examples/screenshots/webgl_loader_gltf_extensions.png b/examples/screenshots/webgl_loader_gltf_extensions.png new file mode 100644 index 00000000000000..a8a13e568f4e02 Binary files /dev/null and b/examples/screenshots/webgl_loader_gltf_extensions.png differ diff --git a/examples/screenshots/webgl_loader_imagebitmap.png b/examples/screenshots/webgl_loader_imagebitmap.png new file mode 100644 index 00000000000000..dd5c6373322701 Binary files /dev/null and b/examples/screenshots/webgl_loader_imagebitmap.png differ diff --git a/examples/screenshots/webgl_loader_json_claraio.png b/examples/screenshots/webgl_loader_json_claraio.png new file mode 100644 index 00000000000000..8d3861e20a4da5 Binary files /dev/null and b/examples/screenshots/webgl_loader_json_claraio.png differ diff --git a/examples/screenshots/webgl_loader_kmz.png b/examples/screenshots/webgl_loader_kmz.png new file mode 100644 index 00000000000000..292387b289f344 Binary files /dev/null and b/examples/screenshots/webgl_loader_kmz.png differ diff --git a/examples/screenshots/webgl_loader_ldraw.png b/examples/screenshots/webgl_loader_ldraw.png new file mode 100644 index 00000000000000..c84afe66ae93f0 Binary files /dev/null and b/examples/screenshots/webgl_loader_ldraw.png differ diff --git a/examples/screenshots/webgl_loader_lwo.png b/examples/screenshots/webgl_loader_lwo.png new file mode 100644 index 00000000000000..3a4ebe7e71c5fe Binary files /dev/null and b/examples/screenshots/webgl_loader_lwo.png differ diff --git a/examples/screenshots/webgl_loader_md2.png b/examples/screenshots/webgl_loader_md2.png new file mode 100644 index 00000000000000..afae1358cf7abd Binary files /dev/null and b/examples/screenshots/webgl_loader_md2.png differ diff --git a/examples/screenshots/webgl_loader_md2_control.png b/examples/screenshots/webgl_loader_md2_control.png new file mode 100644 index 00000000000000..092f3f12eb8e81 Binary files /dev/null and b/examples/screenshots/webgl_loader_md2_control.png differ diff --git a/examples/screenshots/webgl_loader_mmd.png b/examples/screenshots/webgl_loader_mmd.png new file mode 100644 index 00000000000000..daf1e48d4a7b2d Binary files /dev/null and b/examples/screenshots/webgl_loader_mmd.png differ diff --git a/examples/screenshots/webgl_loader_mmd_audio.png b/examples/screenshots/webgl_loader_mmd_audio.png new file mode 100644 index 00000000000000..ddf70b7e5d91a6 Binary files /dev/null and b/examples/screenshots/webgl_loader_mmd_audio.png differ diff --git a/examples/screenshots/webgl_loader_mmd_pose.png b/examples/screenshots/webgl_loader_mmd_pose.png new file mode 100644 index 00000000000000..5af1437da2a24f Binary files /dev/null and b/examples/screenshots/webgl_loader_mmd_pose.png differ diff --git a/examples/screenshots/webgl_loader_nodes.png b/examples/screenshots/webgl_loader_nodes.png new file mode 100644 index 00000000000000..c5b15dd255f69f Binary files /dev/null and b/examples/screenshots/webgl_loader_nodes.png differ diff --git a/examples/screenshots/webgl_loader_nrrd.png b/examples/screenshots/webgl_loader_nrrd.png new file mode 100644 index 00000000000000..b0f1c95babb378 Binary files /dev/null and b/examples/screenshots/webgl_loader_nrrd.png differ diff --git a/examples/screenshots/webgl_loader_obj.png b/examples/screenshots/webgl_loader_obj.png new file mode 100644 index 00000000000000..a4268cf1af5886 Binary files /dev/null and b/examples/screenshots/webgl_loader_obj.png differ diff --git a/examples/screenshots/webgl_loader_obj2.png b/examples/screenshots/webgl_loader_obj2.png new file mode 100644 index 00000000000000..3bcf4282be3db4 Binary files /dev/null and b/examples/screenshots/webgl_loader_obj2.png differ diff --git a/examples/screenshots/webgl_loader_obj2_options.png b/examples/screenshots/webgl_loader_obj2_options.png new file mode 100644 index 00000000000000..1fed378afe93c5 Binary files /dev/null and b/examples/screenshots/webgl_loader_obj2_options.png differ diff --git a/examples/screenshots/webgl_loader_obj_mtl.png b/examples/screenshots/webgl_loader_obj_mtl.png new file mode 100644 index 00000000000000..a2fc477f650cda Binary files /dev/null and b/examples/screenshots/webgl_loader_obj_mtl.png differ diff --git a/examples/screenshots/webgl_loader_pcd.png b/examples/screenshots/webgl_loader_pcd.png new file mode 100644 index 00000000000000..ec171f54c202ec Binary files /dev/null and b/examples/screenshots/webgl_loader_pcd.png differ diff --git a/examples/screenshots/webgl_loader_pdb.png b/examples/screenshots/webgl_loader_pdb.png new file mode 100644 index 00000000000000..f2af950073192a Binary files /dev/null and b/examples/screenshots/webgl_loader_pdb.png differ diff --git a/examples/screenshots/webgl_loader_ply.png b/examples/screenshots/webgl_loader_ply.png new file mode 100644 index 00000000000000..da863e950640e3 Binary files /dev/null and b/examples/screenshots/webgl_loader_ply.png differ diff --git a/examples/screenshots/webgl_loader_prwm.png b/examples/screenshots/webgl_loader_prwm.png new file mode 100644 index 00000000000000..b6032156634377 Binary files /dev/null and b/examples/screenshots/webgl_loader_prwm.png differ diff --git a/examples/screenshots/webgl_loader_stl.png b/examples/screenshots/webgl_loader_stl.png new file mode 100644 index 00000000000000..6f59edf9b49e2e Binary files /dev/null and b/examples/screenshots/webgl_loader_stl.png differ diff --git a/examples/screenshots/webgl_loader_svg.png b/examples/screenshots/webgl_loader_svg.png new file mode 100644 index 00000000000000..080ad37d3b945e Binary files /dev/null and b/examples/screenshots/webgl_loader_svg.png differ diff --git a/examples/screenshots/webgl_loader_texture_basis.png b/examples/screenshots/webgl_loader_texture_basis.png new file mode 100644 index 00000000000000..60a4568c8c6b90 Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_basis.png differ diff --git a/examples/screenshots/webgl_loader_texture_dds.png b/examples/screenshots/webgl_loader_texture_dds.png new file mode 100644 index 00000000000000..170b2b48911c17 Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_dds.png differ diff --git a/examples/screenshots/webgl_loader_texture_exr.png b/examples/screenshots/webgl_loader_texture_exr.png new file mode 100644 index 00000000000000..80de80e5cb8ac4 Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_exr.png differ diff --git a/examples/screenshots/webgl_loader_texture_hdr.png b/examples/screenshots/webgl_loader_texture_hdr.png new file mode 100644 index 00000000000000..0663d0b89c4105 Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_hdr.png differ diff --git a/examples/screenshots/webgl_loader_texture_ktx.png b/examples/screenshots/webgl_loader_texture_ktx.png new file mode 100644 index 00000000000000..e9f6f3f7c84e5d Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_ktx.png differ diff --git a/examples/screenshots/webgl_loader_texture_pvrtc.png b/examples/screenshots/webgl_loader_texture_pvrtc.png new file mode 100644 index 00000000000000..38456f88261d57 Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_pvrtc.png differ diff --git a/examples/screenshots/webgl_loader_texture_rgbm.png b/examples/screenshots/webgl_loader_texture_rgbm.png new file mode 100644 index 00000000000000..ead3c5d63cfa5e Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_rgbm.png differ diff --git a/examples/screenshots/webgl_loader_texture_tga.png b/examples/screenshots/webgl_loader_texture_tga.png new file mode 100644 index 00000000000000..6df1ba3fc83208 Binary files /dev/null and b/examples/screenshots/webgl_loader_texture_tga.png differ diff --git a/examples/screenshots/webgl_loader_ttf.png b/examples/screenshots/webgl_loader_ttf.png new file mode 100644 index 00000000000000..f261a5390912f8 Binary files /dev/null and b/examples/screenshots/webgl_loader_ttf.png differ diff --git a/examples/screenshots/webgl_loader_vrm.png b/examples/screenshots/webgl_loader_vrm.png new file mode 100644 index 00000000000000..aca481a17bb62c Binary files /dev/null and b/examples/screenshots/webgl_loader_vrm.png differ diff --git a/examples/screenshots/webgl_loader_vrml.png b/examples/screenshots/webgl_loader_vrml.png new file mode 100644 index 00000000000000..08871e82c98c96 Binary files /dev/null and b/examples/screenshots/webgl_loader_vrml.png differ diff --git a/examples/screenshots/webgl_loader_vtk.png b/examples/screenshots/webgl_loader_vtk.png new file mode 100644 index 00000000000000..9ba57f5d9398c4 Binary files /dev/null and b/examples/screenshots/webgl_loader_vtk.png differ diff --git a/examples/screenshots/webgl_loader_x.png b/examples/screenshots/webgl_loader_x.png new file mode 100644 index 00000000000000..4f5761b7d9868c Binary files /dev/null and b/examples/screenshots/webgl_loader_x.png differ diff --git a/examples/screenshots/webgl_lod.png b/examples/screenshots/webgl_lod.png new file mode 100644 index 00000000000000..4813cca2ac4b53 Binary files /dev/null and b/examples/screenshots/webgl_lod.png differ diff --git a/examples/screenshots/webgl_marchingcubes.png b/examples/screenshots/webgl_marchingcubes.png new file mode 100644 index 00000000000000..e3bc6c3240d200 Binary files /dev/null and b/examples/screenshots/webgl_marchingcubes.png differ diff --git a/examples/screenshots/webgl_materials.png b/examples/screenshots/webgl_materials.png new file mode 100644 index 00000000000000..de3c7c087a6184 Binary files /dev/null and b/examples/screenshots/webgl_materials.png differ diff --git a/examples/screenshots/webgl_materials_blending.png b/examples/screenshots/webgl_materials_blending.png new file mode 100644 index 00000000000000..aa11fa4d88a720 Binary files /dev/null and b/examples/screenshots/webgl_materials_blending.png differ diff --git a/examples/screenshots/webgl_materials_blending_custom.png b/examples/screenshots/webgl_materials_blending_custom.png new file mode 100644 index 00000000000000..ca2628972485f3 Binary files /dev/null and b/examples/screenshots/webgl_materials_blending_custom.png differ diff --git a/examples/screenshots/webgl_materials_bumpmap.png b/examples/screenshots/webgl_materials_bumpmap.png new file mode 100644 index 00000000000000..96d877c069806b Binary files /dev/null and b/examples/screenshots/webgl_materials_bumpmap.png differ diff --git a/examples/screenshots/webgl_materials_bumpmap_skin.png b/examples/screenshots/webgl_materials_bumpmap_skin.png new file mode 100644 index 00000000000000..9d10e548a5700b Binary files /dev/null and b/examples/screenshots/webgl_materials_bumpmap_skin.png differ diff --git a/examples/screenshots/webgl_materials_car.png b/examples/screenshots/webgl_materials_car.png new file mode 100644 index 00000000000000..86856793883ea4 Binary files /dev/null and b/examples/screenshots/webgl_materials_car.png differ diff --git a/examples/screenshots/webgl_materials_channels.png b/examples/screenshots/webgl_materials_channels.png new file mode 100644 index 00000000000000..ca5997d48f361a Binary files /dev/null and b/examples/screenshots/webgl_materials_channels.png differ diff --git a/examples/screenshots/webgl_materials_compile.png b/examples/screenshots/webgl_materials_compile.png new file mode 100644 index 00000000000000..75729532104065 Binary files /dev/null and b/examples/screenshots/webgl_materials_compile.png differ diff --git a/examples/screenshots/webgl_materials_cubemap.png b/examples/screenshots/webgl_materials_cubemap.png new file mode 100644 index 00000000000000..fe307c95a451ee Binary files /dev/null and b/examples/screenshots/webgl_materials_cubemap.png differ diff --git a/examples/screenshots/webgl_materials_cubemap_balls_reflection.png b/examples/screenshots/webgl_materials_cubemap_balls_reflection.png new file mode 100644 index 00000000000000..40dfc5271f989f Binary files /dev/null and b/examples/screenshots/webgl_materials_cubemap_balls_reflection.png differ diff --git a/examples/screenshots/webgl_materials_cubemap_balls_refraction.png b/examples/screenshots/webgl_materials_cubemap_balls_refraction.png new file mode 100644 index 00000000000000..2bd5d0a8ba1136 Binary files /dev/null and b/examples/screenshots/webgl_materials_cubemap_balls_refraction.png differ diff --git a/examples/screenshots/webgl_materials_cubemap_dynamic.png b/examples/screenshots/webgl_materials_cubemap_dynamic.png new file mode 100644 index 00000000000000..15fa968ccbc858 Binary files /dev/null and b/examples/screenshots/webgl_materials_cubemap_dynamic.png differ diff --git a/examples/screenshots/webgl_materials_cubemap_mipmaps.png b/examples/screenshots/webgl_materials_cubemap_mipmaps.png new file mode 100644 index 00000000000000..3123723db9334f Binary files /dev/null and b/examples/screenshots/webgl_materials_cubemap_mipmaps.png differ diff --git a/examples/screenshots/webgl_materials_cubemap_refraction.png b/examples/screenshots/webgl_materials_cubemap_refraction.png new file mode 100644 index 00000000000000..0fb3997b6414b0 Binary files /dev/null and b/examples/screenshots/webgl_materials_cubemap_refraction.png differ diff --git a/examples/screenshots/webgl_materials_curvature.png b/examples/screenshots/webgl_materials_curvature.png new file mode 100644 index 00000000000000..6a673d29bcd24a Binary files /dev/null and b/examples/screenshots/webgl_materials_curvature.png differ diff --git a/examples/screenshots/webgl_materials_displacementmap.png b/examples/screenshots/webgl_materials_displacementmap.png new file mode 100644 index 00000000000000..99d07fbbca3412 Binary files /dev/null and b/examples/screenshots/webgl_materials_displacementmap.png differ diff --git a/examples/screenshots/webgl_materials_envmaps.png b/examples/screenshots/webgl_materials_envmaps.png new file mode 100644 index 00000000000000..3098291b994a44 Binary files /dev/null and b/examples/screenshots/webgl_materials_envmaps.png differ diff --git a/examples/screenshots/webgl_materials_envmaps_exr.png b/examples/screenshots/webgl_materials_envmaps_exr.png new file mode 100644 index 00000000000000..82f3e50133a190 Binary files /dev/null and b/examples/screenshots/webgl_materials_envmaps_exr.png differ diff --git a/examples/screenshots/webgl_materials_envmaps_hdr.png b/examples/screenshots/webgl_materials_envmaps_hdr.png new file mode 100644 index 00000000000000..f14978241c16b0 Binary files /dev/null and b/examples/screenshots/webgl_materials_envmaps_hdr.png differ diff --git a/examples/screenshots/webgl_materials_envmaps_hdr_nodes.png b/examples/screenshots/webgl_materials_envmaps_hdr_nodes.png new file mode 100644 index 00000000000000..54c7243d28d9ef Binary files /dev/null and b/examples/screenshots/webgl_materials_envmaps_hdr_nodes.png differ diff --git a/examples/screenshots/webgl_materials_envmaps_parallax.png b/examples/screenshots/webgl_materials_envmaps_parallax.png new file mode 100644 index 00000000000000..25b40ac38541d8 Binary files /dev/null and b/examples/screenshots/webgl_materials_envmaps_parallax.png differ diff --git a/examples/screenshots/webgl_materials_envmaps_pmrem_nodes.png b/examples/screenshots/webgl_materials_envmaps_pmrem_nodes.png new file mode 100644 index 00000000000000..54c7243d28d9ef Binary files /dev/null and b/examples/screenshots/webgl_materials_envmaps_pmrem_nodes.png differ diff --git a/examples/screenshots/webgl_materials_grass.png b/examples/screenshots/webgl_materials_grass.png new file mode 100644 index 00000000000000..0dbb288eac90d4 Binary files /dev/null and b/examples/screenshots/webgl_materials_grass.png differ diff --git a/examples/screenshots/webgl_materials_lightmap.png b/examples/screenshots/webgl_materials_lightmap.png new file mode 100644 index 00000000000000..82c362e588da08 Binary files /dev/null and b/examples/screenshots/webgl_materials_lightmap.png differ diff --git a/examples/screenshots/webgl_materials_matcap.png b/examples/screenshots/webgl_materials_matcap.png new file mode 100644 index 00000000000000..c42b60bd063226 Binary files /dev/null and b/examples/screenshots/webgl_materials_matcap.png differ diff --git a/examples/screenshots/webgl_materials_modified.png b/examples/screenshots/webgl_materials_modified.png new file mode 100644 index 00000000000000..c20f9e4b79e033 Binary files /dev/null and b/examples/screenshots/webgl_materials_modified.png differ diff --git a/examples/screenshots/webgl_materials_nodes.png b/examples/screenshots/webgl_materials_nodes.png new file mode 100644 index 00000000000000..39331a2a96ed66 Binary files /dev/null and b/examples/screenshots/webgl_materials_nodes.png differ diff --git a/examples/screenshots/webgl_materials_normalmap.png b/examples/screenshots/webgl_materials_normalmap.png new file mode 100644 index 00000000000000..53544036ec2b24 Binary files /dev/null and b/examples/screenshots/webgl_materials_normalmap.png differ diff --git a/examples/screenshots/webgl_materials_normalmap_object_space.png b/examples/screenshots/webgl_materials_normalmap_object_space.png new file mode 100644 index 00000000000000..818f862c1478ca Binary files /dev/null and b/examples/screenshots/webgl_materials_normalmap_object_space.png differ diff --git a/examples/screenshots/webgl_materials_parallaxmap.png b/examples/screenshots/webgl_materials_parallaxmap.png new file mode 100644 index 00000000000000..f7a7a708bf9ea1 Binary files /dev/null and b/examples/screenshots/webgl_materials_parallaxmap.png differ diff --git a/examples/screenshots/webgl_materials_physical_clearcoat.png b/examples/screenshots/webgl_materials_physical_clearcoat.png new file mode 100644 index 00000000000000..8903e9137129b2 Binary files /dev/null and b/examples/screenshots/webgl_materials_physical_clearcoat.png differ diff --git a/examples/screenshots/webgl_materials_physical_reflectivity.png b/examples/screenshots/webgl_materials_physical_reflectivity.png new file mode 100644 index 00000000000000..ca821d613317ac Binary files /dev/null and b/examples/screenshots/webgl_materials_physical_reflectivity.png differ diff --git a/examples/screenshots/webgl_materials_physical_sheen.png b/examples/screenshots/webgl_materials_physical_sheen.png new file mode 100644 index 00000000000000..e589be9f3b2479 Binary files /dev/null and b/examples/screenshots/webgl_materials_physical_sheen.png differ diff --git a/examples/screenshots/webgl_materials_physical_transparency.png b/examples/screenshots/webgl_materials_physical_transparency.png new file mode 100644 index 00000000000000..ba7f54819647b3 Binary files /dev/null and b/examples/screenshots/webgl_materials_physical_transparency.png differ diff --git a/examples/screenshots/webgl_materials_shaders_fresnel.png b/examples/screenshots/webgl_materials_shaders_fresnel.png new file mode 100644 index 00000000000000..a821cb1b670909 Binary files /dev/null and b/examples/screenshots/webgl_materials_shaders_fresnel.png differ diff --git a/examples/screenshots/webgl_materials_standard.png b/examples/screenshots/webgl_materials_standard.png new file mode 100644 index 00000000000000..a6627ede30518f Binary files /dev/null and b/examples/screenshots/webgl_materials_standard.png differ diff --git a/examples/screenshots/webgl_materials_texture_anisotropy.png b/examples/screenshots/webgl_materials_texture_anisotropy.png new file mode 100644 index 00000000000000..28ad1a0a351683 Binary files /dev/null and b/examples/screenshots/webgl_materials_texture_anisotropy.png differ diff --git a/examples/screenshots/webgl_materials_texture_canvas.png b/examples/screenshots/webgl_materials_texture_canvas.png new file mode 100644 index 00000000000000..bddd3b994627ec Binary files /dev/null and b/examples/screenshots/webgl_materials_texture_canvas.png differ diff --git a/examples/screenshots/webgl_materials_texture_filters.png b/examples/screenshots/webgl_materials_texture_filters.png new file mode 100644 index 00000000000000..6704ca3b734915 Binary files /dev/null and b/examples/screenshots/webgl_materials_texture_filters.png differ diff --git a/examples/screenshots/webgl_materials_texture_manualmipmap.png b/examples/screenshots/webgl_materials_texture_manualmipmap.png new file mode 100644 index 00000000000000..94cf01e2b697aa Binary files /dev/null and b/examples/screenshots/webgl_materials_texture_manualmipmap.png differ diff --git a/examples/screenshots/webgl_materials_texture_partialupdate.png b/examples/screenshots/webgl_materials_texture_partialupdate.png new file mode 100644 index 00000000000000..b1be1497efa4bc Binary files /dev/null and b/examples/screenshots/webgl_materials_texture_partialupdate.png differ diff --git a/examples/screenshots/webgl_materials_texture_rotation.png b/examples/screenshots/webgl_materials_texture_rotation.png new file mode 100644 index 00000000000000..d53fe3f52315fb Binary files /dev/null and b/examples/screenshots/webgl_materials_texture_rotation.png differ diff --git a/examples/screenshots/webgl_materials_translucency.png b/examples/screenshots/webgl_materials_translucency.png new file mode 100644 index 00000000000000..1b280d2255900f Binary files /dev/null and b/examples/screenshots/webgl_materials_translucency.png differ diff --git a/examples/screenshots/webgl_materials_variations_basic.png b/examples/screenshots/webgl_materials_variations_basic.png new file mode 100644 index 00000000000000..8830740f38f5bd Binary files /dev/null and b/examples/screenshots/webgl_materials_variations_basic.png differ diff --git a/examples/screenshots/webgl_materials_variations_lambert.png b/examples/screenshots/webgl_materials_variations_lambert.png new file mode 100644 index 00000000000000..c5ab3a8fe5cc9e Binary files /dev/null and b/examples/screenshots/webgl_materials_variations_lambert.png differ diff --git a/examples/screenshots/webgl_materials_variations_phong.png b/examples/screenshots/webgl_materials_variations_phong.png new file mode 100644 index 00000000000000..7cd2831f14ef7e Binary files /dev/null and b/examples/screenshots/webgl_materials_variations_phong.png differ diff --git a/examples/screenshots/webgl_materials_variations_physical.png b/examples/screenshots/webgl_materials_variations_physical.png new file mode 100644 index 00000000000000..e560ff5582c88a Binary files /dev/null and b/examples/screenshots/webgl_materials_variations_physical.png differ diff --git a/examples/screenshots/webgl_materials_variations_standard.png b/examples/screenshots/webgl_materials_variations_standard.png new file mode 100644 index 00000000000000..65adf546c4de24 Binary files /dev/null and b/examples/screenshots/webgl_materials_variations_standard.png differ diff --git a/examples/screenshots/webgl_materials_variations_toon.png b/examples/screenshots/webgl_materials_variations_toon.png new file mode 100644 index 00000000000000..39396297d2c190 Binary files /dev/null and b/examples/screenshots/webgl_materials_variations_toon.png differ diff --git a/examples/screenshots/webgl_materials_video.png b/examples/screenshots/webgl_materials_video.png new file mode 100644 index 00000000000000..1eebae15a78c8f Binary files /dev/null and b/examples/screenshots/webgl_materials_video.png differ diff --git a/examples/screenshots/webgl_materials_video_webcam.png b/examples/screenshots/webgl_materials_video_webcam.png new file mode 100644 index 00000000000000..38456f88261d57 Binary files /dev/null and b/examples/screenshots/webgl_materials_video_webcam.png differ diff --git a/examples/screenshots/webgl_materials_wireframe.png b/examples/screenshots/webgl_materials_wireframe.png new file mode 100644 index 00000000000000..90b31687948b43 Binary files /dev/null and b/examples/screenshots/webgl_materials_wireframe.png differ diff --git a/examples/screenshots/webgl_math_obb.png b/examples/screenshots/webgl_math_obb.png new file mode 100644 index 00000000000000..caaa39cd0ebff1 Binary files /dev/null and b/examples/screenshots/webgl_math_obb.png differ diff --git a/examples/screenshots/webgl_math_orientation_transform.png b/examples/screenshots/webgl_math_orientation_transform.png new file mode 100644 index 00000000000000..365fbde1dd991c Binary files /dev/null and b/examples/screenshots/webgl_math_orientation_transform.png differ diff --git a/examples/screenshots/webgl_mirror.png b/examples/screenshots/webgl_mirror.png new file mode 100644 index 00000000000000..d0d840aef06da1 Binary files /dev/null and b/examples/screenshots/webgl_mirror.png differ diff --git a/examples/screenshots/webgl_mirror_nodes.png b/examples/screenshots/webgl_mirror_nodes.png new file mode 100644 index 00000000000000..db14cf9f328de5 Binary files /dev/null and b/examples/screenshots/webgl_mirror_nodes.png differ diff --git a/examples/screenshots/webgl_modifier_simplifier.png b/examples/screenshots/webgl_modifier_simplifier.png new file mode 100644 index 00000000000000..dfab4be83344b3 Binary files /dev/null and b/examples/screenshots/webgl_modifier_simplifier.png differ diff --git a/examples/screenshots/webgl_modifier_subdivision.png b/examples/screenshots/webgl_modifier_subdivision.png new file mode 100644 index 00000000000000..1f7a53f3309127 Binary files /dev/null and b/examples/screenshots/webgl_modifier_subdivision.png differ diff --git a/examples/screenshots/webgl_modifier_tessellation.png b/examples/screenshots/webgl_modifier_tessellation.png new file mode 100644 index 00000000000000..6c19b7fb21fe35 Binary files /dev/null and b/examples/screenshots/webgl_modifier_tessellation.png differ diff --git a/examples/screenshots/webgl_morphtargets.png b/examples/screenshots/webgl_morphtargets.png new file mode 100644 index 00000000000000..d70307d56bb941 Binary files /dev/null and b/examples/screenshots/webgl_morphtargets.png differ diff --git a/examples/screenshots/webgl_morphtargets_horse.png b/examples/screenshots/webgl_morphtargets_horse.png new file mode 100644 index 00000000000000..c9e0b58c04fdf0 Binary files /dev/null and b/examples/screenshots/webgl_morphtargets_horse.png differ diff --git a/examples/screenshots/webgl_morphtargets_sphere.png b/examples/screenshots/webgl_morphtargets_sphere.png new file mode 100644 index 00000000000000..3c16b97e59e4d6 Binary files /dev/null and b/examples/screenshots/webgl_morphtargets_sphere.png differ diff --git a/examples/screenshots/webgl_multiple_canvases_circle.png b/examples/screenshots/webgl_multiple_canvases_circle.png new file mode 100644 index 00000000000000..c5521e4fb6fe36 Binary files /dev/null and b/examples/screenshots/webgl_multiple_canvases_circle.png differ diff --git a/examples/screenshots/webgl_multiple_canvases_complex.png b/examples/screenshots/webgl_multiple_canvases_complex.png new file mode 100644 index 00000000000000..3c4106a5ce4021 Binary files /dev/null and b/examples/screenshots/webgl_multiple_canvases_complex.png differ diff --git a/examples/screenshots/webgl_multiple_canvases_grid.png b/examples/screenshots/webgl_multiple_canvases_grid.png new file mode 100644 index 00000000000000..adb00b98d61e7b Binary files /dev/null and b/examples/screenshots/webgl_multiple_canvases_grid.png differ diff --git a/examples/screenshots/webgl_multiple_elements.png b/examples/screenshots/webgl_multiple_elements.png new file mode 100644 index 00000000000000..5d8355182898a0 Binary files /dev/null and b/examples/screenshots/webgl_multiple_elements.png differ diff --git a/examples/screenshots/webgl_multiple_elements_text.png b/examples/screenshots/webgl_multiple_elements_text.png new file mode 100644 index 00000000000000..96c69c7ad333cb Binary files /dev/null and b/examples/screenshots/webgl_multiple_elements_text.png differ diff --git a/examples/screenshots/webgl_multiple_renderers.png b/examples/screenshots/webgl_multiple_renderers.png new file mode 100644 index 00000000000000..14832a4172715e Binary files /dev/null and b/examples/screenshots/webgl_multiple_renderers.png differ diff --git a/examples/screenshots/webgl_multiple_scenes_comparison.png b/examples/screenshots/webgl_multiple_scenes_comparison.png new file mode 100644 index 00000000000000..2986f5b15995e0 Binary files /dev/null and b/examples/screenshots/webgl_multiple_scenes_comparison.png differ diff --git a/examples/screenshots/webgl_multiple_views.png b/examples/screenshots/webgl_multiple_views.png new file mode 100644 index 00000000000000..0453edb86d3142 Binary files /dev/null and b/examples/screenshots/webgl_multiple_views.png differ diff --git a/examples/screenshots/webgl_nearestneighbour.png b/examples/screenshots/webgl_nearestneighbour.png new file mode 100644 index 00000000000000..41bad9bda1062f Binary files /dev/null and b/examples/screenshots/webgl_nearestneighbour.png differ diff --git a/examples/screenshots/webgl_panorama_cube.png b/examples/screenshots/webgl_panorama_cube.png new file mode 100644 index 00000000000000..57e38f899b13ef Binary files /dev/null and b/examples/screenshots/webgl_panorama_cube.png differ diff --git a/examples/screenshots/webgl_panorama_dualfisheye.png b/examples/screenshots/webgl_panorama_dualfisheye.png new file mode 100644 index 00000000000000..25c314676c385d Binary files /dev/null and b/examples/screenshots/webgl_panorama_dualfisheye.png differ diff --git a/examples/screenshots/webgl_panorama_equirectangular.png b/examples/screenshots/webgl_panorama_equirectangular.png new file mode 100644 index 00000000000000..d2dff3630d707a Binary files /dev/null and b/examples/screenshots/webgl_panorama_equirectangular.png differ diff --git a/examples/screenshots/webgl_performance.png b/examples/screenshots/webgl_performance.png new file mode 100644 index 00000000000000..f9fca58d1e25e1 Binary files /dev/null and b/examples/screenshots/webgl_performance.png differ diff --git a/examples/screenshots/webgl_performance_doublesided.png b/examples/screenshots/webgl_performance_doublesided.png new file mode 100644 index 00000000000000..bc5c7ae8228dee Binary files /dev/null and b/examples/screenshots/webgl_performance_doublesided.png differ diff --git a/examples/screenshots/webgl_performance_nodes.png b/examples/screenshots/webgl_performance_nodes.png new file mode 100644 index 00000000000000..3c0956885806f1 Binary files /dev/null and b/examples/screenshots/webgl_performance_nodes.png differ diff --git a/examples/screenshots/webgl_performance_static.png b/examples/screenshots/webgl_performance_static.png new file mode 100644 index 00000000000000..37ce95044edab7 Binary files /dev/null and b/examples/screenshots/webgl_performance_static.png differ diff --git a/examples/screenshots/webgl_pmrem_test.png b/examples/screenshots/webgl_pmrem_test.png new file mode 100644 index 00000000000000..ab7a2b7276422d Binary files /dev/null and b/examples/screenshots/webgl_pmrem_test.png differ diff --git a/examples/screenshots/webgl_points_billboards.png b/examples/screenshots/webgl_points_billboards.png new file mode 100644 index 00000000000000..d67410977061ec Binary files /dev/null and b/examples/screenshots/webgl_points_billboards.png differ diff --git a/examples/screenshots/webgl_points_dynamic.png b/examples/screenshots/webgl_points_dynamic.png new file mode 100644 index 00000000000000..72438ed0b7a6e6 Binary files /dev/null and b/examples/screenshots/webgl_points_dynamic.png differ diff --git a/examples/screenshots/webgl_points_sprites.png b/examples/screenshots/webgl_points_sprites.png new file mode 100644 index 00000000000000..0d01efe9fe9506 Binary files /dev/null and b/examples/screenshots/webgl_points_sprites.png differ diff --git a/examples/screenshots/webgl_points_waves.png b/examples/screenshots/webgl_points_waves.png new file mode 100644 index 00000000000000..b481a8b25da71c Binary files /dev/null and b/examples/screenshots/webgl_points_waves.png differ diff --git a/examples/screenshots/webgl_postprocessing.png b/examples/screenshots/webgl_postprocessing.png new file mode 100644 index 00000000000000..a3cfe1e674610b Binary files /dev/null and b/examples/screenshots/webgl_postprocessing.png differ diff --git a/examples/screenshots/webgl_postprocessing_advanced.png b/examples/screenshots/webgl_postprocessing_advanced.png new file mode 100644 index 00000000000000..c56270013863df Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_advanced.png differ diff --git a/examples/screenshots/webgl_postprocessing_afterimage.png b/examples/screenshots/webgl_postprocessing_afterimage.png new file mode 100644 index 00000000000000..2f392c6b9804d9 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_afterimage.png differ diff --git a/examples/screenshots/webgl_postprocessing_backgrounds.png b/examples/screenshots/webgl_postprocessing_backgrounds.png new file mode 100644 index 00000000000000..a073adaffb3a48 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_backgrounds.png differ diff --git a/examples/screenshots/webgl_postprocessing_crossfade.png b/examples/screenshots/webgl_postprocessing_crossfade.png new file mode 100644 index 00000000000000..0d395544a37260 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_crossfade.png differ diff --git a/examples/screenshots/webgl_postprocessing_dof.png b/examples/screenshots/webgl_postprocessing_dof.png new file mode 100644 index 00000000000000..2aff68e7c28b66 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_dof.png differ diff --git a/examples/screenshots/webgl_postprocessing_dof2.png b/examples/screenshots/webgl_postprocessing_dof2.png new file mode 100644 index 00000000000000..38456f88261d57 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_dof2.png differ diff --git a/examples/screenshots/webgl_postprocessing_fxaa.png b/examples/screenshots/webgl_postprocessing_fxaa.png new file mode 100644 index 00000000000000..c75ae3b0742491 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_fxaa.png differ diff --git a/examples/screenshots/webgl_postprocessing_glitch.png b/examples/screenshots/webgl_postprocessing_glitch.png new file mode 100644 index 00000000000000..fab1c61a48310c Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_glitch.png differ diff --git a/examples/screenshots/webgl_postprocessing_godrays.png b/examples/screenshots/webgl_postprocessing_godrays.png new file mode 100644 index 00000000000000..1c39b3140c1bc0 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_godrays.png differ diff --git a/examples/screenshots/webgl_postprocessing_masking.png b/examples/screenshots/webgl_postprocessing_masking.png new file mode 100644 index 00000000000000..ae6061ec9ffcd7 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_masking.png differ diff --git a/examples/screenshots/webgl_postprocessing_nodes.png b/examples/screenshots/webgl_postprocessing_nodes.png new file mode 100644 index 00000000000000..4ec0956e2e706a Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_nodes.png differ diff --git a/examples/screenshots/webgl_postprocessing_nodes_pass.png b/examples/screenshots/webgl_postprocessing_nodes_pass.png new file mode 100644 index 00000000000000..9e9e0cd9b6175c Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_nodes_pass.png differ diff --git a/examples/screenshots/webgl_postprocessing_outline.png b/examples/screenshots/webgl_postprocessing_outline.png new file mode 100644 index 00000000000000..f2785fe1842a05 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_outline.png differ diff --git a/examples/screenshots/webgl_postprocessing_pixel.png b/examples/screenshots/webgl_postprocessing_pixel.png new file mode 100644 index 00000000000000..6b3a12a2c934af Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_pixel.png differ diff --git a/examples/screenshots/webgl_postprocessing_procedural.png b/examples/screenshots/webgl_postprocessing_procedural.png new file mode 100644 index 00000000000000..977b68d66fcada Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_procedural.png differ diff --git a/examples/screenshots/webgl_postprocessing_rgb_halftone.png b/examples/screenshots/webgl_postprocessing_rgb_halftone.png new file mode 100644 index 00000000000000..ea3c2146e4b615 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_rgb_halftone.png differ diff --git a/examples/screenshots/webgl_postprocessing_sao.png b/examples/screenshots/webgl_postprocessing_sao.png new file mode 100644 index 00000000000000..6a80397581bf5e Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_sao.png differ diff --git a/examples/screenshots/webgl_postprocessing_smaa.png b/examples/screenshots/webgl_postprocessing_smaa.png new file mode 100644 index 00000000000000..68bcbe6f33ec4d Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_smaa.png differ diff --git a/examples/screenshots/webgl_postprocessing_sobel.png b/examples/screenshots/webgl_postprocessing_sobel.png new file mode 100644 index 00000000000000..fc0401feb7e6d8 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_sobel.png differ diff --git a/examples/screenshots/webgl_postprocessing_ssaa.png b/examples/screenshots/webgl_postprocessing_ssaa.png new file mode 100644 index 00000000000000..1ec0a5733872f7 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_ssaa.png differ diff --git a/examples/screenshots/webgl_postprocessing_ssaa_unbiased.png b/examples/screenshots/webgl_postprocessing_ssaa_unbiased.png new file mode 100644 index 00000000000000..ffc34b4a6dab81 Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_ssaa_unbiased.png differ diff --git a/examples/screenshots/webgl_postprocessing_ssao.png b/examples/screenshots/webgl_postprocessing_ssao.png new file mode 100644 index 00000000000000..6ead5cbca91aad Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_ssao.png differ diff --git a/examples/screenshots/webgl_postprocessing_taa.png b/examples/screenshots/webgl_postprocessing_taa.png new file mode 100644 index 00000000000000..304e1654f42bbe Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_taa.png differ diff --git a/examples/screenshots/webgl_postprocessing_unreal_bloom.png b/examples/screenshots/webgl_postprocessing_unreal_bloom.png new file mode 100644 index 00000000000000..9083fe0769dc4e Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_unreal_bloom.png differ diff --git a/examples/screenshots/webgl_postprocessing_unreal_bloom_selective.png b/examples/screenshots/webgl_postprocessing_unreal_bloom_selective.png new file mode 100644 index 00000000000000..53c219412fc07e Binary files /dev/null and b/examples/screenshots/webgl_postprocessing_unreal_bloom_selective.png differ diff --git a/examples/screenshots/webgl_raycast_sprite.png b/examples/screenshots/webgl_raycast_sprite.png new file mode 100644 index 00000000000000..6e33d2a7f7532e Binary files /dev/null and b/examples/screenshots/webgl_raycast_sprite.png differ diff --git a/examples/screenshots/webgl_raycast_texture.png b/examples/screenshots/webgl_raycast_texture.png new file mode 100644 index 00000000000000..c852bbf33c5db8 Binary files /dev/null and b/examples/screenshots/webgl_raycast_texture.png differ diff --git a/examples/screenshots/webgl_raymarching_reflect.png b/examples/screenshots/webgl_raymarching_reflect.png new file mode 100644 index 00000000000000..c512df7c23ccd6 Binary files /dev/null and b/examples/screenshots/webgl_raymarching_reflect.png differ diff --git a/examples/screenshots/webgl_read_float_buffer.png b/examples/screenshots/webgl_read_float_buffer.png new file mode 100644 index 00000000000000..fd9a66cf02b6d9 Binary files /dev/null and b/examples/screenshots/webgl_read_float_buffer.png differ diff --git a/examples/screenshots/webgl_refraction.png b/examples/screenshots/webgl_refraction.png new file mode 100644 index 00000000000000..1e8aeb40456ce6 Binary files /dev/null and b/examples/screenshots/webgl_refraction.png differ diff --git a/examples/screenshots/webgl_rtt.png b/examples/screenshots/webgl_rtt.png new file mode 100644 index 00000000000000..c6b2b913b4ca10 Binary files /dev/null and b/examples/screenshots/webgl_rtt.png differ diff --git a/examples/screenshots/webgl_sandbox.png b/examples/screenshots/webgl_sandbox.png new file mode 100644 index 00000000000000..f3841628d31b92 Binary files /dev/null and b/examples/screenshots/webgl_sandbox.png differ diff --git a/examples/screenshots/webgl_shader.png b/examples/screenshots/webgl_shader.png new file mode 100644 index 00000000000000..9da8a3aa1dd260 Binary files /dev/null and b/examples/screenshots/webgl_shader.png differ diff --git a/examples/screenshots/webgl_shader2.png b/examples/screenshots/webgl_shader2.png new file mode 100644 index 00000000000000..efa25bfc9168d0 Binary files /dev/null and b/examples/screenshots/webgl_shader2.png differ diff --git a/examples/screenshots/webgl_shader_lava.png b/examples/screenshots/webgl_shader_lava.png new file mode 100644 index 00000000000000..cd4c18f69a3ea6 Binary files /dev/null and b/examples/screenshots/webgl_shader_lava.png differ diff --git a/examples/screenshots/webgl_shaders_ocean.png b/examples/screenshots/webgl_shaders_ocean.png new file mode 100644 index 00000000000000..02b800735a116f Binary files /dev/null and b/examples/screenshots/webgl_shaders_ocean.png differ diff --git a/examples/screenshots/webgl_shaders_ocean2.png b/examples/screenshots/webgl_shaders_ocean2.png new file mode 100644 index 00000000000000..e26c94fd6b6a2e Binary files /dev/null and b/examples/screenshots/webgl_shaders_ocean2.png differ diff --git a/examples/screenshots/webgl_shaders_sky.png b/examples/screenshots/webgl_shaders_sky.png new file mode 100644 index 00000000000000..41626c0e2beed5 Binary files /dev/null and b/examples/screenshots/webgl_shaders_sky.png differ diff --git a/examples/screenshots/webgl_shaders_tonemapping.png b/examples/screenshots/webgl_shaders_tonemapping.png new file mode 100644 index 00000000000000..3bbcbf7c1d568d Binary files /dev/null and b/examples/screenshots/webgl_shaders_tonemapping.png differ diff --git a/examples/screenshots/webgl_shaders_vector.png b/examples/screenshots/webgl_shaders_vector.png new file mode 100644 index 00000000000000..7496b89255521c Binary files /dev/null and b/examples/screenshots/webgl_shaders_vector.png differ diff --git a/examples/screenshots/webgl_shading_physical.png b/examples/screenshots/webgl_shading_physical.png new file mode 100644 index 00000000000000..148f052354b7ab Binary files /dev/null and b/examples/screenshots/webgl_shading_physical.png differ diff --git a/examples/screenshots/webgl_shadow_contact.png b/examples/screenshots/webgl_shadow_contact.png new file mode 100644 index 00000000000000..9f0e832d170bac Binary files /dev/null and b/examples/screenshots/webgl_shadow_contact.png differ diff --git a/examples/screenshots/webgl_shadowmap.png b/examples/screenshots/webgl_shadowmap.png new file mode 100644 index 00000000000000..130125f82bc663 Binary files /dev/null and b/examples/screenshots/webgl_shadowmap.png differ diff --git a/examples/screenshots/webgl_shadowmap_csm.png b/examples/screenshots/webgl_shadowmap_csm.png new file mode 100644 index 00000000000000..852118674a8aa4 Binary files /dev/null and b/examples/screenshots/webgl_shadowmap_csm.png differ diff --git a/examples/screenshots/webgl_shadowmap_pcss.png b/examples/screenshots/webgl_shadowmap_pcss.png new file mode 100644 index 00000000000000..b0843e7f7bb3e8 Binary files /dev/null and b/examples/screenshots/webgl_shadowmap_pcss.png differ diff --git a/examples/screenshots/webgl_shadowmap_performance.png b/examples/screenshots/webgl_shadowmap_performance.png new file mode 100644 index 00000000000000..cff681e740da14 Binary files /dev/null and b/examples/screenshots/webgl_shadowmap_performance.png differ diff --git a/examples/screenshots/webgl_shadowmap_pointlight.png b/examples/screenshots/webgl_shadowmap_pointlight.png new file mode 100644 index 00000000000000..4a2d84f0129530 Binary files /dev/null and b/examples/screenshots/webgl_shadowmap_pointlight.png differ diff --git a/examples/screenshots/webgl_shadowmap_viewer.png b/examples/screenshots/webgl_shadowmap_viewer.png new file mode 100644 index 00000000000000..92229c816d40e6 Binary files /dev/null and b/examples/screenshots/webgl_shadowmap_viewer.png differ diff --git a/examples/screenshots/webgl_shadowmap_vsm.png b/examples/screenshots/webgl_shadowmap_vsm.png new file mode 100644 index 00000000000000..ab93a6f0158dde Binary files /dev/null and b/examples/screenshots/webgl_shadowmap_vsm.png differ diff --git a/examples/screenshots/webgl_shadowmesh.png b/examples/screenshots/webgl_shadowmesh.png new file mode 100644 index 00000000000000..49abe2d205aea8 Binary files /dev/null and b/examples/screenshots/webgl_shadowmesh.png differ diff --git a/examples/screenshots/webgl_simple_gi.png b/examples/screenshots/webgl_simple_gi.png new file mode 100644 index 00000000000000..38456f88261d57 Binary files /dev/null and b/examples/screenshots/webgl_simple_gi.png differ diff --git a/examples/screenshots/webgl_skinning_simple.png b/examples/screenshots/webgl_skinning_simple.png new file mode 100644 index 00000000000000..4b7099b70efaef Binary files /dev/null and b/examples/screenshots/webgl_skinning_simple.png differ diff --git a/examples/screenshots/webgl_sprites.png b/examples/screenshots/webgl_sprites.png new file mode 100644 index 00000000000000..48fbf551c4f663 Binary files /dev/null and b/examples/screenshots/webgl_sprites.png differ diff --git a/examples/screenshots/webgl_sprites_nodes.png b/examples/screenshots/webgl_sprites_nodes.png new file mode 100644 index 00000000000000..1af93a45803bd4 Binary files /dev/null and b/examples/screenshots/webgl_sprites_nodes.png differ diff --git a/examples/screenshots/webgl_test_memory.png b/examples/screenshots/webgl_test_memory.png new file mode 100644 index 00000000000000..3b028f6eb6ce01 Binary files /dev/null and b/examples/screenshots/webgl_test_memory.png differ diff --git a/examples/screenshots/webgl_test_memory2.png b/examples/screenshots/webgl_test_memory2.png new file mode 100644 index 00000000000000..1c604e15f3800b Binary files /dev/null and b/examples/screenshots/webgl_test_memory2.png differ diff --git a/examples/screenshots/webgl_tiled_forward.png b/examples/screenshots/webgl_tiled_forward.png new file mode 100644 index 00000000000000..28f96df976d8d6 Binary files /dev/null and b/examples/screenshots/webgl_tiled_forward.png differ diff --git a/examples/screenshots/webgl_tonemapping.png b/examples/screenshots/webgl_tonemapping.png new file mode 100644 index 00000000000000..48e9701320fef5 Binary files /dev/null and b/examples/screenshots/webgl_tonemapping.png differ diff --git a/examples/screenshots/webgl_trails.png b/examples/screenshots/webgl_trails.png new file mode 100644 index 00000000000000..308cc737f6d39f Binary files /dev/null and b/examples/screenshots/webgl_trails.png differ diff --git a/examples/screenshots/webgl_video_panorama_equirectangular.png b/examples/screenshots/webgl_video_panorama_equirectangular.png new file mode 100644 index 00000000000000..a2600fc0aecf34 Binary files /dev/null and b/examples/screenshots/webgl_video_panorama_equirectangular.png differ diff --git a/examples/screenshots/webgl_water.png b/examples/screenshots/webgl_water.png new file mode 100644 index 00000000000000..c6d23cc0145e04 Binary files /dev/null and b/examples/screenshots/webgl_water.png differ diff --git a/examples/screenshots/webgl_water_flowmap.png b/examples/screenshots/webgl_water_flowmap.png new file mode 100644 index 00000000000000..82988f70d47bc1 Binary files /dev/null and b/examples/screenshots/webgl_water_flowmap.png differ diff --git a/examples/screenshots/webgl_worker_offscreencanvas.png b/examples/screenshots/webgl_worker_offscreencanvas.png new file mode 100644 index 00000000000000..15f3f9177a3c93 Binary files /dev/null and b/examples/screenshots/webgl_worker_offscreencanvas.png differ diff --git a/examples/screenshots/webxr_ar_cones.png b/examples/screenshots/webxr_ar_cones.png new file mode 100644 index 00000000000000..38456f88261d57 Binary files /dev/null and b/examples/screenshots/webxr_ar_cones.png differ diff --git a/examples/screenshots/webxr_ar_hittest.png b/examples/screenshots/webxr_ar_hittest.png new file mode 100644 index 00000000000000..38456f88261d57 Binary files /dev/null and b/examples/screenshots/webxr_ar_hittest.png differ diff --git a/examples/screenshots/webxr_ar_paint.png b/examples/screenshots/webxr_ar_paint.png new file mode 100644 index 00000000000000..38456f88261d57 Binary files /dev/null and b/examples/screenshots/webxr_ar_paint.png differ diff --git a/examples/screenshots/webxr_vr_ballshooter.png b/examples/screenshots/webxr_vr_ballshooter.png new file mode 100644 index 00000000000000..7500e1b4165e25 Binary files /dev/null and b/examples/screenshots/webxr_vr_ballshooter.png differ diff --git a/examples/screenshots/webxr_vr_cubes.png b/examples/screenshots/webxr_vr_cubes.png new file mode 100644 index 00000000000000..22b310c20f17ba Binary files /dev/null and b/examples/screenshots/webxr_vr_cubes.png differ diff --git a/examples/screenshots/webxr_vr_dragging.png b/examples/screenshots/webxr_vr_dragging.png new file mode 100644 index 00000000000000..72531bff7f8ed8 Binary files /dev/null and b/examples/screenshots/webxr_vr_dragging.png differ diff --git a/examples/screenshots/webxr_vr_lorenzattractor.png b/examples/screenshots/webxr_vr_lorenzattractor.png new file mode 100644 index 00000000000000..e49a9da8413af8 Binary files /dev/null and b/examples/screenshots/webxr_vr_lorenzattractor.png differ diff --git a/examples/screenshots/webxr_vr_paint.png b/examples/screenshots/webxr_vr_paint.png new file mode 100644 index 00000000000000..376b671bf1385a Binary files /dev/null and b/examples/screenshots/webxr_vr_paint.png differ diff --git a/examples/screenshots/webxr_vr_panorama.png b/examples/screenshots/webxr_vr_panorama.png new file mode 100644 index 00000000000000..fba86975458122 Binary files /dev/null and b/examples/screenshots/webxr_vr_panorama.png differ diff --git a/examples/screenshots/webxr_vr_panorama_depth.png b/examples/screenshots/webxr_vr_panorama_depth.png new file mode 100644 index 00000000000000..1bce86ca276bcb Binary files /dev/null and b/examples/screenshots/webxr_vr_panorama_depth.png differ diff --git a/examples/screenshots/webxr_vr_rollercoaster.png b/examples/screenshots/webxr_vr_rollercoaster.png new file mode 100644 index 00000000000000..6dd36118b5a39f Binary files /dev/null and b/examples/screenshots/webxr_vr_rollercoaster.png differ diff --git a/examples/screenshots/webxr_vr_sandbox.png b/examples/screenshots/webxr_vr_sandbox.png new file mode 100644 index 00000000000000..89bf19c1fc41cc Binary files /dev/null and b/examples/screenshots/webxr_vr_sandbox.png differ diff --git a/examples/screenshots/webxr_vr_sculpt.png b/examples/screenshots/webxr_vr_sculpt.png new file mode 100644 index 00000000000000..3538a145b1be67 Binary files /dev/null and b/examples/screenshots/webxr_vr_sculpt.png differ diff --git a/examples/screenshots/webxr_vr_video.png b/examples/screenshots/webxr_vr_video.png new file mode 100644 index 00000000000000..f194cbdd991ec6 Binary files /dev/null and b/examples/screenshots/webxr_vr_video.png differ diff --git a/examples/software_geometry_earth.html b/examples/software_geometry_earth.html deleted file mode 100644 index ee0bab81546e65..00000000000000 --- a/examples/software_geometry_earth.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - three.js software - geometry - earth - - - - - - - -
        -
        three.js - earth demo
        - - - - - diff --git a/examples/software_lines_splines.html b/examples/software_lines_splines.html deleted file mode 100644 index 57c74f1ce724fe..00000000000000 --- a/examples/software_lines_splines.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - three.js software - lines - splines - - - - - - -
        - three.js - splines Software demo
        - Hilbert curve thanks to Thomas Diewald -
        - - - - diff --git a/examples/software_sandbox.html b/examples/software_sandbox.html deleted file mode 100644 index 18a43f23e12f37..00000000000000 --- a/examples/software_sandbox.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - three.js - software renderer - - - - - - -
        - three.js - software renderer
        - drag to change the point of view -
        - - - - - diff --git a/examples/svg_lines.html b/examples/svg_lines.html index 65af98f4e1d0aa..cabea2688a00e0 100644 --- a/examples/svg_lines.html +++ b/examples/svg_lines.html @@ -17,7 +17,7 @@
        - three.js svg - lines + three.js svg - lines
        - three.js - 2D Texture array
        + three.js - 2D Texture array
        Scanned head data by Divine Augustine
        licensed under @@ -99,12 +99,9 @@ var array = zip.files[ 'head256x256x109' ].asUint8Array(); var texture = new THREE.DataTexture2DArray( array, 256, 256, 109 ); - texture.format = THREE.RedFormat; texture.type = THREE.UnsignedByteType; - texture.needsUpdate = true; - var material = new THREE.ShaderMaterial( { uniforms: { diffuse: { value: texture }, @@ -126,9 +123,9 @@ // 2D Texture array is available on WebGL 2.0 var canvas = document.createElement( 'canvas' ); - var context = canvas.getContext( 'webgl2' ); + var context = canvas.getContext( 'webgl2', { alpha: false, antialias: false } ); - renderer = new THREE.WebGLRenderer( { antialias: true, canvas: canvas, context: context } ); + renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); diff --git a/examples/webgl2_materials_texture3d.html b/examples/webgl2_materials_texture3d.html index 42f42e87986805..e43c076751a915 100644 --- a/examples/webgl2_materials_texture3d.html +++ b/examples/webgl2_materials_texture3d.html @@ -9,7 +9,7 @@
        - three.js - Float volume render test (mip / isosurface) + three.js - Float volume render test (mip / isosurface)
        @@ -44,7 +44,7 @@ // Create renderer var canvas = document.createElement( 'canvas' ); - var context = canvas.getContext( 'webgl2' ); + var context = canvas.getContext( 'webgl2', { alpha: false, antialias: false } ); renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); @@ -91,7 +91,6 @@ texture.type = THREE.FloatType; texture.minFilter = texture.magFilter = THREE.LinearFilter; texture.unpackAlignment = 1; - texture.needsUpdate = true; // Colormap textures cmtextures = { diff --git a/examples/webgl2_multisampled_renderbuffers.html b/examples/webgl2_multisampled_renderbuffers.html index e0f3eb824f1c4f..78bf74605b9003 100644 --- a/examples/webgl2_multisampled_renderbuffers.html +++ b/examples/webgl2_multisampled_renderbuffers.html @@ -17,7 +17,7 @@ #container { position: absolute; - top: 80px; + top: 70px; width: 100%; bottom: 0px; } @@ -27,8 +27,8 @@
        - three.js - Multisampled Renderbuffers
        - Left scene is multi-sampled, right scene is rendered without anti-aliasing. + three.js - Multisampled Renderbuffers
        + Left: WebGLRenderTarget, Right: WebGLMultisampleRenderTarget.
        @@ -60,7 +60,7 @@ container = document.getElementById( 'container' ); - camera = new THREE.PerspectiveCamera( 45, ( container.offsetWidth * 0.5 ) / container.offsetHeight, 1, 2000 ); + camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 2000 ); camera.position.z = 500; scene = new THREE.Scene(); @@ -71,30 +71,35 @@ // - var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 ); - hemiLight.position.set( 0, 1000, 0 ); + var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x222222, 1.5 ); + hemiLight.position.set( 1, 1, 1 ); scene.add( hemiLight ); - var dirLight = new THREE.DirectionalLight( 0xffffff, 0.8 ); - dirLight.position.set( - 3000, 1000, - 1000 ); - scene.add( dirLight ); - // group = new THREE.Group(); - var geometry = new THREE.IcosahedronBufferGeometry( 10, 2 ); - var material = new THREE.MeshStandardMaterial( { color: 0xee0808, flatShading: true } ); + var geometry = new THREE.SphereBufferGeometry( 10, 64, 40 ); + var material = new THREE.MeshLambertMaterial( { color: 0xee0808 } ); + var material2 = new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } ); - for ( var i = 0; i < 100; i ++ ) { + for ( var i = 0; i < 10; i ++ ) { var mesh = new THREE.Mesh( geometry, material ); - mesh.position.x = Math.random() * 500 - 250; - mesh.position.y = Math.random() * 500 - 250; - mesh.position.z = Math.random() * 500 - 250; - mesh.scale.setScalar( Math.random() * 2 + 1 ); + mesh.position.x = Math.random() * 600 - 300; + mesh.position.y = Math.random() * 600 - 300; + mesh.position.z = Math.random() * 600 - 300; + mesh.rotation.x = Math.random(); + mesh.rotation.z = Math.random(); + mesh.scale.setScalar( Math.random() * 5 + 5 ); group.add( mesh ); + var mesh2 = new THREE.Mesh( geometry, material2 ); + mesh2.position.copy( mesh.position ); + mesh2.rotation.copy( mesh.rotation ); + mesh2.scale.copy( mesh.scale ); + group.add( mesh2 ); + } scene.add( group ); @@ -102,10 +107,11 @@ // var canvas = document.createElement( 'canvas' ); - var context = canvas.getContext( 'webgl2', { antialias: false } ); + var context = canvas.getContext( 'webgl2', { alpha: false, antialias: false } ); renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } ); renderer.autoClear = false; + renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( container.offsetWidth, container.offsetHeight ); container.appendChild( renderer.domElement ); @@ -124,13 +130,13 @@ // - composer1 = new EffectComposer( renderer, renderTarget ); + composer1 = new EffectComposer( renderer ); composer1.addPass( renderPass ); composer1.addPass( copyPass ); // - composer2 = new EffectComposer( renderer ); + composer2 = new EffectComposer( renderer, renderTarget ); composer2.addPass( renderPass ); composer2.addPass( copyPass ); @@ -142,7 +148,7 @@ function onWindowResize() { - camera.aspect = ( container.offsetWidth * 0.5 ) / container.offsetHeight; + camera.aspect = container.offsetWidth / container.offsetHeight; camera.updateProjectionMatrix(); renderer.setSize( container.offsetWidth, container.offsetHeight ); @@ -159,14 +165,16 @@ group.rotation.y += clock.getDelta() * 0.1; - renderer.setViewport( 0, 0, halfWidth, container.offsetHeight ); + renderer.setScissorTest( true ); + renderer.setScissor( 0, 0, halfWidth - 1, container.offsetHeight ); composer1.render(); - renderer.setViewport( halfWidth, 0, halfWidth, container.offsetHeight ); - + renderer.setScissor( halfWidth, 0, halfWidth, container.offsetHeight ); composer2.render(); + renderer.setScissorTest( false ); + } diff --git a/examples/webgl2_sandbox.html b/examples/webgl2_sandbox.html index 4f24962b027c89..275276039e5d94 100644 --- a/examples/webgl2_sandbox.html +++ b/examples/webgl2_sandbox.html @@ -8,7 +8,7 @@ -
        three.js - webgl2 sandbox
        +
        three.js - webgl2 sandbox
        + + + diff --git a/examples/webgl_buffergeometry_constructed_from_geometry.html b/examples/webgl_buffergeometry_constructed_from_geometry.html index 28e5cc7abff1c7..c3f2f23826b288 100644 --- a/examples/webgl_buffergeometry_constructed_from_geometry.html +++ b/examples/webgl_buffergeometry_constructed_from_geometry.html @@ -13,7 +13,7 @@
        - three.js webgl - buffergeometry constructed from geometry
        + three.js webgl - buffergeometry constructed from geometry
        by Callum Prentice
        @@ -158,11 +158,11 @@ } - bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); - bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); - bufferGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); + bufferGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) ); + bufferGeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) ); + bufferGeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); - var material = new THREE.MeshPhongMaterial( { shininess: 80, vertexColors: THREE.VertexColors } ); + var material = new THREE.MeshPhongMaterial( { shininess: 80, vertexColors: true } ); var mesh = new THREE.Mesh( bufferGeometry, material ); scene.add( mesh ); diff --git a/examples/webgl_buffergeometry_custom_attributes_particles.html b/examples/webgl_buffergeometry_custom_attributes_particles.html index 3a5e7a3efca779..2033c096e80746 100644 --- a/examples/webgl_buffergeometry_custom_attributes_particles.html +++ b/examples/webgl_buffergeometry_custom_attributes_particles.html @@ -8,7 +8,7 @@
        -
        three.js webgl - buffergeometry custom attributes - particles
        +
        three.js webgl - buffergeometry custom attributes - particles
        - - - - - - - - diff --git a/examples/webgl_buffergeometry_instancing_billboards.html b/examples/webgl_buffergeometry_instancing_billboards.html index 8f0bd933328676..826a29e64082f4 100644 --- a/examples/webgl_buffergeometry_instancing_billboards.html +++ b/examples/webgl_buffergeometry_instancing_billboards.html @@ -21,7 +21,7 @@
        - three.js - instanced circle billboards - colors + three.js - instanced circle billboards - colors
        @@ -129,7 +129,7 @@ } - geometry.addAttribute( 'translate', new THREE.InstancedBufferAttribute( translateArray, 3 ) ); + geometry.setAttribute( 'translate', new THREE.InstancedBufferAttribute( translateArray, 3 ) ); material = new THREE.RawShaderMaterial( { uniforms: { diff --git a/examples/webgl_buffergeometry_instancing_dynamic.html b/examples/webgl_buffergeometry_instancing_dynamic.html deleted file mode 100644 index 6940e6729b09f4..00000000000000 --- a/examples/webgl_buffergeometry_instancing_dynamic.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - three.js webgl - indexed instancing (single box), dynamic updates - - - - - - - -
        -
        - three.js - indexed instancing (single box), dynamic updates - -
        - - - - - - - - - - - - diff --git a/examples/webgl_buffergeometry_instancing_interleaved_dynamic.html b/examples/webgl_buffergeometry_instancing_interleaved.html similarity index 52% rename from examples/webgl_buffergeometry_instancing_interleaved_dynamic.html rename to examples/webgl_buffergeometry_instancing_interleaved.html index fad7112279982f..478cb4fde92fe5 100644 --- a/examples/webgl_buffergeometry_instancing_interleaved_dynamic.html +++ b/examples/webgl_buffergeometry_instancing_interleaved.html @@ -1,7 +1,7 @@ - three.js webgl - indexed instancing (single box), interleaved buffers, dynamic updates + three.js webgl - indexed instancing (single box), interleaved buffers @@ -22,68 +22,28 @@
        - three.js - indexed instancing (single box)
        interleaved buffers, dynamic updates + three.js - indexed instancing (single box), interleaved buffers
        - - - - diff --git a/examples/webgl_buffergeometry_instancing_lambert.html b/examples/webgl_buffergeometry_instancing_lambert.html deleted file mode 100644 index 77d4658d92a979..00000000000000 --- a/examples/webgl_buffergeometry_instancing_lambert.html +++ /dev/null @@ -1,346 +0,0 @@ - - - - three.js webgl - instancing - lambert shader - - - - - - - -
        -
        - three.js - instancing - lambert shader - -
        - - - - - - diff --git a/examples/webgl_buffergeometry_lines.html b/examples/webgl_buffergeometry_lines.html index c8de170b5c676b..f05363c97d2650 100644 --- a/examples/webgl_buffergeometry_lines.html +++ b/examples/webgl_buffergeometry_lines.html @@ -14,7 +14,7 @@
        -
        three.js webgl - buffergeometry - lines
        +
        three.js webgl - buffergeometry - lines
        diff --git a/examples/webgl_geometry_colors.html b/examples/webgl_geometry_colors.html index 40be955d36817d..38dfa2a8e132ba 100644 --- a/examples/webgl_geometry_colors.html +++ b/examples/webgl_geometry_colors.html @@ -18,7 +18,7 @@
        -
        three.js webgl - vertex colors
        +
        three.js webgl - vertex colors
        + + + diff --git a/examples/webgl_instancing_modified.html b/examples/webgl_instancing_modified.html new file mode 100644 index 00000000000000..44875600e48959 --- /dev/null +++ b/examples/webgl_instancing_modified.html @@ -0,0 +1,196 @@ + + + + three.js webgl - instancing - modified + + + + + + +
        + three.js - webgl instancing - modified +
        + + + + + diff --git a/examples/webgl_instancing_performance.html b/examples/webgl_instancing_performance.html new file mode 100644 index 00000000000000..5ac5cf7a655712 --- /dev/null +++ b/examples/webgl_instancing_performance.html @@ -0,0 +1,358 @@ + + + + three.js webgl - instancing - performance + + + + + + + +
        + + three.js webgl - instancing - performance + +
        + +
        + + + + + diff --git a/examples/webgl_instancing_raycast.html b/examples/webgl_instancing_raycast.html new file mode 100644 index 00000000000000..811ecc02b8c640 --- /dev/null +++ b/examples/webgl_instancing_raycast.html @@ -0,0 +1,151 @@ + + + + three.js webgl - instancing - raycast + + + + + + + + diff --git a/examples/webgl_instancing_scatter.html b/examples/webgl_instancing_scatter.html new file mode 100644 index 00000000000000..d5a2e97e877f50 --- /dev/null +++ b/examples/webgl_instancing_scatter.html @@ -0,0 +1,312 @@ + + + + three.js webgl - instancing - scatter + + + + + + + + + + diff --git a/examples/webgl_interactive_buffergeometry.html b/examples/webgl_interactive_buffergeometry.html index 18ecdf026d65d8..e052c1ffcb7919 100644 --- a/examples/webgl_interactive_buffergeometry.html +++ b/examples/webgl_interactive_buffergeometry.html @@ -9,7 +9,7 @@
        -
        three.js webgl - interactive - buffergeometry
        +
        three.js webgl - interactive - buffergeometry
        - - - - - - - - - - - - - - - diff --git a/examples/webgl_interactive_lines.html b/examples/webgl_interactive_lines.html index b60629c0a10373..db16acb7013f6a 100644 --- a/examples/webgl_interactive_lines.html +++ b/examples/webgl_interactive_lines.html @@ -42,7 +42,7 @@ info.style.top = '10px'; info.style.width = '100%'; info.style.textAlign = 'center'; - info.innerHTML = 'three.js webgl - interactive lines'; + info.innerHTML = 'three.js webgl - interactive lines'; container.appendChild( info ); camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 ); @@ -75,7 +75,7 @@ } - lineGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( points, 3 ) ); + lineGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( points, 3 ) ); parentTransform = new THREE.Object3D(); parentTransform.position.x = Math.random() * 40 - 20; @@ -94,13 +94,15 @@ var object; + var lineMaterial = new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } ); + if ( Math.random() > 0.5 ) { - object = new THREE.Line( lineGeometry ); + object = new THREE.Line( lineGeometry, lineMaterial ); } else { - object = new THREE.LineSegments( lineGeometry ); + object = new THREE.LineSegments( lineGeometry, lineMaterial ); } @@ -123,7 +125,7 @@ scene.add( parentTransform ); raycaster = new THREE.Raycaster(); - raycaster.linePrecision = 3; + raycaster.params.Line.threshold = 3; renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); @@ -174,9 +176,9 @@ theta += 0.1; - camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) ); - camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) ); - camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) ); + camera.position.x = radius * Math.sin( THREE.MathUtils.degToRad( theta ) ); + camera.position.y = radius * Math.sin( THREE.MathUtils.degToRad( theta ) ); + camera.position.z = radius * Math.cos( THREE.MathUtils.degToRad( theta ) ); camera.lookAt( scene.position ); camera.updateMatrixWorld(); diff --git a/examples/webgl_interactive_points.html b/examples/webgl_interactive_points.html index e0bf6d43aa339b..e6298384c4ea6e 100644 --- a/examples/webgl_interactive_points.html +++ b/examples/webgl_interactive_points.html @@ -9,7 +9,7 @@
        -
        three.js webgl - interactive - particles
        +
        three.js webgl - interactive - particles
        + + + diff --git a/examples/webgl_lights_hemisphere.html b/examples/webgl_lights_hemisphere.html index e96b3e44720212..f01395316e2c25 100644 --- a/examples/webgl_lights_hemisphere.html +++ b/examples/webgl_lights_hemisphere.html @@ -18,7 +18,7 @@
        - three.js - webgl hemisphere light example
        + three.js - webgl hemisphere light example
        flamingo by mirada from rome

        @@ -190,10 +190,7 @@ renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); - - renderer.gammaInput = true; - renderer.gammaOutput = true; - + renderer.outputEncoding = THREE.sRGBEncoding; renderer.shadowMap.enabled = true; // STATS diff --git a/examples/webgl_lights_physical.html b/examples/webgl_lights_physical.html index 5a6ff62f72481e..edb14a94a22a4c 100644 --- a/examples/webgl_lights_physical.html +++ b/examples/webgl_lights_physical.html @@ -10,7 +10,7 @@
        - three.js - Physically accurate incandescent bulb by Ben Houston
        + three.js - Physically accurate incandescent bulb by Ben Houston
        Real world scale: Brick cube is 50 cm in size. Globe is 50 cm in diameter.
        Reinhard inline tonemapping with real-world light falloff (decay = 2).
        @@ -110,6 +110,7 @@ map.wrapT = THREE.RepeatWrapping; map.anisotropy = 4; map.repeat.set( 10, 24 ); + map.encoding = THREE.sRGBEncoding; floorMat.map = map; floorMat.needsUpdate = true; @@ -147,6 +148,7 @@ map.wrapT = THREE.RepeatWrapping; map.anisotropy = 4; map.repeat.set( 1, 1 ); + map.encoding = THREE.sRGBEncoding; cubeMat.map = map; cubeMat.needsUpdate = true; @@ -170,6 +172,7 @@ textureLoader.load( "textures/planets/earth_atmos_2048.jpg", function ( map ) { map.anisotropy = 4; + map.encoding = THREE.sRGBEncoding; ballMat.map = map; ballMat.needsUpdate = true; @@ -177,6 +180,7 @@ textureLoader.load( "textures/planets/earth_specular_2048.jpg", function ( map ) { map.anisotropy = 4; + map.encoding = THREE.sRGBEncoding; ballMat.metalnessMap = map; ballMat.needsUpdate = true; @@ -214,8 +218,7 @@ renderer = new THREE.WebGLRenderer(); renderer.physicallyCorrectLights = true; - renderer.gammaInput = true; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.shadowMap.enabled = true; renderer.toneMapping = THREE.ReinhardToneMapping; renderer.setPixelRatio( window.devicePixelRatio ); diff --git a/examples/webgl_lights_pointlights.html b/examples/webgl_lights_pointlights.html index eb01af7b6e2f32..a52b0dabbf7b08 100644 --- a/examples/webgl_lights_pointlights.html +++ b/examples/webgl_lights_pointlights.html @@ -9,7 +9,7 @@
        - three.js - point lights WebGL demo.
        + three.js - point lights WebGL demo.
        Walt Disney head by David OReilly
        diff --git a/examples/webgl_lights_pointlights2.html b/examples/webgl_lights_pointlights2.html index f519da89954300..396be245ec4b09 100644 --- a/examples/webgl_lights_pointlights2.html +++ b/examples/webgl_lights_pointlights2.html @@ -10,7 +10,7 @@
        - three.js - point lights WebGL demo + three.js - point lights WebGL demo
        - - - - - - - diff --git a/examples/webgl_lines_colors.html b/examples/webgl_lines_colors.html index ad4dff13100e5b..d3f8f2376a1cfa 100644 --- a/examples/webgl_lines_colors.html +++ b/examples/webgl_lines_colors.html @@ -9,7 +9,7 @@
        - three.js - color lines
        + three.js - color lines
        Hilbert curve thanks to Thomas Diewald
        @@ -79,13 +79,13 @@ } - geometry1.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry2.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry3.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry1.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry2.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry3.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry1.addAttribute( 'color', new THREE.Float32BufferAttribute( colors1, 3 ) ); - geometry2.addAttribute( 'color', new THREE.Float32BufferAttribute( colors2, 3 ) ); - geometry3.addAttribute( 'color', new THREE.Float32BufferAttribute( colors3, 3 ) ); + geometry1.setAttribute( 'color', new THREE.Float32BufferAttribute( colors1, 3 ) ); + geometry2.setAttribute( 'color', new THREE.Float32BufferAttribute( colors2, 3 ) ); + geometry3.setAttribute( 'color', new THREE.Float32BufferAttribute( colors3, 3 ) ); // @@ -115,17 +115,17 @@ } - geometry4.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry5.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry6.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry4.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry5.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); + geometry6.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry4.addAttribute( 'color', new THREE.Float32BufferAttribute( colors1, 3 ) ); - geometry5.addAttribute( 'color', new THREE.Float32BufferAttribute( colors2, 3 ) ); - geometry6.addAttribute( 'color', new THREE.Float32BufferAttribute( colors3, 3 ) ); + geometry4.setAttribute( 'color', new THREE.Float32BufferAttribute( colors1, 3 ) ); + geometry5.setAttribute( 'color', new THREE.Float32BufferAttribute( colors2, 3 ) ); + geometry6.setAttribute( 'color', new THREE.Float32BufferAttribute( colors3, 3 ) ); // Create lines and add to scene - var material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.VertexColors } ); + var material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: true } ); var line, p, scale = 0.3, d = 225; diff --git a/examples/webgl_lines_dashed.html b/examples/webgl_lines_dashed.html index e3db7b68570bad..cda474c777607e 100644 --- a/examples/webgl_lines_dashed.html +++ b/examples/webgl_lines_dashed.html @@ -8,7 +8,7 @@ -
        three.js - dashed lines example
        +
        three.js - dashed lines example
        - - diff --git a/examples/webgl_loader_awd.html b/examples/webgl_loader_awd.html deleted file mode 100644 index 5ea0543f6a0b69..00000000000000 --- a/examples/webgl_loader_awd.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - three.js webgl - collada - - - - - -
        - three.js - AWD loader -
        - - - - diff --git a/examples/webgl_loader_babylon.html b/examples/webgl_loader_babylon.html deleted file mode 100644 index 68ee1024c79c1c..00000000000000 --- a/examples/webgl_loader_babylon.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - three.js webgl - loaders - Babylon loader - - - - - -
        - three.js - Babylon loader -
        - - - - - diff --git a/examples/webgl_loader_collada_kinematics.html b/examples/webgl_loader_collada_kinematics.html index 23e2a9047b145b..6b18951dd474b7 100644 --- a/examples/webgl_loader_collada_kinematics.html +++ b/examples/webgl_loader_collada_kinematics.html @@ -8,7 +8,7 @@
        - three.js collada loader - kinematics
        + three.js collada loader - kinematics
        robot from collada robots
        @@ -106,7 +106,7 @@ function setupTween() { - var duration = THREE.Math.randInt( 1000, 5000 ); + var duration = THREE.MathUtils.randInt( 1000, 5000 ); var target = {}; @@ -124,7 +124,7 @@ tweenParameters[ prop ] = position; - target[ prop ] = THREE.Math.randInt( joint.limits.min, joint.limits.max ); + target[ prop ] = THREE.MathUtils.randInt( joint.limits.min, joint.limits.max ); } diff --git a/examples/webgl_loader_ctm.html b/examples/webgl_loader_ctm.html deleted file mode 100644 index 7305071f46b691..00000000000000 --- a/examples/webgl_loader_ctm.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - three.js webgl - loaders - CTM loader - - - - - - - - - - - diff --git a/examples/webgl_loader_draco.html b/examples/webgl_loader_draco.html index e9363c67049916..40f711ca6c8b71 100644 --- a/examples/webgl_loader_draco.html +++ b/examples/webgl_loader_draco.html @@ -10,7 +10,7 @@
        - three.js - + three.js - DRACO loader
        @@ -24,9 +24,10 @@ var container = document.querySelector( '#container' ); // Configure and create Draco decoder. - DRACOLoader.setDecoderPath( 'js/libs/draco/' ); - DRACOLoader.setDecoderConfig( { type: 'js' } ); var dracoLoader = new DRACOLoader(); + dracoLoader.setDecoderPath( 'js/libs/draco/' ); + dracoLoader.setDecoderConfig( { type: 'js' } ); + init(); animate(); @@ -71,7 +72,7 @@ scene.add( mesh ); // Release decoder resources. - DRACOLoader.releaseDecoderModule(); + dracoLoader.dispose(); } ); @@ -79,8 +80,7 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.gammaInput = true; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.shadowMap.enabled = true; container.appendChild( renderer.domElement ); diff --git a/examples/webgl_loader_fbx.html b/examples/webgl_loader_fbx.html index ff457d437ae7ca..4d65a356eaf034 100644 --- a/examples/webgl_loader_fbx.html +++ b/examples/webgl_loader_fbx.html @@ -9,7 +9,7 @@
        - three.js - FBXLoader
        + three.js - FBXLoader
        Character and animation from Mixamo
        diff --git a/examples/webgl_loader_fbx_nurbs.html b/examples/webgl_loader_fbx_nurbs.html index fca24a269d28bb..34eca6bb66ce05 100644 --- a/examples/webgl_loader_fbx_nurbs.html +++ b/examples/webgl_loader_fbx_nurbs.html @@ -9,7 +9,7 @@
        - three.js - FBXLoader - Nurbs + three.js - FBXLoader - Nurbs
        diff --git a/examples/webgl_loader_gltf_extensions.html b/examples/webgl_loader_gltf_extensions.html index 856fdea4dceab1..661ec43f6bdbd4 100644 --- a/examples/webgl_loader_gltf_extensions.html +++ b/examples/webgl_loader_gltf_extensions.html @@ -9,7 +9,7 @@
        - three.js - + three.js - glTF 2.0 loader
        @@ -26,9 +26,6 @@ import { DDSLoader } from './jsm/loaders/DDSLoader.js'; import { DRACOLoader } from './jsm/loaders/DRACOLoader.js'; import { RGBELoader } from './jsm/loaders/RGBELoader.js'; - import { EquirectangularToCubeGenerator } from './jsm/loaders/EquirectangularToCubeGenerator.js'; - import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js'; - import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js'; var orbitControls; var container, camera, scene, renderer, loader; @@ -146,7 +143,7 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.physicallyCorrectLights = true; container.appendChild( renderer.domElement ); @@ -157,23 +154,12 @@ new RGBELoader() .setDataType( THREE.UnsignedByteType ) .setPath( 'textures/equirectangular/' ) - .load( 'venice_sunset_2k.hdr', function ( texture ) { - - var cubeGenerator = new EquirectangularToCubeGenerator( texture, { resolution: 1024 } ); - cubeGenerator.update( renderer ); - - background = cubeGenerator.renderTarget; - - var pmremGenerator = new PMREMGenerator( cubeGenerator.renderTarget.texture ); - pmremGenerator.update( renderer ); - - var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods ); - pmremCubeUVPacker.update( renderer ); - - envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture; + .load( 'venice_sunset_1k.hdr', function ( texture ) { + envMap = pmremGenerator.fromEquirectangular( texture ).texture; pmremGenerator.dispose(); - pmremCubeUVPacker.dispose(); + + background = envMap; // @@ -183,6 +169,9 @@ } ); + var pmremGenerator = new THREE.PMREMGenerator( renderer ); + pmremGenerator.compileEquirectangularShader(); + } function initScene( sceneInfo ) { @@ -267,8 +256,10 @@ loader = new GLTFLoader(); - DRACOLoader.setDecoderPath( 'js/libs/draco/gltf/' ); - loader.setDRACOLoader( new DRACOLoader() ); + var dracoLoader = new DRACOLoader(); + dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' ); + loader.setDRACOLoader( dracoLoader ); + loader.setDDSLoader( new DDSLoader() ); var url = sceneInfo.url.replace( /%s/g, state.extension ); diff --git a/examples/webgl_loader_imagebitmap.html b/examples/webgl_loader_imagebitmap.html index b7724c008f3705..fd57a4a1db96ba 100644 --- a/examples/webgl_loader_imagebitmap.html +++ b/examples/webgl_loader_imagebitmap.html @@ -8,7 +8,7 @@
        - three.js - Texture loader using ImageBitmap + three.js - Texture loader using ImageBitmap
        - - diff --git a/examples/webgl_loader_ply.html b/examples/webgl_loader_ply.html index 43d6a1a326f3c8..f1554c437e70d7 100644 --- a/examples/webgl_loader_ply.html +++ b/examples/webgl_loader_ply.html @@ -8,7 +8,7 @@
        - three.js - + three.js - PLY loader test by Wei Meng.
        Image from John Burkardt
        @@ -109,9 +109,7 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - - renderer.gammaInput = true; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.shadowMap.enabled = true; diff --git a/examples/webgl_loader_sea3d.html b/examples/webgl_loader_sea3d.html deleted file mode 100644 index bac9d6385e7b8b..00000000000000 --- a/examples/webgl_loader_sea3d.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - three.js webgl - sea3d - - - - - -
        - three.js - Exported by SEA3D Exporter and edited by SEA3D Studio.
        - Asset by Valdez Araujo. - Geometry Compression with Google Draco and content with LZMA using SEA3D I.O. Tools
        -
        - - - - - - diff --git a/examples/webgl_loader_sea3d_bvh.html b/examples/webgl_loader_sea3d_bvh.html deleted file mode 100644 index 52e50c2b96028a..00000000000000 --- a/examples/webgl_loader_sea3d_bvh.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - three.js webgl - sea3d / bvh - - - - - -
        - three.js - Exported by SEA3D Exporter. Asset by Trivision
        - Runtime convertion of BVH Animation to SEA3D Skeleton Animation -
        - - - - - diff --git a/examples/webgl_loader_sea3d_bvh_retarget.html b/examples/webgl_loader_sea3d_bvh_retarget.html deleted file mode 100644 index f0b33ac1c84849..00000000000000 --- a/examples/webgl_loader_sea3d_bvh_retarget.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - three.js webgl - sea3d / bvh / retarget - - - - - -
        - three.js - Exported by SEA3D Exporter. Asset by Trivision
        - Runtime retarget of BVH Animation to SEA3D Skeleton -
        - - - - - diff --git a/examples/webgl_loader_sea3d_hierarchy.html b/examples/webgl_loader_sea3d_hierarchy.html deleted file mode 100644 index 5723e0eb915b08..00000000000000 --- a/examples/webgl_loader_sea3d_hierarchy.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - three.js webgl - sea3d / hierarchy - - - - - -
        - three.js - Exported by SEA3D Exporter and edited by SEA3D Studio.
        Asset by Valdez Araujo. - Geometry compression lossless with LZMA. -
        - - - - diff --git a/examples/webgl_loader_sea3d_keyframe.html b/examples/webgl_loader_sea3d_keyframe.html deleted file mode 100644 index b51136ec90ca45..00000000000000 --- a/examples/webgl_loader_sea3d_keyframe.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - three.js webgl - sea3d / keyframe - - - - - -
        - three.js - Exported by SEA3D Exporter
        -
        Click to play
        -
        - - - - diff --git a/examples/webgl_loader_sea3d_morph.html b/examples/webgl_loader_sea3d_morph.html deleted file mode 100644 index d610ec9eb21681..00000000000000 --- a/examples/webgl_loader_sea3d_morph.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - three.js webgl - sea3d / morph - - - - - -
        - three.js - Exported by SEA3D Exporter
        -
        Flag is Vertex Animation / Teapot is Morpher
        -
        - - - - diff --git a/examples/webgl_loader_sea3d_physics.html b/examples/webgl_loader_sea3d_physics.html deleted file mode 100644 index 7479666890b347..00000000000000 --- a/examples/webgl_loader_sea3d_physics.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - three.js webgl - sea3d / physics - - - - - -
        - three.js - Ammo Physics Example
        - Exported by SEA3D Exporter edited by SEA3D Studio
        -
        Right click to clone
        -
        - - - - - - diff --git a/examples/webgl_loader_sea3d_skinning.html b/examples/webgl_loader_sea3d_skinning.html deleted file mode 100644 index 0f0f864b24fa56..00000000000000 --- a/examples/webgl_loader_sea3d_skinning.html +++ /dev/null @@ -1,242 +0,0 @@ - - - - three.js webgl - sea3d / skinning - - - - - -
        - three.js - Exported by SEA3D Exporter. Asset by Trivision
        - BoneObject: THREE.Object3D attached in a Bone
        - Left Click to hidden/show the hat - Right click to run
        -
        -
        - - - - diff --git a/examples/webgl_loader_sea3d_sound.html b/examples/webgl_loader_sea3d_sound.html deleted file mode 100644 index d79b0c505ad985..00000000000000 --- a/examples/webgl_loader_sea3d_sound.html +++ /dev/null @@ -1,425 +0,0 @@ - - - - three.js webgl - sea3d / sound - - - - - - -
        - three.js - Exported by SEA3D Exporter and edited by SEA3D Studio -
        - -
        - -
        - Click to play -
        - (W, A, S, D = Move, MOUSE = Look around) -
        - -
        - - - - diff --git a/examples/webgl_loader_stl.html b/examples/webgl_loader_stl.html index 2c0ade62070d19..644a9403f47d92 100644 --- a/examples/webgl_loader_stl.html +++ b/examples/webgl_loader_stl.html @@ -8,7 +8,7 @@
        - three.js - + three.js - STL loader test by aleeper.
        PR2 head from www.ros.org
        @@ -116,7 +116,7 @@ var meshMaterial = material; if ( geometry.hasColors ) { - meshMaterial = new THREE.MeshPhongMaterial( { opacity: geometry.alpha, vertexColors: THREE.VertexColors } ); + meshMaterial = new THREE.MeshPhongMaterial( { opacity: geometry.alpha, vertexColors: true } ); } @@ -145,9 +145,7 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - - renderer.gammaInput = true; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.shadowMap.enabled = true; diff --git a/examples/webgl_loader_svg.html b/examples/webgl_loader_svg.html index e5314485bc6e3d..42028222daa44b 100644 --- a/examples/webgl_loader_svg.html +++ b/examples/webgl_loader_svg.html @@ -16,7 +16,7 @@
        - three.js - SVGLoader + three.js - SVGLoader
        - - - diff --git a/examples/webgl_materials_cars.html b/examples/webgl_materials_car.html similarity index 51% rename from examples/webgl_materials_cars.html rename to examples/webgl_materials_car.html index 446fbec9379bf1..c5494877530ff2 100644 --- a/examples/webgl_materials_cars.html +++ b/examples/webgl_materials_car.html @@ -17,14 +17,12 @@
        - three.js car materials demo
        + three.js car materials
        Ferrari 458 Italia model by vicent091036

        Body: Details: Glass: -

        - Follow camera:
        @@ -38,135 +36,106 @@ import { GLTFLoader } from './jsm/loaders/GLTFLoader.js'; import { DRACOLoader } from './jsm/loaders/DRACOLoader.js'; - import { CarControls } from './jsm/misc/CarControls.js'; - - import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js'; - import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js'; + import { RGBELoader } from './jsm/loaders/RGBELoader.js'; - var camera, scene, renderer, stats, carModel, materialsLib, envMap; + var camera, scene, renderer; + var stats, carModel, materialsLib; var bodyMatSelect = document.getElementById( 'body-mat' ); var rimMatSelect = document.getElementById( 'rim-mat' ); var glassMatSelect = document.getElementById( 'glass-mat' ); - var followCamera = document.getElementById( 'camera-toggle' ); - - var clock = new THREE.Clock(); - var carControls = new CarControls(); - carControls.turningRadius = 75; - var carParts = { body: [], rims: [], glass: [], }; - var damping = 5.0; - var distance = 5; - var cameraTarget = new THREE.Vector3(); + var grid, wheels = []; function init() { var container = document.getElementById( 'container' ); - camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 200 ); - camera.position.set( 3.25, 2.0, - 5 ); - camera.lookAt( 0, 0.5, 0 ); + camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 200 ); scene = new THREE.Scene(); - scene.fog = new THREE.Fog( 0xd7cbb1, 1, 80 ); + // scene.fog = new THREE.Fog( 0xd7cbb1, 1, 80 ); - var urls = [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ]; - var loader = new THREE.CubeTextureLoader().setPath( 'textures/cube/skyboxsun25deg/' ); - loader.load( urls, function ( texture ) { + new RGBELoader() + .setDataType( THREE.UnsignedByteType ) + .setPath( 'textures/equirectangular/' ) + .load( 'quarry_01_1k.hdr', function ( texture ) { - scene.background = texture; + var envMap = pmremGenerator.fromEquirectangular( texture ).texture; + pmremGenerator.dispose(); - var pmremGenerator = new PMREMGenerator( texture ); - pmremGenerator.update( renderer ); + scene.background = envMap; + scene.environment = envMap; - var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods ); - pmremCubeUVPacker.update( renderer ); + // - envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture; + initCar(); + initMaterials(); + initMaterialSelectionMenus(); - pmremGenerator.dispose(); - pmremCubeUVPacker.dispose(); - - // - - initCar(); - initMaterials(); - initMaterialSelectionMenus(); - - } ); + } ); var ground = new THREE.Mesh( - new THREE.PlaneBufferGeometry( 2400, 2400 ), - new THREE.ShadowMaterial( { color: 0x000000, opacity: 0.15, depthWrite: false } - ) ); + new THREE.PlaneBufferGeometry( 400, 400 ), + new THREE.MeshBasicMaterial( { color: 0x6e6a62, depthWrite: false } ) + ); ground.rotation.x = - Math.PI / 2; - ground.receiveShadow = true; ground.renderOrder = 1; scene.add( ground ); - var grid = new THREE.GridHelper( 400, 40, 0x000000, 0x000000 ); - grid.material.opacity = 0.2; + grid = new THREE.GridHelper( 400, 80, 0x000000, 0x000000 ); + grid.material.opacity = 0.1; grid.material.depthWrite = false; grid.material.transparent = true; scene.add( grid ); renderer = new THREE.WebGLRenderer( { antialias: true } ); - renderer.gammaOutput = true; renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - container.appendChild( renderer.domElement ); + renderer.outputEncoding = THREE.sRGBEncoding; + renderer.toneMapping = THREE.ACESFilmicToneMapping; + + var pmremGenerator = new THREE.PMREMGenerator( renderer ); + pmremGenerator.compileEquirectangularShader(); + stats = new Stats(); container.appendChild( stats.dom ); window.addEventListener( 'resize', onWindowResize, false ); - renderer.setAnimationLoop( function () { - - update(); - - renderer.render( scene, camera ); - - } ); + renderer.setAnimationLoop( render ); } function initCar() { - DRACOLoader.setDecoderPath( 'js/libs/draco/gltf/' ); + var dracoLoader = new DRACOLoader(); + dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' ); var loader = new GLTFLoader(); - loader.setDRACOLoader( new DRACOLoader() ); + loader.setDRACOLoader( dracoLoader ); loader.load( 'models/gltf/ferrari.glb', function ( gltf ) { carModel = gltf.scene.children[ 0 ]; - carControls.setModel( carModel ); - - carModel.traverse( function ( child ) { - - if ( child.isMesh ) { - - child.material.envMap = envMap; - - } - - } ); - // shadow var texture = new THREE.TextureLoader().load( 'models/gltf/ferrari_ao.png' ); var shadow = new THREE.Mesh( - new THREE.PlaneBufferGeometry( 0.655 * 4, 1.3 * 4 ).rotateX( - Math.PI / 2 ), - new THREE.MeshBasicMaterial( { map: texture, opacity: 0.8, transparent: true } ) + new THREE.PlaneBufferGeometry( 0.655 * 4, 1.3 * 4 ), + new THREE.MeshBasicMaterial( { + map: texture, opacity: 0.7, transparent: true + } ) ); + shadow.rotation.x = - Math.PI / 2; shadow.renderOrder = 2; carModel.add( shadow ); @@ -187,6 +156,13 @@ carModel.getObjectByName( 'glass' ), ); + wheels.push( + carModel.getObjectByName( 'wheel_fl' ), + carModel.getObjectByName( 'wheel_fr' ), + carModel.getObjectByName( 'wheel_rl' ), + carModel.getObjectByName( 'wheel_rr' ) + ); + updateMaterials(); } ); @@ -199,20 +175,38 @@ main: [ - new THREE.MeshStandardMaterial( { color: 0xff4400, envMap: envMap, metalness: 0.9, roughness: 0.2, name: 'orange' } ), - new THREE.MeshStandardMaterial( { color: 0x001166, envMap: envMap, metalness: 0.9, roughness: 0.2, name: 'blue' } ), - new THREE.MeshStandardMaterial( { color: 0x990000, envMap: envMap, metalness: 0.9, roughness: 0.2, name: 'red' } ), - new THREE.MeshStandardMaterial( { color: 0x000000, envMap: envMap, metalness: 0.9, roughness: 0.5, name: 'black' } ), - new THREE.MeshStandardMaterial( { color: 0xffffff, envMap: envMap, metalness: 0.9, roughness: 0.5, name: 'white' } ), - new THREE.MeshStandardMaterial( { color: 0x555555, envMap: envMap, envMapIntensity: 2.0, metalness: 1.0, roughness: 0.2, name: 'metallic' } ), + new THREE.MeshStandardMaterial( { + color: 0xff4400, metalness: 1.0, roughness: 0.2, name: 'orange' + } ), + new THREE.MeshStandardMaterial( { + color: 0x001166, metalness: 1.0, roughness: 0.2, name: 'blue' + } ), + new THREE.MeshStandardMaterial( { + color: 0x990000, metalness: 1.0, roughness: 0.2, name: 'red' + } ), + new THREE.MeshStandardMaterial( { + color: 0x000000, metalness: 1.0, roughness: 0.4, name: 'black' + } ), + new THREE.MeshStandardMaterial( { + color: 0xffffff, metalness: 0.1, roughness: 0.2, name: 'white' + } ), + new THREE.MeshStandardMaterial( { + color: 0xffffff, metalness: 1.0, roughness: 0.2, name: 'metallic' + } ) ], glass: [ - new THREE.MeshStandardMaterial( { color: 0xffffff, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'clear' } ), - new THREE.MeshStandardMaterial( { color: 0x000000, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'smoked' } ), - new THREE.MeshStandardMaterial( { color: 0x001133, envMap: envMap, metalness: 1, roughness: 0, opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'blue' } ), + new THREE.MeshPhysicalMaterial( { + color: 0xffffff, metalness: 0, roughness: 0, transparency: 1.0, transparent: true, name: 'clear' + } ), + new THREE.MeshPhysicalMaterial( { + color: 0x000000, metalness: 0, roughness: 0, transparency: 0.7, transparent: true, name: 'smoked' + } ), + new THREE.MeshPhysicalMaterial( { + color: 0x001133, metalness: 0, roughness: 0, transparency: 0.7, transparent: true, name: 'blue' + } ) ], @@ -244,7 +238,7 @@ } ); - bodyMatSelect.selectedIndex = 3; + bodyMatSelect.selectedIndex = 2; rimMatSelect.selectedIndex = 5; glassMatSelect.selectedIndex = 0; @@ -276,41 +270,24 @@ } - function update() { - - var delta = clock.getDelta(); - - if ( carModel ) { + function render() { - carControls.update( delta / 3 ); + var time = - performance.now() / 1000; - if ( carModel.position.length() > 200 ) { - - carModel.position.set( 0, 0, 0 ); - carControls.speed = 0; - - } - - if ( followCamera.checked ) { - - carModel.getWorldPosition( cameraTarget ); - cameraTarget.y = 2.5; - cameraTarget.z += distance; - - camera.position.lerp( cameraTarget, delta * damping ); - - } else { + camera.position.x = Math.cos( time / 10 ) * 6; + camera.position.y = 1.5; + camera.position.z = Math.sin( time / 10 ) * 6; + camera.lookAt( 0, 0.5, 0 ); - carModel.getWorldPosition( cameraTarget ); - cameraTarget.y += 0.5; + for ( var i = 0; i < wheels.length; i ++ ) { - camera.position.set( 3.25, 2.0, - 5 ); + wheels[ i ].rotation.x = time * Math.PI; - } + } - camera.lookAt( carModel.position ); + grid.position.z = - ( time ) % 5; - } + renderer.render( scene, camera ); stats.update(); diff --git a/examples/webgl_materials_channels.html b/examples/webgl_materials_channels.html index bce168db43c403..887a72f14b6c28 100644 --- a/examples/webgl_materials_channels.html +++ b/examples/webgl_materials_channels.html @@ -9,7 +9,7 @@
        - three.js - Normal, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
        + three.js - Normal, Depth, DepthRGBA, DepthRGBAUnpacked, Materials
        by Ben Houston. ninja head from AMD GPU MeshMapper
        diff --git a/examples/webgl_materials_clearcoat_normalmap.html b/examples/webgl_materials_clearcoat_normalmap.html deleted file mode 100644 index cd7dcf34591852..00000000000000 --- a/examples/webgl_materials_clearcoat_normalmap.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - three.js webgl - materials - clearcoat normal - - - - - - - -
        - three.js - webgl - materials - clearcoat normal map
        -
        - - - - diff --git a/examples/webgl_materials_compile.html b/examples/webgl_materials_compile.html index ab56ee5529dada..297eabe2e3be36 100644 --- a/examples/webgl_materials_compile.html +++ b/examples/webgl_materials_compile.html @@ -25,7 +25,7 @@
        - three.js - Node-Based Material + three.js - Node-Based Material
        change preload
        @@ -58,7 +58,6 @@ var frame = new NodeFrame(); var teapot; var controls; - var rtTexture, rtMaterial; var meshes = []; document.getElementById( "preload" ).addEventListener( 'click', function () { @@ -151,20 +150,6 @@ if ( mesh.material ) mesh.material.dispose(); - if ( rtTexture ) { - - rtTexture.dispose(); - rtTexture = null; - - } - - if ( rtMaterial ) { - - rtMaterial.dispose(); - rtMaterial = null; - - } - var mtl = new PhongNodeMaterial(); var time = new TimerNode(); @@ -218,8 +203,6 @@ renderer.setSize( width, height ); - if ( rtTexture ) rtTexture.setSize( width, height ); - } function animate() { diff --git a/examples/webgl_materials_cubemap.html b/examples/webgl_materials_cubemap.html index da2dc2f72bcd49..53a75460227615 100644 --- a/examples/webgl_materials_cubemap.html +++ b/examples/webgl_materials_cubemap.html @@ -10,7 +10,7 @@
        - three.js - cube mapping demo.
        + three.js - cube mapping demo.
        Texture by Humus, Walt Disney head by David OReilly
        @@ -50,11 +50,8 @@ ]; var reflectionCube = new THREE.CubeTextureLoader().load( urls ); - reflectionCube.format = THREE.RGBFormat; - var refractionCube = new THREE.CubeTextureLoader().load( urls ); refractionCube.mapping = THREE.CubeRefractionMapping; - refractionCube.format = THREE.RGBFormat; scene = new THREE.Scene(); scene.background = reflectionCube; diff --git a/examples/webgl_materials_cubemap_balls_reflection.html b/examples/webgl_materials_cubemap_balls_reflection.html index 46d5c7f6f06ceb..cfcdf4bc7c42a6 100644 --- a/examples/webgl_materials_cubemap_balls_reflection.html +++ b/examples/webgl_materials_cubemap_balls_reflection.html @@ -8,7 +8,7 @@
        - three.js - webgl cube reflection demo.
        + three.js - webgl cube reflection demo.
        skybox by Paul Debevec
        diff --git a/examples/webgl_materials_cubemap_balls_refraction.html b/examples/webgl_materials_cubemap_balls_refraction.html index 1ce6c0ba038deb..e4eea3a6ee3512 100644 --- a/examples/webgl_materials_cubemap_balls_refraction.html +++ b/examples/webgl_materials_cubemap_balls_refraction.html @@ -8,7 +8,7 @@
        - three.js - webgl cube refraction demo.
        + three.js - webgl cube refraction demo.
        skybox by Jochum Skoglund
        diff --git a/examples/webgl_materials_cubemap_dynamic.html b/examples/webgl_materials_cubemap_dynamic.html index 9febe2b9260c52..b2ffd70ab45eff 100644 --- a/examples/webgl_materials_cubemap_dynamic.html +++ b/examples/webgl_materials_cubemap_dynamic.html @@ -8,14 +8,12 @@ -
        three.js webgl - materials - dynamic cube reflection
        Photo by Jón Ragnarsson.
        +
        three.js webgl - materials - dynamic cube reflection
        Photo by Jón Ragnarsson.
        + + diff --git a/examples/webgl_materials_reflectivity.html b/examples/webgl_materials_physical_reflectivity.html similarity index 81% rename from examples/webgl_materials_reflectivity.html rename to examples/webgl_materials_physical_reflectivity.html index 5a05ee5f54e557..3c70570f0f0ff4 100644 --- a/examples/webgl_materials_reflectivity.html +++ b/examples/webgl_materials_physical_reflectivity.html @@ -1,7 +1,7 @@ - threejs webgl - materials - hdr environment mapping + threejs webgl - materials - physical - reflectivity @@ -10,7 +10,7 @@
        - threejs - Standard Material Reflectivity (reflectance at F0)
        + threejs - Physical Material Reflectivity (reflectance at F0)
        example by Ben Houston.
        @@ -23,9 +23,7 @@ import { GUI } from './jsm/libs/dat.gui.module.js'; import { OrbitControls } from './jsm/controls/OrbitControls.js'; import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js'; - import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js'; - import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js'; + import { RGBELoader } from './jsm/loaders/RGBELoader.js'; var container, stats; var params = { @@ -59,7 +57,7 @@ gemBackMaterial = new THREE.MeshPhysicalMaterial( { map: null, color: 0x0000ff, - metalness: 1.0, + metalness: 1, roughness: 0, opacity: 0.5, side: THREE.BackSide, @@ -72,12 +70,12 @@ gemFrontMaterial = new THREE.MeshPhysicalMaterial( { map: null, color: 0x0000ff, - metalness: 0.0, + metalness: 0, roughness: 0, - opacity: 0.15, + opacity: 0.25, side: THREE.FrontSide, transparent: true, - envMapIntensity: 5, + envMapIntensity: 10, premultipliedAlpha: true } ); @@ -113,39 +111,23 @@ } ); - var genCubeUrls = function ( prefix, postfix ) { - - return [ - prefix + 'px' + postfix, prefix + 'nx' + postfix, - prefix + 'py' + postfix, prefix + 'ny' + postfix, - prefix + 'pz' + postfix, prefix + 'nz' + postfix - ]; - - }; - - var hdrUrls = genCubeUrls( "./textures/cube/pisaHDR/", ".hdr" ); - - new HDRCubeTextureLoader() + new RGBELoader() .setDataType( THREE.UnsignedByteType ) - .load( hdrUrls, function ( hdrCubeMap ) { + .setPath( 'textures/equirectangular/' ) + .load( 'royal_esplanade_1k.hdr', function ( hdrEquirect ) { - var pmremGenerator = new PMREMGenerator( hdrCubeMap ); - pmremGenerator.update( renderer ); - - var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods ); - pmremCubeUVPacker.update( renderer ); - - hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget; + hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect ); + pmremGenerator.dispose(); gemFrontMaterial.envMap = gemBackMaterial.envMap = hdrCubeRenderTarget.texture; gemFrontMaterial.needsUpdate = gemBackMaterial.needsUpdate = true; - hdrCubeMap.dispose(); - pmremGenerator.dispose(); - pmremCubeUVPacker.dispose(); + hdrEquirect.dispose(); } ); + var pmremGenerator = new THREE.PMREMGenerator( renderer ); + pmremGenerator.compileEquirectangularShader(); // Lights @@ -173,7 +155,7 @@ renderer.shadowMap.enabled = true; container.appendChild( renderer.domElement ); - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; stats = new Stats(); container.appendChild( stats.dom ); diff --git a/examples/webgl_materials_physical_sheen.html b/examples/webgl_materials_physical_sheen.html new file mode 100644 index 00000000000000..1ead0fcfb41bf2 --- /dev/null +++ b/examples/webgl_materials_physical_sheen.html @@ -0,0 +1,203 @@ + + + Sheen demo (material property) + + + + + + +
        Sheen demo by DanielSturk
        +
        + + + + + + + diff --git a/examples/webgl_materials_physical_transparency.html b/examples/webgl_materials_physical_transparency.html new file mode 100644 index 00000000000000..e6a446bbda2768 --- /dev/null +++ b/examples/webgl_materials_physical_transparency.html @@ -0,0 +1,250 @@ + + + + threejs webgl - materials - transparency + + + + + + +
        +
        threejs - Transparency with Premultiplied Alpha (right) and without (left)
        + + + + diff --git a/examples/webgl_materials_shaders_fresnel.html b/examples/webgl_materials_shaders_fresnel.html index 69349cefaac50d..a2665e22d5186e 100644 --- a/examples/webgl_materials_shaders_fresnel.html +++ b/examples/webgl_materials_shaders_fresnel.html @@ -10,7 +10,7 @@
        - three.js - webgl cube Fresnel shader demo.
        texture by Humus + three.js - webgl cube Fresnel shader demo.
        texture by Humus
        - - - diff --git a/examples/webgl_materials_standard.html b/examples/webgl_materials_standard.html index 572746b43c09dc..0f3338b1ab8750 100644 --- a/examples/webgl_materials_standard.html +++ b/examples/webgl_materials_standard.html @@ -9,7 +9,7 @@
        - three.js - webgl physically based material
        + three.js - webgl physically based material
        Cerberus(FFVII Gun) model by Andrew Maximov.
        @@ -21,8 +21,7 @@ import { TrackballControls } from './jsm/controls/TrackballControls.js'; import { OBJLoader } from './jsm/loaders/OBJLoader.js'; - import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js'; - import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js'; + import { RGBELoader } from './jsm/loaders/RGBELoader.js'; var statsEnabled = true; @@ -43,8 +42,7 @@ renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); - renderer.gammaInput = true; - renderer.gammaOutput = true; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.toneMapping = THREE.ReinhardToneMapping; renderer.toneMappingExposure = 3; @@ -75,7 +73,9 @@ material.roughness = 1; // attenuates roughnessMap material.metalness = 1; // attenuates metalnessMap - material.map = loader.load( 'Cerberus_A.jpg' ); + var diffuseMap = loader.load( 'Cerberus_A.jpg' ); + diffuseMap.encoding = THREE.sRGBEncoding; + material.map = diffuseMap; // roughness is in G channel, metalness is in B channel material.metalnessMap = material.roughnessMap = loader.load( 'Cerberus_RM.jpg' ); material.normalMap = loader.load( 'Cerberus_N.jpg' ); @@ -87,7 +87,7 @@ group.traverse( function ( child ) { - if ( child instanceof THREE.Mesh ) { + if ( child.isMesh ) { child.material = material; @@ -101,32 +101,23 @@ } ); - new THREE.CubeTextureLoader().setPath( './textures/cube/pisaRGBM16/' ) - .load( [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ], function ( rgbmCubeMap ) { - - rgbmCubeMap.encoding = THREE.RGBM16Encoding; - rgbmCubeMap.format = THREE.RGBAFormat; - - var pmremGenerator = new PMREMGenerator( rgbmCubeMap ); - pmremGenerator.update( renderer ); - - var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods ); - pmremCubeUVPacker.update( renderer ); - - var rgbmCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget; - - material.envMap = rgbmCubeRenderTarget.texture; - material.needsUpdate = true; // is this needed? - - rgbmCubeMap.magFilter = THREE.LinearFilter; - rgbmCubeMap.needsUpdate = true; - scene.background = rgbmCubeMap; + new RGBELoader() + .setDataType( THREE.UnsignedByteType ) + .setPath( 'textures/equirectangular/' ) + .load( 'venice_sunset_1k.hdr', function ( hdrEquirect ) { + var hdrCubeRenderTarget = pmremGenerator.fromEquirectangular( hdrEquirect ); + hdrEquirect.dispose(); pmremGenerator.dispose(); - pmremCubeUVPacker.dispose(); + + scene.background = hdrCubeRenderTarget.texture; + scene.environment = hdrCubeRenderTarget.texture; } ); + var pmremGenerator = new THREE.PMREMGenerator( renderer ); + pmremGenerator.compileEquirectangularShader(); + // if ( statsEnabled ) { diff --git a/examples/webgl_materials_texture_anisotropy.html b/examples/webgl_materials_texture_anisotropy.html index 5041ff9d867882..0d9c23c7e8c969 100644 --- a/examples/webgl_materials_texture_anisotropy.html +++ b/examples/webgl_materials_texture_anisotropy.html @@ -42,7 +42,7 @@
        - three.js - anisotropic texture filtering example + three.js - anisotropic texture filtering example
        @@ -192,7 +192,7 @@ function render() { camera.position.x += ( mouseX - camera.position.x ) * .05; - camera.position.y = THREE.Math.clamp( camera.position.y + ( - ( mouseY - 200 ) - camera.position.y ) * .05, 50, 1000 ); + camera.position.y = THREE.MathUtils.clamp( camera.position.y + ( - ( mouseY - 200 ) - camera.position.y ) * .05, 50, 1000 ); camera.lookAt( scene1.position ); diff --git a/examples/webgl_materials_texture_canvas.html b/examples/webgl_materials_texture_canvas.html index 7917feb125b029..548fbdcc256456 100755 --- a/examples/webgl_materials_texture_canvas.html +++ b/examples/webgl_materials_texture_canvas.html @@ -19,7 +19,7 @@
        - three.js - webgl - canvas as a texture + three.js - webgl - canvas as a texture
        click and draw in the white box
        diff --git a/examples/webgl_materials_texture_filters.html b/examples/webgl_materials_texture_filters.html index 26b114a7f9aa7b..0c7e085baf8be7 100644 --- a/examples/webgl_materials_texture_filters.html +++ b/examples/webgl_materials_texture_filters.html @@ -19,7 +19,7 @@
        - three.js - texture filtering example
        + three.js - texture filtering example
        painting by Caravaggio
        diff --git a/examples/webgl_materials_texture_manualmipmap.html b/examples/webgl_materials_texture_manualmipmap.html index 11a3728edd19d4..1b9f7949a65886 100644 --- a/examples/webgl_materials_texture_manualmipmap.html +++ b/examples/webgl_materials_texture_manualmipmap.html @@ -19,7 +19,7 @@
        - three.js - texture manual mipmapping example
        + three.js - texture manual mipmapping example
        painting by Caravaggio
        diff --git a/examples/webgl_materials_texture_partialupdate.html b/examples/webgl_materials_texture_partialupdate.html index 3e90219c1e5ee5..590c2e2a5db19a 100644 --- a/examples/webgl_materials_texture_partialupdate.html +++ b/examples/webgl_materials_texture_partialupdate.html @@ -84,8 +84,8 @@ last = elapsedTime; - position.x = ( 32 * THREE.Math.randInt( 1, 16 ) ) - 32; - position.y = ( 32 * THREE.Math.randInt( 1, 16 ) ) - 32; + position.x = ( 32 * THREE.MathUtils.randInt( 1, 16 ) ) - 32; + position.y = ( 32 * THREE.MathUtils.randInt( 1, 16 ) ) - 32; // generate new color data diff --git a/examples/webgl_materials_texture_rotation.html b/examples/webgl_materials_texture_rotation.html index 0b1b891b02c18d..858b6653a1e5af 100644 --- a/examples/webgl_materials_texture_rotation.html +++ b/examples/webgl_materials_texture_rotation.html @@ -9,7 +9,7 @@
        - three.js webgl - texture rotation + three.js webgl - texture rotation
        - - diff --git a/examples/webgl_materials_variations_basic.html b/examples/webgl_materials_variations_basic.html index 875f89d25b7b59..d4e6322d323f8b 100644 --- a/examples/webgl_materials_variations_basic.html +++ b/examples/webgl_materials_variations_basic.html @@ -9,7 +9,7 @@
        -
        three.js - Basic Material Variantions by Ben Houston.
        +
        three.js - Basic Material Variantions by Ben Houston.
        + + + diff --git a/examples/webgl_mirror.html b/examples/webgl_mirror.html index 0c1905a7df16c8..2be20ce9d940f4 100644 --- a/examples/webgl_mirror.html +++ b/examples/webgl_mirror.html @@ -17,7 +17,7 @@
        -
        three.js - mirror +
        three.js - mirror
        + + diff --git a/examples/webgl_points_billboards.html b/examples/webgl_points_billboards.html index b4d2b7ad70ac6c..3b014e670a6e91 100644 --- a/examples/webgl_points_billboards.html +++ b/examples/webgl_points_billboards.html @@ -9,7 +9,7 @@
        - three.js - webgl particle billboards example + three.js - webgl particle billboards example
        + + diff --git a/examples/webgl_shadowmap.html b/examples/webgl_shadowmap.html index db34488f23e876..471c6d078dd6df 100644 --- a/examples/webgl_shadowmap.html +++ b/examples/webgl_shadowmap.html @@ -10,7 +10,7 @@
        - three.js - shadowmap - models by mirada from rome
        + three.js - shadowmap - models by mirada from rome
        move camera with WASD / RF + mouse
        t: toggle HUD
        @@ -65,27 +65,18 @@ scene.background = new THREE.Color( 0x59472b ); scene.fog = new THREE.Fog( 0x59472b, 1000, FAR ); - controls = new FirstPersonControls( camera ); - - controls.lookSpeed = 0.0125; - controls.movementSpeed = 500; - controls.noFly = false; - controls.lookVertical = true; - - controls.lookAt( scene.position ); - // LIGHTS var ambient = new THREE.AmbientLight( 0x444444 ); scene.add( ambient ); - light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 2 ); + light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 5, 0.3 ); light.position.set( 0, 1500, 1000 ); light.target.position.set( 0, 0, 0 ); light.castShadow = true; - - light.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 1200, 2500 ) ); + light.shadow.camera.near = 1200; + light.shadow.camera.far = 2500; light.shadow.bias = 0.0001; light.shadow.mapSize.width = SHADOW_MAP_WIDTH; @@ -103,8 +94,7 @@ renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); container.appendChild( renderer.domElement ); - renderer.gammaOutput = true; - renderer.gammaFactor = 2.2; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.autoClear = false; // @@ -112,6 +102,17 @@ renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFShadowMap; + // CONTROLS + + controls = new FirstPersonControls( camera, renderer.domElement ); + + controls.lookSpeed = 0.0125; + controls.movementSpeed = 500; + controls.noFly = false; + controls.lookVertical = true; + + controls.lookAt( scene.position ); + // STATS stats = new Stats(); diff --git a/examples/webgl_shadowmap_csm.html b/examples/webgl_shadowmap_csm.html new file mode 100644 index 00000000000000..d05a87ed15de1f --- /dev/null +++ b/examples/webgl_shadowmap_csm.html @@ -0,0 +1,288 @@ + + + + three.js webgl - cascaded shadow maps + + + + + + +
        +
        + three.js webgl - cascaded shadow maps
        + by vHawk (original repository) +
        + + + + + diff --git a/examples/webgl_shadowmap_pcss.html b/examples/webgl_shadowmap_pcss.html index e1a3b0a017b7ae..5ebfe462f15c58 100644 --- a/examples/webgl_shadowmap_pcss.html +++ b/examples/webgl_shadowmap_pcss.html @@ -238,9 +238,7 @@ container.appendChild( renderer.domElement ); - renderer.gammaInput = true; - renderer.gammaOutput = true; - + renderer.outputEncoding = THREE.sRGBEncoding; renderer.shadowMap.enabled = true; // controls diff --git a/examples/webgl_shadowmap_performance.html b/examples/webgl_shadowmap_performance.html index c836df0d220107..8439f3049c71df 100644 --- a/examples/webgl_shadowmap_performance.html +++ b/examples/webgl_shadowmap_performance.html @@ -10,7 +10,7 @@
        - three.js - shadowmap - models by mirada from rome
        + three.js - shadowmap - models by mirada from rome
        move camera with WASD / RF + mouse
        @@ -62,28 +62,18 @@ scene.background = new THREE.Color( 0x59472b ); scene.fog = new THREE.Fog( 0x59472b, 1000, FAR ); - controls = new FirstPersonControls( camera ); - - controls.lookSpeed = 0.0125; - controls.movementSpeed = 500; - controls.noFly = false; - controls.lookVertical = true; - - controls.lookAt( scene.position ); - // LIGHTS var ambient = new THREE.AmbientLight( 0x444444 ); scene.add( ambient ); - light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 2 ); + light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 5, 0.3 ); light.position.set( 0, 1500, 1000 ); light.target.position.set( 0, 0, 0 ); light.castShadow = true; - - light.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 700, FAR ) ); - + light.shadow.camera.near = 1200; + light.shadow.camera.far = 2500; light.shadow.bias = 0.0001; light.shadow.mapSize.width = SHADOW_MAP_WIDTH; @@ -100,8 +90,7 @@ renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); container.appendChild( renderer.domElement ); - renderer.gammaOutput = true; - renderer.gammaFactor = 2.2; + renderer.outputEncoding = THREE.sRGBEncoding; renderer.autoClear = false; // @@ -109,6 +98,17 @@ renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; + // CONTROLS + + controls = new FirstPersonControls( camera, renderer.domElement ); + + controls.lookSpeed = 0.0125; + controls.movementSpeed = 500; + controls.noFly = false; + controls.lookVertical = true; + + controls.lookAt( scene.position ); + // STATS stats = new Stats(); diff --git a/examples/webgl_shadowmap_pointlight.html b/examples/webgl_shadowmap_pointlight.html index 54a936915b33e7..255f3542358484 100644 --- a/examples/webgl_shadowmap_pointlight.html +++ b/examples/webgl_shadowmap_pointlight.html @@ -8,7 +8,7 @@
        - three.js - THREE.PointLight ShadowMap by mkkellogg + three.js - THREE.PointLight ShadowMap by mkkellogg
        + + diff --git a/examples/webgl_shadowmesh.html b/examples/webgl_shadowmesh.html index 6b0251513ea8b9..f3bbeece28e770 100644 --- a/examples/webgl_shadowmesh.html +++ b/examples/webgl_shadowmesh.html @@ -8,7 +8,7 @@
        - three.js - shadow mesh
        + three.js - shadow mesh
        diff --git a/examples/webgl_simple_gi.html b/examples/webgl_simple_gi.html index c139d8a23e4e37..c41536da0bc96e 100644 --- a/examples/webgl_simple_gi.html +++ b/examples/webgl_simple_gi.html @@ -9,7 +9,7 @@
        - three.js - simple global illumination (article) + three.js - simple global illumination (article)
        - - - - - - - diff --git a/examples/webgl_tiled_forward.html b/examples/webgl_tiled_forward.html index c2d5cd365a405e..84a146b5d6d05a 100644 --- a/examples/webgl_tiled_forward.html +++ b/examples/webgl_tiled_forward.html @@ -8,7 +8,7 @@
        - threejs - Tiled forward lighting
        + threejs - Tiled forward lighting
        Created by wizgrav.
        @@ -233,6 +233,8 @@ transparent: tIndex === index ? true : false, } ); + mtl.extensions.derivatives = true; + mtl.uniforms[ "opacity" ].value = tIndex === index ? 0.9 : 1; mtl.uniforms[ "tileData" ] = State.tileData; mtl.uniforms[ "tileTexture" ] = State.tileTexture; diff --git a/examples/webgl_tonemapping.html b/examples/webgl_tonemapping.html index 5c787f89f1787c..d7694daa31e165 100644 --- a/examples/webgl_tonemapping.html +++ b/examples/webgl_tonemapping.html @@ -1,42 +1,38 @@ - three.js webgl - inline tone mapping + three.js webgl - tone mapping - -
        -
        threejs - Inline Tone Mapping (within a Material's fragment shader) without
        using a pre-processing step or float/half buffers by Ben Houston.
        + +
        + three.js - Tone Mapping
        + Battle Damaged Sci-fi Helmet by + theblueturtle_
        + Royal Esplanade by HDRI Haven +
        - - - - - - diff --git a/examples/webvr_paint.html b/examples/webvr_paint.html deleted file mode 100644 index 19f38304b9fb66..00000000000000 --- a/examples/webvr_paint.html +++ /dev/null @@ -1,372 +0,0 @@ - - - - three.js webvr - paint - - - - - - - - -
        - three.js webvr - paint -
        - - - - - - diff --git a/examples/webvr_vive_paint.html b/examples/webvr_vive_paint.html deleted file mode 100644 index d8e5eced23390c..00000000000000 --- a/examples/webvr_vive_paint.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - three.js webvr - htc vive - paint - - - - - - - - -
        - three.js webgl - htc vive - paint -
        - - - - - - diff --git a/examples/webvr_vive_sculpt.html b/examples/webvr_vive_sculpt.html deleted file mode 100644 index f820560addaa0d..00000000000000 --- a/examples/webvr_vive_sculpt.html +++ /dev/null @@ -1,304 +0,0 @@ - - - - three.js webvr - htc vive - sculpt - - - - - - - - -
        - three.js webgl - htc vive - sculpt -
        - - - - - - diff --git a/examples/webxr_ar_cones.html b/examples/webxr_ar_cones.html new file mode 100644 index 00000000000000..462d62aa741210 --- /dev/null +++ b/examples/webxr_ar_cones.html @@ -0,0 +1,101 @@ + + + + three.js ar - cones + + + + + + +
        + three.js ar - cones
        Enable chrome://flags/#webxr-ar-module
        (Chrome Android 80+) +
        + + + + diff --git a/examples/webxr_ar_hittest.html b/examples/webxr_ar_hittest.html new file mode 100644 index 00000000000000..da50b28ba56fea --- /dev/null +++ b/examples/webxr_ar_hittest.html @@ -0,0 +1,167 @@ + + + + three.js ar - hit test + + + + + + +
        + three.js ar - hit test
        Enable chrome://flags/#webxr-ar-module
        Enable chrome://flags/#webxr-hit-test
        (Chrome Android 81+) +
        + + + + diff --git a/examples/webxr_ar_paint.html b/examples/webxr_ar_paint.html new file mode 100644 index 00000000000000..7a3ffe034263d2 --- /dev/null +++ b/examples/webxr_ar_paint.html @@ -0,0 +1,145 @@ + + + + three.js ar - paint + + + + + + +
        + three.js ar - paint
        Enable chrome://flags/#webxr-ar-module
        (Chrome Android 80+) +
        + + + + diff --git a/examples/webvr_ballshooter.html b/examples/webxr_vr_ballshooter.html similarity index 64% rename from examples/webvr_ballshooter.html rename to examples/webxr_vr_ballshooter.html index 0dd13675ad7f61..c9a788d5f76859 100644 --- a/examples/webvr_ballshooter.html +++ b/examples/webxr_vr_ballshooter.html @@ -1,17 +1,15 @@ - three.js webvr - ball shooter + three.js vr - ball shooter - -
        - three.js webvr - ball shooter + three.js vr - ball shooter
        @@ -21,10 +19,12 @@ import * as THREE from '../build/three.module.js'; import { BoxLineGeometry } from './jsm/geometries/BoxLineGeometry.js'; - import { WEBVR } from './jsm/vr/WebVR.js'; + import { VRButton } from './jsm/webxr/VRButton.js'; + import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js'; var camera, scene, renderer; var controller1, controller2; + var controllerGrip1, controllerGrip2; var room; @@ -43,7 +43,8 @@ scene = new THREE.Scene(); scene.background = new THREE.Color( 0x505050 ); - camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 ); + camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10 ); + camera.position.set( 0, 1.6, 3 ); room = new THREE.LineSegments( new BoxLineGeometry( 6, 6, 6, 10, 10, 10 ), @@ -52,8 +53,10 @@ room.geometry.translate( 0, 3, 0 ); scene.add( room ); - var light = new THREE.HemisphereLight( 0xffffff, 0x444444 ); - light.position.set( 1, 1, 1 ); + scene.add( new THREE.HemisphereLight( 0x606060, 0x404040 ) ); + + var light = new THREE.DirectionalLight( 0xffffff ); + light.position.set( 1, 1, 1 ).normalize(); scene.add( light ); var geometry = new THREE.IcosahedronBufferGeometry( radius, 2 ); @@ -80,12 +83,13 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.vr.enabled = true; + renderer.outputEncoding = THREE.sRGBEncoding; + renderer.xr.enabled = true; document.body.appendChild( renderer.domElement ); // - document.body.appendChild( WEBVR.createButton( renderer ) ); + document.body.appendChild( VRButton.createButton( renderer ) ); // controllers @@ -101,26 +105,50 @@ } - controller1 = renderer.vr.getController( 0 ); + controller1 = renderer.xr.getController( 0 ); controller1.addEventListener( 'selectstart', onSelectStart ); controller1.addEventListener( 'selectend', onSelectEnd ); + controller1.addEventListener( 'connected', function ( event ) { + + this.add( buildController( event.data ) ); + + } ); + controller1.addEventListener( 'disconnected', function () { + + this.remove( this.children[ 0 ] ); + + } ); scene.add( controller1 ); - controller2 = renderer.vr.getController( 1 ); + controller2 = renderer.xr.getController( 1 ); controller2.addEventListener( 'selectstart', onSelectStart ); controller2.addEventListener( 'selectend', onSelectEnd ); + controller2.addEventListener( 'connected', function ( event ) { + + this.add( buildController( event.data ) ); + + } ); + controller2.addEventListener( 'disconnected', function () { + + this.remove( this.children[ 0 ] ); + + } ); scene.add( controller2 ); - // helpers + // The XRControllerModelFactory will automatically fetch controller models + // that match what the user is holding as closely as possible. The models + // should be attached to the object returned from getControllerGrip in + // order to match the orientation of the held device. - var geometry = new THREE.BufferGeometry(); - geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 0, 0, - 1 ], 3 ) ); - geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( [ 0.5, 0.5, 0.5, 0, 0, 0 ], 3 ) ); + var controllerModelFactory = new XRControllerModelFactory(); - var material = new THREE.LineBasicMaterial( { vertexColors: true, blending: THREE.AdditiveBlending } ); + controllerGrip1 = renderer.xr.getControllerGrip( 0 ); + controllerGrip1.add( controllerModelFactory.createControllerModel( controllerGrip1 ) ); + scene.add( controllerGrip1 ); - controller1.add( new THREE.Line( geometry, material ) ); - controller2.add( new THREE.Line( geometry, material ) ); + controllerGrip2 = renderer.xr.getControllerGrip( 1 ); + controllerGrip2.add( controllerModelFactory.createControllerModel( controllerGrip2 ) ); + scene.add( controllerGrip2 ); // @@ -128,6 +156,30 @@ } + function buildController( data ) { + + switch ( data.targetRayMode ) { + + case 'tracked-pointer': + + var geometry = new THREE.BufferGeometry(); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 0, 0, - 1 ], 3 ) ); + geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( [ 0.5, 0.5, 0.5, 0, 0, 0 ], 3 ) ); + + var material = new THREE.LineBasicMaterial( { vertexColors: true, blending: THREE.AdditiveBlending } ); + + return new THREE.Line( geometry, material ); + + case 'gaze': + + var geometry = new THREE.RingBufferGeometry( 0.02, 0.04, 32 ).translate( 0, 0, - 1 ); + var material = new THREE.MeshBasicMaterial( { opacity: 0.5, transparent: true } ); + return new THREE.Mesh( geometry, material ); + + } + + } + function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; @@ -186,7 +238,7 @@ if ( object.position.x < - range || object.position.x > range ) { - object.position.x = THREE.Math.clamp( object.position.x, - range, range ); + object.position.x = THREE.MathUtils.clamp( object.position.x, - range, range ); object.userData.velocity.x = - object.userData.velocity.x; } @@ -203,7 +255,7 @@ if ( object.position.z < - range || object.position.z > range ) { - object.position.z = THREE.Math.clamp( object.position.z, - range, range ); + object.position.z = THREE.MathUtils.clamp( object.position.z, - range, range ); object.userData.velocity.z = - object.userData.velocity.z; } diff --git a/examples/webvr_cubes.html b/examples/webxr_vr_cubes.html similarity index 60% rename from examples/webvr_cubes.html rename to examples/webxr_vr_cubes.html index ef09339cc59dd1..55a86832f815f5 100644 --- a/examples/webvr_cubes.html +++ b/examples/webxr_vr_cubes.html @@ -1,17 +1,15 @@ - three.js webvr - cubes + three.js vr - cubes - -
        - three.js webgl - interactive cubes + three.js vr - interactive cubes
        @@ -21,7 +19,8 @@ import * as THREE from '../build/three.module.js'; import { BoxLineGeometry } from './jsm/geometries/BoxLineGeometry.js'; - import { WEBVR } from './jsm/vr/WebVR.js'; + import { VRButton } from './jsm/webxr/VRButton.js'; + import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js'; var clock = new THREE.Clock(); @@ -29,10 +28,9 @@ var camera, scene, raycaster, renderer; var room; - var isMouseDown = false; + var controller, controllerGrip, tempMatrix = new THREE.Matrix4(); var INTERSECTED; - var crosshair; init(); animate(); @@ -45,25 +43,14 @@ scene = new THREE.Scene(); scene.background = new THREE.Color( 0x505050 ); - camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 10 ); + camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10 ); + camera.position.set( 0, 1.6, 3 ); scene.add( camera ); - crosshair = new THREE.Mesh( - new THREE.RingBufferGeometry( 0.02, 0.04, 32 ), - new THREE.MeshBasicMaterial( { - color: 0xffffff, - opacity: 0.5, - transparent: true - } ) - ); - crosshair.position.z = - 2; - camera.add( crosshair ); - room = new THREE.LineSegments( - new BoxLineGeometry( 6, 6, 6, 10, 10, 10 ), + new BoxLineGeometry( 6, 6, 6, 10, 10, 10 ).translate( 0, 3, 0 ), new THREE.LineBasicMaterial( { color: 0x808080 } ) ); - room.position.y = 3; scene.add( room ); scene.add( new THREE.HemisphereLight( 0x606060, 0x404040 ) ); @@ -79,7 +66,7 @@ var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) ); object.position.x = Math.random() * 4 - 2; - object.position.y = Math.random() * 4 - 2; + object.position.y = Math.random() * 4; object.position.z = Math.random() * 4 - 2; object.rotation.x = Math.random() * 2 * Math.PI; @@ -104,55 +91,72 @@ renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.vr.enabled = true; + renderer.outputEncoding = THREE.sRGBEncoding; + renderer.xr.enabled = true; container.appendChild( renderer.domElement ); - renderer.domElement.addEventListener( 'mousedown', onMouseDown, false ); - renderer.domElement.addEventListener( 'mouseup', onMouseUp, false ); - renderer.domElement.addEventListener( 'touchstart', onMouseDown, false ); - renderer.domElement.addEventListener( 'touchend', onMouseUp, false ); + // - window.addEventListener( 'resize', onWindowResize, false ); + function onSelectStart() { - // + this.userData.isSelecting = true; - window.addEventListener( 'vrdisplaypointerrestricted', onPointerRestricted, false ); - window.addEventListener( 'vrdisplaypointerunrestricted', onPointerUnrestricted, false ); + } - document.body.appendChild( WEBVR.createButton( renderer ) ); + function onSelectEnd() { - } + this.userData.isSelecting = false; - function onMouseDown() { + } - isMouseDown = true; + controller = renderer.xr.getController( 0 ); + controller.addEventListener( 'selectstart', onSelectStart ); + controller.addEventListener( 'selectend', onSelectEnd ); + controller.addEventListener( 'connected', function ( event ) { - } + this.add( buildController( event.data ) ); - function onMouseUp() { + } ); + controller.addEventListener( 'disconnected', function () { - isMouseDown = false; + this.remove( this.children[ 0 ] ); - } + } ); + scene.add( controller ); - function onPointerRestricted() { + var controllerModelFactory = new XRControllerModelFactory(); - var pointerLockElement = renderer.domElement; - if ( pointerLockElement && typeof ( pointerLockElement.requestPointerLock ) === 'function' ) { + controllerGrip = renderer.xr.getControllerGrip( 0 ); + controllerGrip.add( controllerModelFactory.createControllerModel( controllerGrip ) ); + scene.add( controllerGrip ); - pointerLockElement.requestPointerLock(); + window.addEventListener( 'resize', onWindowResize, false ); - } + // + + document.body.appendChild( VRButton.createButton( renderer ) ); } - function onPointerUnrestricted() { + function buildController( data ) { + + switch ( data.targetRayMode ) { - var currentPointerLockElement = document.pointerLockElement; - var expectedPointerLockElement = renderer.domElement; - if ( currentPointerLockElement && currentPointerLockElement === expectedPointerLockElement && typeof ( document.exitPointerLock ) === 'function' ) { + case 'tracked-pointer': - document.exitPointerLock(); + var geometry = new THREE.BufferGeometry(); + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 0, 0, - 1 ], 3 ) ); + geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( [ 0.5, 0.5, 0.5, 0, 0, 0 ], 3 ) ); + + var material = new THREE.LineBasicMaterial( { vertexColors: true, blending: THREE.AdditiveBlending } ); + + return new THREE.Line( geometry, material ); + + case 'gaze': + + var geometry = new THREE.RingBufferGeometry( 0.02, 0.04, 32 ).translate( 0, 0, - 1 ); + var material = new THREE.MeshBasicMaterial( { opacity: 0.5, transparent: true } ); + return new THREE.Mesh( geometry, material ); } @@ -179,24 +183,26 @@ var delta = clock.getDelta() * 60; - if ( isMouseDown === true ) { + if ( controller.userData.isSelecting === true ) { var cube = room.children[ 0 ]; room.remove( cube ); - cube.position.set( 0, 0, - 0.75 ); - cube.position.applyQuaternion( camera.quaternion ); + cube.position.copy( controller.position ); cube.userData.velocity.x = ( Math.random() - 0.5 ) * 0.02 * delta; cube.userData.velocity.y = ( Math.random() - 0.5 ) * 0.02 * delta; cube.userData.velocity.z = ( Math.random() * 0.01 - 0.05 ) * delta; - cube.userData.velocity.applyQuaternion( camera.quaternion ); + cube.userData.velocity.applyQuaternion( controller.quaternion ); room.add( cube ); } // find intersections - raycaster.setFromCamera( { x: 0, y: 0 }, camera ); + tempMatrix.identity().extractRotation( controller.matrixWorld ); + + raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld ); + raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix ); var intersects = raycaster.intersectObjects( room.children ); @@ -232,21 +238,21 @@ if ( cube.position.x < - 3 || cube.position.x > 3 ) { - cube.position.x = THREE.Math.clamp( cube.position.x, - 3, 3 ); + cube.position.x = THREE.MathUtils.clamp( cube.position.x, - 3, 3 ); cube.userData.velocity.x = - cube.userData.velocity.x; } - if ( cube.position.y < - 3 || cube.position.y > 3 ) { + if ( cube.position.y < 0 || cube.position.y > 6 ) { - cube.position.y = THREE.Math.clamp( cube.position.y, - 3, 3 ); + cube.position.y = THREE.MathUtils.clamp( cube.position.y, 0, 6 ); cube.userData.velocity.y = - cube.userData.velocity.y; } if ( cube.position.z < - 3 || cube.position.z > 3 ) { - cube.position.z = THREE.Math.clamp( cube.position.z, - 3, 3 ); + cube.position.z = THREE.MathUtils.clamp( cube.position.z, - 3, 3 ); cube.userData.velocity.z = - cube.userData.velocity.z; } diff --git a/examples/webvr_dragging.html b/examples/webxr_vr_dragging.html similarity index 82% rename from examples/webvr_dragging.html rename to examples/webxr_vr_dragging.html index de4c898727c831..542e469424b4d7 100644 --- a/examples/webvr_dragging.html +++ b/examples/webxr_vr_dragging.html @@ -1,17 +1,15 @@ - three.js webvr - dragging + three.js vr - dragging - -
        - three.js webvr - dragging + three.js vr - dragging
        @@ -19,16 +17,19 @@ + + + + diff --git a/examples/webvr_panorama.html b/examples/webxr_vr_panorama.html similarity index 82% rename from examples/webvr_panorama.html rename to examples/webxr_vr_panorama.html index 2d66ddfacbfd73..e3384facbdff5d 100644 --- a/examples/webvr_panorama.html +++ b/examples/webxr_vr_panorama.html @@ -1,12 +1,10 @@ - three.js webvr - panorama + three.js vr - panorama - - @@ -14,7 +12,7 @@ + + + + diff --git a/examples/webvr_rollercoaster.html b/examples/webxr_vr_rollercoaster.html similarity index 86% rename from examples/webvr_rollercoaster.html rename to examples/webxr_vr_rollercoaster.html index 511951472d3cd6..e2bce7e7166ecb 100644 --- a/examples/webvr_rollercoaster.html +++ b/examples/webxr_vr_rollercoaster.html @@ -1,12 +1,10 @@ - three.js webvr - roller coaster + three.js vr - roller coaster - - @@ -16,16 +14,22 @@ import * as THREE from '../build/three.module.js'; - import { RollerCoasterGeometry, RollerCoasterShadowGeometry, RollerCoasterLiftersGeometry, TreesGeometry, SkyGeometry } from './jsm/misc/RollerCoaster.js'; - import { WEBVR } from './jsm/vr/WebVR.js'; + import { + RollerCoasterGeometry, + RollerCoasterShadowGeometry, + RollerCoasterLiftersGeometry, + TreesGeometry, + SkyGeometry + } from './jsm/misc/RollerCoaster.js'; + import { VRButton } from './jsm/webxr/VRButton.js'; var renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.vr.enabled = true; + renderer.xr.enabled = true; document.body.appendChild( renderer.domElement ); - document.body.appendChild( WEBVR.createButton( renderer, { referenceSpaceType: 'local' } ) ); + document.body.appendChild( VRButton.createButton( renderer, { referenceSpaceType: 'local' } ) ); // @@ -39,7 +43,7 @@ var train = new THREE.Object3D(); scene.add( train ); - var camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 500 ); + var camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 500 ); train.add( camera ); // environment @@ -75,7 +79,7 @@ var geometry = new TreesGeometry( mesh ); var material = new THREE.MeshBasicMaterial( { - side: THREE.DoubleSide, vertexColors: THREE.VertexColors + side: THREE.DoubleSide, vertexColors: true } ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); @@ -125,7 +129,7 @@ var geometry = new RollerCoasterGeometry( curve, 1500 ); var material = new THREE.MeshPhongMaterial( { - vertexColors: THREE.VertexColors + vertexColors: true } ); var mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); diff --git a/examples/webvr_sandbox.html b/examples/webxr_vr_sandbox.html similarity index 89% rename from examples/webvr_sandbox.html rename to examples/webxr_vr_sandbox.html index 1ab1bae0605fc2..88cd2c7a81f610 100644 --- a/examples/webvr_sandbox.html +++ b/examples/webxr_vr_sandbox.html @@ -1,12 +1,10 @@ - three.js webvr - sandbox + three.js vr - sandbox - - @@ -18,7 +16,7 @@ import { Lensflare, LensflareElement } from './jsm/objects/Lensflare.js'; import { Reflector } from './jsm/objects/Reflector.js'; - import { WEBVR } from './jsm/vr/WebVR.js'; + import { VRButton } from './jsm/webxr/VRButton.js'; var camera, scene, renderer; @@ -32,12 +30,12 @@ var background = new THREE.CubeTextureLoader() .setPath( 'textures/cube/MilkyWay/' ) .load( [ 'dark-s_px.jpg', 'dark-s_nx.jpg', 'dark-s_py.jpg', 'dark-s_ny.jpg', 'dark-s_pz.jpg', 'dark-s_nz.jpg' ] ); - background.format = THREE.RGBFormat; scene = new THREE.Scene(); scene.background = background; camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10 ); + camera.position.set( 0, 1.6, 2 ); var geometry = new THREE.TorusKnotBufferGeometry( 0.4, 0.15, 150, 20 ); var material = new THREE.MeshStandardMaterial( { roughness: 0.01, metalness: 0.2, envMap: background } ); @@ -121,10 +119,10 @@ renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.shadowMap.enabled = true; - renderer.vr.enabled = true; + renderer.xr.enabled = true; document.body.appendChild( renderer.domElement ); - document.body.appendChild( WEBVR.createButton( renderer ) ); + document.body.appendChild( VRButton.createButton( renderer ) ); // diff --git a/examples/webvr_sculpt.html b/examples/webxr_vr_sculpt.html similarity index 85% rename from examples/webvr_sculpt.html rename to examples/webxr_vr_sculpt.html index fd8070a03bc46e..e88d64e2344f20 100644 --- a/examples/webvr_sculpt.html +++ b/examples/webxr_vr_sculpt.html @@ -1,17 +1,15 @@ - three.js webvr - sculpt + three.js vr - sculpt - -
        - three.js webvr - sculpt + three.js vr - sculpt
        @@ -19,15 +17,15 @@ -