浏览代码

Merge branch 'dev' of https://github.com/mrdoob/three.js into dev

linbingquan 6 年之前
父节点
当前提交
ad1c992748
共有 49 个文件被更改,包括 749 次插入605 次删除
  1. 1 1
      .github/ISSUE_TEMPLATE.md
  2. 1 1
      build/three.js
  3. 146 146
      build/three.min.js
  4. 1 1
      build/three.module.js
  5. 0 143
      dist/Three.d.ts
  6. 15 0
      docs/index.html
  7. 1 0
      examples/js/nodes/Nodes.js
  8. 2 0
      examples/js/nodes/THREE.Nodes.js
  9. 2 2
      examples/js/nodes/accessors/CameraNode.js
  10. 1 1
      examples/js/nodes/accessors/NormalNode.js
  11. 1 1
      examples/js/nodes/accessors/PositionNode.js
  12. 1 1
      examples/js/nodes/core/FunctionNode.js
  13. 12 4
      examples/js/nodes/core/InputNode.js
  14. 28 18
      examples/js/nodes/core/NodeBuilder.js
  15. 23 9
      examples/js/nodes/core/TempNode.js
  16. 51 0
      examples/js/nodes/inputs/BoolNode.js
  17. 1 1
      examples/js/nodes/inputs/ScreenNode.js
  18. 1 0
      examples/js/nodes/materials/PhongNodeMaterial.js
  19. 1 0
      examples/js/nodes/materials/SpriteNodeMaterial.js
  20. 1 0
      examples/js/nodes/materials/StandardNodeMaterial.js
  21. 21 2
      examples/js/nodes/materials/nodes/PhongNode.js
  22. 23 6
      examples/js/nodes/materials/nodes/SpriteNode.js
  23. 22 3
      examples/js/nodes/materials/nodes/StandardNode.js
  24. 35 16
      examples/js/nodes/math/CondNode.js
  25. 3 3
      examples/js/nodes/utils/TimerNode.js
  26. 1 1
      examples/js/nodes/utils/VelocityNode.js
  27. 1 1
      examples/js/postprocessing/SSAOPass.js
  28. 1 1
      examples/js/renderers/SVGRenderer.js
  29. 1 1
      examples/js/shaders/SSAOShader.js
  30. 2 2
      examples/webgl_buffergeometry_instancing_lambert.html
  31. 5 3
      examples/webgl_camera_array.html
  32. 9 5
      examples/webgl_lights_hemisphere.html
  33. 3 3
      examples/webgl_materials_envmaps_exr.html
  34. 6 3
      examples/webgl_materials_envmaps_hdr.html
  35. 264 9
      examples/webgl_materials_nodes.html
  36. 4 11
      examples/webgl_materials_standard.html
  37. 4 7
      examples/webgl_materials_variations_physical.html
  38. 4 6
      examples/webgl_materials_variations_standard.html
  39. 1 1
      package.json
  40. 0 162
      src/Three.ts
  41. 1 1
      src/constants.js
  42. 2 0
      src/objects/Mesh.js
  43. 4 2
      src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl.js
  44. 5 1
      src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js
  45. 13 3
      src/renderers/shaders/ShaderLib/meshlambert_frag.glsl.js
  46. 2 3
      src/renderers/shaders/ShaderLib/meshlambert_vert.glsl.js
  47. 1 1
      src/renderers/webgl/WebGLBackground.js
  48. 19 19
      src/renderers/webgl/WebGLTextures.js
  49. 2 0
      src/scenes/Scene.js

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -19,7 +19,7 @@ Please also include a live example if possible. You can start from these templat
 ##### Three.js version
 ##### Three.js version
 
 
 - [ ] Dev
 - [ ] Dev
-- [ ] r100
+- [ ] r101
 - [ ] ...
 - [ ] ...
 
 
 ##### Browser
 ##### Browser

文件差异内容过多而无法显示
+ 1 - 1
build/three.js


文件差异内容过多而无法显示
+ 146 - 146
build/three.min.js


文件差异内容过多而无法显示
+ 1 - 1
build/three.module.js


+ 0 - 143
dist/Three.d.ts

@@ -1,143 +0,0 @@
-import './polyfills';
-export { WebGLRenderTargetCube } from './renderers/WebGLRenderTargetCube';
-export { WebGLRenderTarget } from './renderers/WebGLRenderTarget';
-export { WebGLRenderer } from './renderers/WebGLRenderer';
-export { ShaderLib } from './renderers/shaders/ShaderLib';
-export { UniformsLib } from './renderers/shaders/UniformsLib';
-export { UniformsUtils } from './renderers/shaders/UniformsUtils';
-export { ShaderChunk } from './renderers/shaders/ShaderChunk';
-export { FogExp2 } from './scenes/FogExp2';
-export { Fog } from './scenes/Fog';
-export { Scene } from './scenes/Scene';
-export { Sprite } from './objects/Sprite';
-export { LOD } from './objects/LOD';
-export { SkinnedMesh } from './objects/SkinnedMesh';
-export { Skeleton } from './objects/Skeleton';
-export { Bone } from './objects/Bone';
-export { Mesh } from './objects/Mesh';
-export { LineSegments } from './objects/LineSegments';
-export { Line } from './objects/Line';
-export { Points } from './objects/Points';
-export { Group } from './objects/Group';
-export { VideoTexture } from './textures/VideoTexture';
-export { DataTexture } from './textures/DataTexture';
-export { CompressedTexture } from './textures/CompressedTexture';
-export { CubeTexture } from './textures/CubeTexture';
-export { CanvasTexture } from './textures/CanvasTexture';
-export { DepthTexture } from './textures/DepthTexture';
-export { Texture } from './textures/Texture';
-export * from './geometries/Geometries';
-export * from './materials/Materials';
-export { CompressedTextureLoader } from './loaders/CompressedTextureLoader';
-export { DataTextureLoader } from './loaders/DataTextureLoader';
-export { CubeTextureLoader } from './loaders/CubeTextureLoader';
-export { TextureLoader } from './loaders/TextureLoader';
-export { ObjectLoader } from './loaders/ObjectLoader';
-export { MaterialLoader } from './loaders/MaterialLoader';
-export { BufferGeometryLoader } from './loaders/BufferGeometryLoader';
-export { LoadingManager, DefaultLoadingManager, } from './loaders/LoadingManager';
-export { ImageLoader } from './loaders/ImageLoader';
-export { FontLoader } from './loaders/FontLoader';
-export { FileLoader } from './loaders/FileLoader';
-export { Loader } from './loaders/Loader';
-export { LoaderUtils } from './loaders/LoaderUtils';
-export { Cache } from './loaders/Cache';
-export { AudioLoader } from './loaders/AudioLoader';
-export { SpotLightShadow } from './lights/SpotLightShadow';
-export { SpotLight } from './lights/SpotLight';
-export { PointLight } from './lights/PointLight';
-export { HemisphereLight } from './lights/HemisphereLight';
-export { DirectionalLightShadow } from './lights/DirectionalLightShadow';
-export { DirectionalLight } from './lights/DirectionalLight';
-export { AmbientLight } from './lights/AmbientLight';
-export { LightShadow } from './lights/LightShadow';
-export { Light } from './lights/Light';
-export { StereoCamera } from './cameras/StereoCamera';
-export { PerspectiveCamera } from './cameras/PerspectiveCamera';
-export { OrthographicCamera } from './cameras/OrthographicCamera';
-export { CubeCamera } from './cameras/CubeCamera';
-export { ArrayCamera } from './cameras/ArrayCamera';
-export { Camera } from './cameras/Camera';
-export { AudioListener } from './audio/AudioListener';
-export { PositionalAudio } from './audio/PositionalAudio';
-export { AudioContext } from './audio/AudioContext';
-export { AudioAnalyser } from './audio/AudioAnalyser';
-export { Audio } from './audio/Audio';
-export { VectorKeyframeTrack } from './animation/tracks/VectorKeyframeTrack';
-export { StringKeyframeTrack } from './animation/tracks/StringKeyframeTrack';
-export { QuaternionKeyframeTrack, } from './animation/tracks/QuaternionKeyframeTrack';
-export { NumberKeyframeTrack } from './animation/tracks/NumberKeyframeTrack';
-export { ColorKeyframeTrack } from './animation/tracks/ColorKeyframeTrack';
-export { BooleanKeyframeTrack } from './animation/tracks/BooleanKeyframeTrack';
-export { PropertyMixer } from './animation/PropertyMixer';
-export { PropertyBinding } from './animation/PropertyBinding';
-export { KeyframeTrack } from './animation/KeyframeTrack';
-export { AnimationUtils } from './animation/AnimationUtils';
-export { AnimationObjectGroup } from './animation/AnimationObjectGroup';
-export { AnimationMixer } from './animation/AnimationMixer';
-export { AnimationClip } from './animation/AnimationClip';
-export { Uniform } from './core/Uniform';
-export { InstancedBufferGeometry } from './core/InstancedBufferGeometry';
-export { BufferGeometry } from './core/BufferGeometry';
-export { Geometry } from './core/Geometry';
-export { InterleavedBufferAttribute } from './core/InterleavedBufferAttribute';
-export { InstancedInterleavedBuffer } from './core/InstancedInterleavedBuffer';
-export { InterleavedBuffer } from './core/InterleavedBuffer';
-export { InstancedBufferAttribute } from './core/InstancedBufferAttribute';
-export * from './core/BufferAttribute';
-export { Face3 } from './core/Face3';
-export { Object3D } from './core/Object3D';
-export { Raycaster } from './core/Raycaster';
-export { Layers } from './core/Layers';
-export { EventDispatcher } from './core/EventDispatcher';
-export { Clock } from './core/Clock';
-export { QuaternionLinearInterpolant, } from './math/interpolants/QuaternionLinearInterpolant';
-export { LinearInterpolant } from './math/interpolants/LinearInterpolant';
-export { DiscreteInterpolant } from './math/interpolants/DiscreteInterpolant';
-export { CubicInterpolant } from './math/interpolants/CubicInterpolant';
-export { Interpolant } from './math/Interpolant';
-export { Triangle } from './math/Triangle';
-export { _Math as Math } from './math/Math';
-export { Spherical } from './math/Spherical';
-export { Cylindrical } from './math/Cylindrical';
-export { Plane } from './math/Plane';
-export { Frustum } from './math/Frustum';
-export { Sphere } from './math/Sphere';
-export { Ray } from './math/Ray';
-export { Matrix4 } from './math/Matrix4';
-export { Matrix3 } from './math/Matrix3';
-export { Box3 } from './math/Box3';
-export { Box2 } from './math/Box2';
-export { Line3 } from './math/Line3';
-export { Euler } from './math/Euler';
-export { Vector4 } from './math/Vector4';
-export { Vector3 } from './math/Vector3';
-export { Vector2 } from './math/Vector2';
-export { Quaternion } from './math/Quaternion';
-export { Color } from './math/Color';
-export { ImmediateRenderObject } from './extras/objects/ImmediateRenderObject';
-export { VertexNormalsHelper } from './helpers/VertexNormalsHelper';
-export { SpotLightHelper } from './helpers/SpotLightHelper';
-export { SkeletonHelper } from './helpers/SkeletonHelper';
-export { PointLightHelper } from './helpers/PointLightHelper';
-export { HemisphereLightHelper } from './helpers/HemisphereLightHelper';
-export { GridHelper } from './helpers/GridHelper';
-export { FaceNormalsHelper } from './helpers/FaceNormalsHelper';
-export { DirectionalLightHelper } from './helpers/DirectionalLightHelper';
-export { CameraHelper } from './helpers/CameraHelper';
-export { BoxHelper } from './helpers/BoxHelper';
-export { PlaneHelper } from './helpers/PlaneHelper';
-export { ArrowHelper } from './helpers/ArrowHelper';
-export { AxesHelper } from './helpers/AxesHelper';
-export * from './extras/curves/Curves';
-export { Shape } from './extras/core/Shape';
-export { Path } from './extras/core/Path';
-export { ShapePath } from './extras/core/ShapePath';
-export { Font } from './extras/core/Font';
-export { CurvePath } from './extras/core/CurvePath';
-export { Curve } from './extras/core/Curve';
-export { ImageUtils } from './extras/ImageUtils';
-export { ShapeUtils } from './extras/ShapeUtils';
-export * from './constants';
-export * from './Three.Legacy';
-//# sourceMappingURL=Three.d.ts.map

+ 15 - 0
docs/index.html

@@ -69,6 +69,8 @@
 
 
 				language = value;
 				language = value;
 				createNavigation();
 				createNavigation();
+				updateFilter();
+				autoChangeUrlLanguage( language );
 
 
 			}
 			}
 
 
@@ -226,6 +228,19 @@
 
 
 			}
 			}
 
 
+			// Auto change language url. If a reader open a document in English, when he click "zh", the document he read will auto change into Chinese version
+
+			function autoChangeUrlLanguage( language ) {
+
+				var hash = location.hash;
+				if ( hash === '' ) return;
+				var docType = hash.substr( 0, hash.indexOf( '/' ) + 1 );
+				var docLink = hash.substr( hash.indexOf( '/' ) + 1 );
+				docLink = docLink.substr( docLink.indexOf( '/' ) );
+				location.href = docType + language + docLink;
+
+			}
+
 
 
 			// Filtering
 			// Filtering
 
 

+ 1 - 0
examples/js/nodes/Nodes.js

@@ -20,6 +20,7 @@ export { NodeBuilder } from './core/NodeBuilder.js';
 
 
 // inputs
 // inputs
 
 
+export { BoolNode } from './inputs/BoolNode.js';
 export { IntNode } from './inputs/IntNode.js';
 export { IntNode } from './inputs/IntNode.js';
 export { FloatNode } from './inputs/FloatNode.js';
 export { FloatNode } from './inputs/FloatNode.js';
 export { Vector2Node } from './inputs/Vector2Node.js';
 export { Vector2Node } from './inputs/Vector2Node.js';

+ 2 - 0
examples/js/nodes/THREE.Nodes.js

@@ -20,6 +20,7 @@ import {
 
 
 	// inputs
 	// inputs
 
 
+	BoolNode,
 	IntNode,
 	IntNode,
 	FloatNode,
 	FloatNode,
 	Vector2Node,
 	Vector2Node,
@@ -132,6 +133,7 @@ THREE.NodeBuilder = NodeBuilder;
 
 
 // inputs
 // inputs
 
 
+THREE.BoolNode = BoolNode;
 THREE.IntNode = IntNode;
 THREE.IntNode = IntNode;
 THREE.FloatNode = FloatNode;
 THREE.FloatNode = FloatNode;
 THREE.Vector2Node = Vector2Node;
 THREE.Vector2Node = Vector2Node;

+ 2 - 2
examples/js/nodes/accessors/CameraNode.js

@@ -101,7 +101,7 @@ CameraNode.prototype.getType = function ( builder ) {
 
 
 };
 };
 
 
-CameraNode.prototype.isUnique = function ( builder ) {
+CameraNode.prototype.getUnique = function ( builder ) {
 
 
 	switch ( this.scope ) {
 	switch ( this.scope ) {
 
 
@@ -116,7 +116,7 @@ CameraNode.prototype.isUnique = function ( builder ) {
 
 
 };
 };
 
 
-CameraNode.prototype.isShared = function ( builder ) {
+CameraNode.prototype.getShared = function ( builder ) {
 
 
 	switch ( this.scope ) {
 	switch ( this.scope ) {
 
 

+ 1 - 1
examples/js/nodes/accessors/NormalNode.js

@@ -21,7 +21,7 @@ NormalNode.prototype = Object.create( TempNode.prototype );
 NormalNode.prototype.constructor = NormalNode;
 NormalNode.prototype.constructor = NormalNode;
 NormalNode.prototype.nodeType = "Normal";
 NormalNode.prototype.nodeType = "Normal";
 
 
-NormalNode.prototype.isShared = function ( builder ) {
+NormalNode.prototype.getShared = function ( builder ) {
 
 
 	switch ( this.scope ) {
 	switch ( this.scope ) {
 
 

+ 1 - 1
examples/js/nodes/accessors/PositionNode.js

@@ -36,7 +36,7 @@ PositionNode.prototype.getType = function ( ) {
 
 
 };
 };
 
 
-PositionNode.prototype.isShared = function ( builder ) {
+PositionNode.prototype.getShared = function ( builder ) {
 
 
 	switch ( this.scope ) {
 	switch ( this.scope ) {
 
 

+ 1 - 1
examples/js/nodes/core/FunctionNode.js

@@ -25,7 +25,7 @@ FunctionNode.prototype.nodeType = "Function";
 
 
 FunctionNode.prototype.useKeywords = true;
 FunctionNode.prototype.useKeywords = true;
 
 
-FunctionNode.prototype.isShared = function ( builder, output ) {
+FunctionNode.prototype.getShared = function ( builder, output ) {
 
 
 	return ! this.isMethod;
 	return ! this.isMethod;
 
 

+ 12 - 4
examples/js/nodes/core/InputNode.js

@@ -18,7 +18,15 @@ function InputNode( type, params ) {
 InputNode.prototype = Object.create( TempNode.prototype );
 InputNode.prototype = Object.create( TempNode.prototype );
 InputNode.prototype.constructor = InputNode;
 InputNode.prototype.constructor = InputNode;
 
 
-InputNode.prototype.isReadonly = function ( builder ) {
+InputNode.prototype.setReadonly = function ( value ) {
+
+	this.readonly = value;
+
+	return this;
+
+};
+
+InputNode.prototype.getReadonly = function ( builder ) {
 
 
 	return this.readonly;
 	return this.readonly;
 
 
@@ -48,7 +56,7 @@ InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needs
 	type = type || this.getType( builder );
 	type = type || this.getType( builder );
 
 
 	var data = builder.getNodeData( uuid ),
 	var data = builder.getNodeData( uuid ),
-		readonly = this.isReadonly( builder ) && this.generateReadonly !== undefined;
+		readonly = this.getReadonly( builder ) && this.generateReadonly !== undefined;
 
 
 	if ( readonly ) {
 	if ( readonly ) {
 
 
@@ -60,7 +68,7 @@ InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needs
 
 
 			if ( ! data.vertex ) {
 			if ( ! data.vertex ) {
 
 
-				data.vertex = builder.createVertexUniform( type, this, ns, needsUpdate );
+				data.vertex = builder.createVertexUniform( type, this, ns, needsUpdate, this.getLabel() );
 
 
 			}
 			}
 
 
@@ -70,7 +78,7 @@ InputNode.prototype.generate = function ( builder, output, uuid, type, ns, needs
 
 
 			if ( ! data.fragment ) {
 			if ( ! data.fragment ) {
 
 
-				data.fragment = builder.createFragmentUniform( type, this, ns, needsUpdate );
+				data.fragment = builder.createFragmentUniform( type, this, ns, needsUpdate, this.getLabel() );
 
 
 			}
 			}
 
 

+ 28 - 18
examples/js/nodes/core/NodeBuilder.js

@@ -22,7 +22,8 @@ var elements = NodeUtils.elements,
 		vec3: 'v3',
 		vec3: 'v3',
 		vec4: 'v4',
 		vec4: 'v4',
 		mat4: 'v4',
 		mat4: 'v4',
-		int: 'i'
+		int: 'i',
+		bool: 'b'
 	},
 	},
 	convertTypeToFormat = {
 	convertTypeToFormat = {
 		t: 'sampler2D',
 		t: 'sampler2D',
@@ -442,9 +443,7 @@ NodeBuilder.prototype = {
 
 
 	},
 	},
 
 
-	getVar: function ( uuid, type, ns, shader ) {
-
-		shader = shader || 'varying';
+	getVar: function ( uuid, type, ns, shader = 'varying', prefix = 'V', label = '' ) {
 
 
 		var vars = this.getVars( shader ),
 		var vars = this.getVars( shader ),
 			data = vars[ uuid ];
 			data = vars[ uuid ];
@@ -452,7 +451,7 @@ NodeBuilder.prototype = {
 		if ( ! data ) {
 		if ( ! data ) {
 
 
 			var index = vars.length,
 			var index = vars.length,
-				name = ns ? ns : 'nVv' + index;
+				name = ns ? ns : 'node' + prefix + index + ( label ? '_' + label : '' );
 
 
 			data = { name: name, type: type };
 			data = { name: name, type: type };
 
 
@@ -465,9 +464,9 @@ NodeBuilder.prototype = {
 
 
 	},
 	},
 
 
-	getTempVar: function ( uuid, type, ns ) {
+	getTempVar: function ( uuid, type, ns, label ) {
 
 
-		return this.getVar( uuid, type, ns, this.shader );
+		return this.getVar( uuid, type, ns, this.shader, 'T', label );
 
 
 	},
 	},
 
 
@@ -550,14 +549,14 @@ NodeBuilder.prototype = {
 
 
 	},
 	},
 
 
-	createUniform: function ( shader, type, node, ns, needsUpdate ) {
+	createUniform: function ( shader, type, node, ns, needsUpdate, label ) {
 
 
 		var uniforms = this.inputs.uniforms,
 		var uniforms = this.inputs.uniforms,
 			index = uniforms.list.length;
 			index = uniforms.list.length;
 
 
 		var uniform = new NodeUniform( {
 		var uniform = new NodeUniform( {
 			type: type,
 			type: type,
-			name: ns ? ns : 'nVu' + index,
+			name: ns ? ns : 'nodeU' + index + ( label ? '_' + label : '' ),
 			node: node,
 			node: node,
 			needsUpdate: needsUpdate
 			needsUpdate: needsUpdate
 		} );
 		} );
@@ -573,15 +572,15 @@ NodeBuilder.prototype = {
 
 
 	},
 	},
 
 
-	createVertexUniform: function ( type, node, ns, needsUpdate ) {
+	createVertexUniform: function ( type, node, ns, needsUpdate, label ) {
 
 
-		return this.createUniform( 'vertex', type, node, ns, needsUpdate );
+		return this.createUniform( 'vertex', type, node, ns, needsUpdate, label );
 
 
 	},
 	},
 
 
-	createFragmentUniform: function ( type, node, ns, needsUpdate ) {
+	createFragmentUniform: function ( type, node, ns, needsUpdate, label ) {
 
 
-		return this.createUniform( 'fragment', type, node, ns, needsUpdate );
+		return this.createUniform( 'fragment', type, node, ns, needsUpdate, label );
 
 
 	},
 	},
 
 
@@ -821,28 +820,39 @@ NodeBuilder.prototype = {
 			case 'f <- v2' : return code + '.x';
 			case 'f <- v2' : return code + '.x';
 			case 'f <- v3' : return code + '.x';
 			case 'f <- v3' : return code + '.x';
 			case 'f <- v4' : return code + '.x';
 			case 'f <- v4' : return code + '.x';
-			case 'f <- i' : return 'float( ' + code + ' )';
+			case 'f <- i' :
+			case 'f <- b' :	return 'float( ' + code + ' )';
 
 
 			case 'v2 <- f' : return 'vec2( ' + code + ' )';
 			case 'v2 <- f' : return 'vec2( ' + code + ' )';
 			case 'v2 <- v3': return code + '.xy';
 			case 'v2 <- v3': return code + '.xy';
 			case 'v2 <- v4': return code + '.xy';
 			case 'v2 <- v4': return code + '.xy';
-			case 'v2 <- i' : return 'vec2( float( ' + code + ' ) )';
+			case 'v2 <- i' :
+			case 'v2 <- b' : return 'vec2( float( ' + code + ' ) )';
 
 
 			case 'v3 <- f' : return 'vec3( ' + code + ' )';
 			case 'v3 <- f' : return 'vec3( ' + code + ' )';
 			case 'v3 <- v2': return 'vec3( ' + code + ', 0.0 )';
 			case 'v3 <- v2': return 'vec3( ' + code + ', 0.0 )';
 			case 'v3 <- v4': return code + '.xyz';
 			case 'v3 <- v4': return code + '.xyz';
-			case 'v3 <- i' : return 'vec2( float( ' + code + ' ) )';
+			case 'v3 <- i' :
+			case 'v3 <- b' : return 'vec2( float( ' + code + ' ) )';
 
 
 			case 'v4 <- f' : return 'vec4( ' + code + ' )';
 			case 'v4 <- f' : return 'vec4( ' + code + ' )';
 			case 'v4 <- v2': return 'vec4( ' + code + ', 0.0, 1.0 )';
 			case 'v4 <- v2': return 'vec4( ' + code + ', 0.0, 1.0 )';
 			case 'v4 <- v3': return 'vec4( ' + code + ', 1.0 )';
 			case 'v4 <- v3': return 'vec4( ' + code + ', 1.0 )';
-			case 'v4 <- i' : return 'vec4( float( ' + code + ' ) )';
+			case 'v4 <- i' :
+			case 'v4 <- b' : return 'vec4( float( ' + code + ' ) )';
 
 
-			case 'i <- f' : return 'int( ' + code + ' )';
+			case 'i <- f' :
+			case 'i <- b' : return 'int( ' + code + ' )';
 			case 'i <- v2' : return 'int( ' + code + '.x )';
 			case 'i <- v2' : return 'int( ' + code + '.x )';
 			case 'i <- v3' : return 'int( ' + code + '.x )';
 			case 'i <- v3' : return 'int( ' + code + '.x )';
 			case 'i <- v4' : return 'int( ' + code + '.x )';
 			case 'i <- v4' : return 'int( ' + code + '.x )';
 
 
+			case 'b <- f' : return '( ' + code + ' != 0.0 )';
+			case 'b <- v2' : return '( ' + code + ' != vec2( 0.0 ) )';
+			case 'b <- v3' : return '( ' + code + ' != vec3( 0.0 ) )';
+			case 'b <- v4' : return '( ' + code + ' != vec4( 0.0 ) )';
+			case 'b <- i' : return '( ' + code + ' != 0 )';
+
 		}
 		}
 
 
 		return code;
 		return code;

+ 23 - 9
examples/js/nodes/core/TempNode.js

@@ -23,9 +23,9 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 
 	output = output || this.getType( builder );
 	output = output || this.getType( builder );
 
 
-	if ( this.isShared( builder, output ) ) {
+	if ( this.getShared( builder, output ) ) {
 
 
-		var isUnique = this.isUnique( builder, output );
+		var isUnique = this.getUnique( builder, output );
 
 
 		if ( isUnique && this.constructor.uuid === undefined ) {
 		if ( isUnique && this.constructor.uuid === undefined ) {
 
 
@@ -40,7 +40,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 
 		if ( builder.parsing ) {
 		if ( builder.parsing ) {
 
 
-			if ( ( data.deps || 0 ) > 0 ) {
+			if ( ( data.deps || 0 ) > 0 || this.getLabel() ) {
 
 
 				this.appendDepsNode( builder, data, output );
 				this.appendDepsNode( builder, data, output );
 
 
@@ -56,7 +56,7 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 
 			return data.name;
 			return data.name;
 
 
-		} else if ( ! this.isShared( builder, type ) || ( ! builder.optimize || data.deps == 1 ) ) {
+		} else if ( ! this.getLabel() && ( ! this.getShared( builder, type ) || ( ! builder.optimize || data.deps === 1 ) ) ) {
 
 
 			return Node.prototype.build.call( this, builder, output, uuid );
 			return Node.prototype.build.call( this, builder, output, uuid );
 
 
@@ -88,23 +88,37 @@ TempNode.prototype.build = function ( builder, output, uuid, ns ) {
 
 
 };
 };
 
 
-TempNode.prototype.isShared = function ( builder, output ) {
+TempNode.prototype.getShared = function ( builder, output ) {
 
 
 	return output !== 'sampler2D' && output !== 'samplerCube' && this.shared;
 	return output !== 'sampler2D' && output !== 'samplerCube' && this.shared;
 
 
 };
 };
 
 
-TempNode.prototype.isUnique = function ( builder, output ) {
+TempNode.prototype.getUnique = function ( builder, output ) {
 
 
 	return this.unique;
 	return this.unique;
 
 
 };
 };
 
 
+TempNode.prototype.setLabel = function ( name ) {
+
+	this.label = name;
+
+	return this;
+
+};
+
+TempNode.prototype.getLabel = function ( builder ) {
+
+	return this.label;
+
+};
+
 TempNode.prototype.getUuid = function ( unique ) {
 TempNode.prototype.getUuid = function ( unique ) {
 
 
 	var uuid = unique || unique == undefined ? this.constructor.uuid || this.uuid : this.uuid;
 	var uuid = unique || unique == undefined ? this.constructor.uuid || this.uuid : this.uuid;
 
 
-	if ( typeof this.scope == "string" ) uuid = this.scope + '-' + uuid;
+	if ( typeof this.scope === "string" ) uuid = this.scope + '-' + uuid;
 
 
 	return uuid;
 	return uuid;
 
 
@@ -122,11 +136,11 @@ TempNode.prototype.getTemp = function ( builder, uuid ) {
 
 
 TempNode.prototype.generate = function ( builder, output, uuid, type, ns ) {
 TempNode.prototype.generate = function ( builder, output, uuid, type, ns ) {
 
 
-	if ( ! this.isShared( builder, output ) ) console.error( "THREE.TempNode is not shared!" );
+	if ( ! this.getShared( builder, output ) ) console.error( "THREE.TempNode is not shared!" );
 
 
 	uuid = uuid || this.uuid;
 	uuid = uuid || this.uuid;
 
 
-	return builder.getTempVar( uuid, type || this.getType( builder ), ns ).name;
+	return builder.getTempVar( uuid, type || this.getType( builder ), ns, this.getLabel() ).name;
 
 
 };
 };
 
 

+ 51 - 0
examples/js/nodes/inputs/BoolNode.js

@@ -0,0 +1,51 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { InputNode } from '../core/InputNode.js';
+
+function BoolNode( value ) {
+
+	InputNode.call( this, 'b' );
+
+	this.value = Boolean( value );
+
+}
+
+BoolNode.prototype = Object.create( InputNode.prototype );
+BoolNode.prototype.constructor = BoolNode;
+BoolNode.prototype.nodeType = "Bool";
+
+BoolNode.prototype.generateReadonly = function ( builder, output, uuid, type, ns, needsUpdate ) {
+
+	return builder.format( this.value, type, output );
+
+};
+
+BoolNode.prototype.copy = function ( source ) {
+
+	InputNode.prototype.copy.call( this, source );
+
+	this.value = source.value;
+
+};
+
+BoolNode.prototype.toJSON = function ( meta ) {
+
+	var data = this.getJSONNode( meta );
+
+	if ( ! data ) {
+
+		data = this.createJSONNode( meta );
+
+		data.value = this.value;
+
+		if ( this.readonly === true ) data.readonly = true;
+
+	}
+
+	return data;
+
+};
+
+export { BoolNode };

+ 1 - 1
examples/js/nodes/inputs/ScreenNode.js

@@ -15,7 +15,7 @@ ScreenNode.prototype = Object.create( TextureNode.prototype );
 ScreenNode.prototype.constructor = ScreenNode;
 ScreenNode.prototype.constructor = ScreenNode;
 ScreenNode.prototype.nodeType = "Screen";
 ScreenNode.prototype.nodeType = "Screen";
 
 
-ScreenNode.prototype.isUnique = function () {
+ScreenNode.prototype.getUnique = function () {
 
 
 	return true;
 	return true;
 
 

+ 1 - 0
examples/js/nodes/materials/PhongNodeMaterial.js

@@ -32,6 +32,7 @@ NodeUtils.addShortcuts( PhongNodeMaterial.prototype, 'fragment', [
 	'ao',
 	'ao',
 	'environment',
 	'environment',
 	'environmentAlpha',
 	'environmentAlpha',
+	'mask',
 	'position'
 	'position'
 ] );
 ] );
 
 

+ 1 - 0
examples/js/nodes/materials/SpriteNodeMaterial.js

@@ -22,6 +22,7 @@ SpriteNodeMaterial.prototype.constructor = SpriteNodeMaterial;
 NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [
 NodeUtils.addShortcuts( SpriteNodeMaterial.prototype, 'fragment', [
 	'color',
 	'color',
 	'alpha',
 	'alpha',
+	'mask',
 	'position',
 	'position',
 	'spherical'
 	'spherical'
 ] );
 ] );

+ 1 - 0
examples/js/nodes/materials/StandardNodeMaterial.js

@@ -34,6 +34,7 @@ NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [
 	'shadow',
 	'shadow',
 	'ao',
 	'ao',
 	'environment',
 	'environment',
+	'mask',
 	'position'
 	'position'
 ] );
 ] );
 
 

+ 21 - 2
examples/js/nodes/materials/nodes/PhongNode.js

@@ -103,6 +103,8 @@ PhongNode.prototype.build = function ( builder ) {
 
 
 		// parse all nodes to reuse generate codes
 		// parse all nodes to reuse generate codes
 
 
+		if ( this.mask ) this.mask.parse( builder );
+
 		this.color.parse( builder, { slot: 'color' } );
 		this.color.parse( builder, { slot: 'color' } );
 		this.specular.parse( builder );
 		this.specular.parse( builder );
 		this.shininess.parse( builder );
 		this.shininess.parse( builder );
@@ -123,6 +125,8 @@ PhongNode.prototype.build = function ( builder ) {
 
 
 		// build code
 		// build code
 
 
+		var mask = this.mask ? this.mask.buildCode( builder, 'b' ) : undefined;
+
 		var color = this.color.buildCode( builder, 'c', { slot: 'color' } );
 		var color = this.color.buildCode( builder, 'c', { slot: 'color' } );
 		var specular = this.specular.buildCode( builder, 'c' );
 		var specular = this.specular.buildCode( builder, 'c' );
 		var shininess = this.shininess.buildCode( builder, 'f' );
 		var shininess = this.shininess.buildCode( builder, 'f' );
@@ -157,8 +161,19 @@ PhongNode.prototype.build = function ( builder ) {
 			"#include <normal_fragment_begin>",
 			"#include <normal_fragment_begin>",
 
 
 			// prevent undeclared material
 			// prevent undeclared material
-			"	BlinnPhongMaterial material;",
+			"	BlinnPhongMaterial material;"
+		];
+
+		if ( mask ) {
+
+			output.push(
+				mask.code,
+				'if ( ! ' + mask.result + ' ) discard;'
+			);
 
 
+		}
+
+		output.push(
 			color.code,
 			color.code,
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
@@ -172,7 +187,7 @@ PhongNode.prototype.build = function ( builder ) {
 			"	float shininess = max( 0.0001, " + shininess.result + " );",
 			"	float shininess = max( 0.0001, " + shininess.result + " );",
 
 
 			"	float specularStrength = 1.0;" // Ignored in MaterialNode ( replace to specular )
 			"	float specularStrength = 1.0;" // Ignored in MaterialNode ( replace to specular )
-		];
+		);
 
 
 		if ( alpha ) {
 		if ( alpha ) {
 
 
@@ -335,6 +350,8 @@ PhongNode.prototype.copy = function ( source ) {
 	this.specular = source.specular;
 	this.specular = source.specular;
 	this.shininess = source.shininess;
 	this.shininess = source.shininess;
 
 
+	if ( source.mask ) this.mask = source.mask;
+
 	if ( source.alpha ) this.alpha = source.alpha;
 	if ( source.alpha ) this.alpha = source.alpha;
 
 
 	if ( source.normal ) this.normal = source.normal;
 	if ( source.normal ) this.normal = source.normal;
@@ -370,6 +387,8 @@ PhongNode.prototype.toJSON = function ( meta ) {
 		data.specular = this.specular.toJSON( meta ).uuid;
 		data.specular = this.specular.toJSON( meta ).uuid;
 		data.shininess = this.shininess.toJSON( meta ).uuid;
 		data.shininess = this.shininess.toJSON( meta ).uuid;
 
 
+		if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
+
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 
 
 		if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;
 		if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;

+ 23 - 6
examples/js/nodes/materials/nodes/SpriteNode.js

@@ -123,18 +123,31 @@ SpriteNode.prototype.build = function ( builder ) {
 
 
 		// parse all nodes to reuse generate codes
 		// parse all nodes to reuse generate codes
 
 
+		if ( this.mask ) this.mask.parse( builder );
+
 		if ( this.alpha ) this.alpha.parse( builder );
 		if ( this.alpha ) this.alpha.parse( builder );
 
 
 		this.color.parse( builder, { slot: 'color' } );
 		this.color.parse( builder, { slot: 'color' } );
 
 
 		// build code
 		// build code
 
 
-		var alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined,
-			color = this.color.buildCode( builder, 'c', { slot: 'color' } );
+		var mask = this.mask ? this.mask.buildCode( builder, 'b' ) : undefined,
+			alpha = this.alpha ? this.alpha.buildCode( builder, 'f' ) : undefined,
+			color = this.color.buildCode( builder, 'c', { slot: 'color' } ),
+			output = [];
+
+		if ( mask ) {
+
+			output.push(
+				mask.code,
+				'if ( ! ' + mask.result + ' ) discard;'
+			);
+
+		}
 
 
 		if ( alpha ) {
 		if ( alpha ) {
 
 
-			output = [
+			output.push(
 				alpha.code,
 				alpha.code,
 				'#ifdef ALPHATEST',
 				'#ifdef ALPHATEST',
 
 
@@ -143,14 +156,14 @@ SpriteNode.prototype.build = function ( builder ) {
 				'#endif',
 				'#endif',
 				color.code,
 				color.code,
 				"gl_FragColor = vec4( " + color.result + ", " + alpha.result + " );"
 				"gl_FragColor = vec4( " + color.result + ", " + alpha.result + " );"
-			];
+			);
 
 
 		} else {
 		} else {
 
 
-			output = [
+			output.push(
 				color.code,
 				color.code,
 				"gl_FragColor = vec4( " + color.result + ", 1.0 );"
 				"gl_FragColor = vec4( " + color.result + ", 1.0 );"
-			];
+			);
 
 
 		}
 		}
 
 
@@ -180,6 +193,8 @@ SpriteNode.prototype.copy = function ( source ) {
 
 
 	if ( source.spherical !== undefined ) this.spherical = source.spherical;
 	if ( source.spherical !== undefined ) this.spherical = source.spherical;
 
 
+	if ( source.mask ) this.mask = source.mask;
+
 	if ( source.alpha ) this.alpha = source.alpha;
 	if ( source.alpha ) this.alpha = source.alpha;
 
 
 };
 };
@@ -202,6 +217,8 @@ SpriteNode.prototype.toJSON = function ( meta ) {
 
 
 		if ( this.spherical === false ) data.spherical = false;
 		if ( this.spherical === false ) data.spherical = false;
 
 
+		if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
+
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 
 
 	}
 	}

+ 22 - 3
examples/js/nodes/materials/nodes/StandardNode.js

@@ -117,6 +117,8 @@ StandardNode.prototype.build = function ( builder ) {
 
 
 		// parse all nodes to reuse generate codes
 		// parse all nodes to reuse generate codes
 
 
+		if ( this.mask ) this.mask.parse( builder );
+
 		this.color.parse( builder, { slot: 'color', context: contextGammaOnly } );
 		this.color.parse( builder, { slot: 'color', context: contextGammaOnly } );
 		this.roughness.parse( builder );
 		this.roughness.parse( builder );
 		this.metalness.parse( builder );
 		this.metalness.parse( builder );
@@ -141,6 +143,8 @@ StandardNode.prototype.build = function ( builder ) {
 
 
 		// build code
 		// build code
 
 
+		var mask = this.mask ? this.mask.buildCode( builder, 'b' ) : undefined;
+
 		var color = this.color.buildCode( builder, 'c', { slot: 'color', context: contextGammaOnly } );
 		var color = this.color.buildCode( builder, 'c', { slot: 'color', context: contextGammaOnly } );
 		var roughness = this.roughness.buildCode( builder, 'f' );
 		var roughness = this.roughness.buildCode( builder, 'f' );
 		var metalness = this.metalness.buildCode( builder, 'f' );
 		var metalness = this.metalness.buildCode( builder, 'f' );
@@ -194,8 +198,19 @@ StandardNode.prototype.build = function ( builder ) {
 
 
 			// add before: prevent undeclared material
 			// add before: prevent undeclared material
 			"	PhysicalMaterial material;",
 			"	PhysicalMaterial material;",
-			"	material.diffuseColor = vec3( 1.0 );",
+			"	material.diffuseColor = vec3( 1.0 );"
+		];
+
+		if ( mask ) {
+
+			output.push(
+				mask.code,
+				'if ( ! ' + mask.result + ' ) discard;'
+			);
 
 
+		}
+
+		output.push(
 			color.code,
 			color.code,
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	vec3 diffuseColor = " + color.result + ";",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
 			"	ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
@@ -207,7 +222,7 @@ StandardNode.prototype.build = function ( builder ) {
 
 
 			metalness.code,
 			metalness.code,
 			"	float metalnessFactor = " + metalness.result + ";"
 			"	float metalnessFactor = " + metalness.result + ";"
-		];
+		);
 
 
 		if ( alpha ) {
 		if ( alpha ) {
 
 
@@ -215,7 +230,7 @@ StandardNode.prototype.build = function ( builder ) {
 				alpha.code,
 				alpha.code,
 				'#ifdef ALPHATEST',
 				'#ifdef ALPHATEST',
 
 
-				'if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
+				'	if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
 
 
 				'#endif'
 				'#endif'
 			);
 			);
@@ -403,6 +418,8 @@ StandardNode.prototype.copy = function ( source ) {
 	this.roughness = source.roughness;
 	this.roughness = source.roughness;
 	this.metalness = source.metalness;
 	this.metalness = source.metalness;
 
 
+	if ( source.mask ) this.mask = source.mask;
+
 	if ( source.alpha ) this.alpha = source.alpha;
 	if ( source.alpha ) this.alpha = source.alpha;
 
 
 	if ( source.normal ) this.normal = source.normal;
 	if ( source.normal ) this.normal = source.normal;
@@ -442,6 +459,8 @@ StandardNode.prototype.toJSON = function ( meta ) {
 		data.roughness = this.roughness.toJSON( meta ).uuid;
 		data.roughness = this.roughness.toJSON( meta ).uuid;
 		data.metalness = this.metalness.toJSON( meta ).uuid;
 		data.metalness = this.metalness.toJSON( meta ).uuid;
 
 
+		if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
+
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 		if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
 
 
 		if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;
 		if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;

+ 35 - 16
examples/js/nodes/math/CondNode.js

@@ -4,18 +4,18 @@
 
 
 import { TempNode } from '../core/TempNode.js';
 import { TempNode } from '../core/TempNode.js';
 
 
-function CondNode( a, b, ifNode, elseNode, op ) {
+function CondNode( a, b, op, ifNode, elseNode ) {
 
 
 	TempNode.call( this );
 	TempNode.call( this );
 
 
 	this.a = a;
 	this.a = a;
 	this.b = b;
 	this.b = b;
 
 
+	this.op = op;
+	
 	this.ifNode = ifNode;
 	this.ifNode = ifNode;
 	this.elseNode = elseNode;
 	this.elseNode = elseNode;
 
 
-	this.op = op;
-
 }
 }
 
 
 CondNode.EQUAL = '==';
 CondNode.EQUAL = '==';
@@ -31,13 +31,22 @@ CondNode.prototype.nodeType = "Cond";
 
 
 CondNode.prototype.getType = function ( builder ) {
 CondNode.prototype.getType = function ( builder ) {
 
 
-	if ( builder.getTypeLength( this.elseNode.getType( builder ) ) > builder.getTypeLength( this.ifNode.getType( builder ) ) ) {
+	if (this.ifNode) {
+		
+		var ifType = this.ifNode.getType( builder );
+		var elseType = this.elseNode.getType( builder );
+		
+		if ( builder.getTypeLength( elseType ) > builder.getTypeLength( ifType ) ) {
 
 
-		return this.elseNode.getType( builder );
+			return elseType;
 
 
-	}
+		}
 
 
-	return this.ifNode.getType( builder );
+		return ifType;
+		
+	}
+	
+	return 'b';
 
 
 };
 };
 
 
@@ -59,10 +68,20 @@ CondNode.prototype.generate = function ( builder, output ) {
 		condType = this.getCondType( builder ),
 		condType = this.getCondType( builder ),
 		a = this.a.build( builder, condType ),
 		a = this.a.build( builder, condType ),
 		b = this.b.build( builder, condType ),
 		b = this.b.build( builder, condType ),
-		ifNode = this.ifNode.build( builder, type ),
-		elseNode = this.elseNode.build( builder, type );
-
-	var code = '( ' + [ a, this.op, b, '?', ifNode, ':', elseNode ].join( ' ' ) + ' )';
+		code;
+		
+	if (this.ifNode) {
+		
+		var ifCode = this.ifNode.build( builder, type ),
+			elseCode = this.elseNode.build( builder, type );
+		
+		code = '( ' + [ a, this.op, b, '?', ifCode, ':', elseCode ].join( ' ' ) + ' )';
+		
+	} else {
+
+		code = '( ' + a + ' ' + this.op + ' ' +  b  + ' )';
+		
+	}
 
 
 	return builder.format( code, this.getType( builder ), output );
 	return builder.format( code, this.getType( builder ), output );
 
 
@@ -75,11 +94,11 @@ CondNode.prototype.copy = function ( source ) {
 	this.a = source.a;
 	this.a = source.a;
 	this.b = source.b;
 	this.b = source.b;
 
 
+	this.op = source.op;
+
 	this.ifNode = source.ifNode;
 	this.ifNode = source.ifNode;
 	this.elseNode = source.elseNode;
 	this.elseNode = source.elseNode;
 
 
-	this.op = source.op;
-
 };
 };
 
 
 CondNode.prototype.toJSON = function ( meta ) {
 CondNode.prototype.toJSON = function ( meta ) {
@@ -93,11 +112,11 @@ CondNode.prototype.toJSON = function ( meta ) {
 		data.a = this.a.toJSON( meta ).uuid;
 		data.a = this.a.toJSON( meta ).uuid;
 		data.b = this.b.toJSON( meta ).uuid;
 		data.b = this.b.toJSON( meta ).uuid;
 
 
-		data.ifNode = this.ifNode.toJSON( meta ).uuid;
-		data.elseNode = this.elseNode.toJSON( meta ).uuid;
-
 		data.op = this.op;
 		data.op = this.op;
 
 
+		if ( data.ifNode ) data.ifNode = this.ifNode.toJSON( meta ).uuid;
+		if ( data.elseNode ) data.elseNode = this.elseNode.toJSON( meta ).uuid;
+
 	}
 	}
 
 
 	return data;
 	return data;

+ 3 - 3
examples/js/nodes/utils/TimerNode.js

@@ -12,7 +12,7 @@ function TimerNode( scale, scope, timeScale ) {
 	this.scale = scale !== undefined ? scale : 1;
 	this.scale = scale !== undefined ? scale : 1;
 	this.scope = scope || TimerNode.GLOBAL;
 	this.scope = scope || TimerNode.GLOBAL;
 
 
-	this.timeScale = timeScale !== undefined ? timeScale : this.scale !== 1;
+	this.timeScale = timeScale !== undefined ? timeScale : scale !== undefined;
 
 
 }
 }
 
 
@@ -24,7 +24,7 @@ TimerNode.prototype = Object.create( FloatNode.prototype );
 TimerNode.prototype.constructor = TimerNode;
 TimerNode.prototype.constructor = TimerNode;
 TimerNode.prototype.nodeType = "Timer";
 TimerNode.prototype.nodeType = "Timer";
 
 
-TimerNode.prototype.isReadonly = function () {
+TimerNode.prototype.getReadonly = function () {
 
 
 	// never use TimerNode as readonly but aways as "uniform"
 	// never use TimerNode as readonly but aways as "uniform"
 
 
@@ -32,7 +32,7 @@ TimerNode.prototype.isReadonly = function () {
 
 
 };
 };
 
 
-TimerNode.prototype.isUnique = function () {
+TimerNode.prototype.getUnique = function () {
 
 
 	// share TimerNode "uniform" input if is used on more time with others TimerNode
 	// share TimerNode "uniform" input if is used on more time with others TimerNode
 
 

+ 1 - 1
examples/js/nodes/utils/VelocityNode.js

@@ -21,7 +21,7 @@ VelocityNode.prototype = Object.create( Vector3Node.prototype );
 VelocityNode.prototype.constructor = VelocityNode;
 VelocityNode.prototype.constructor = VelocityNode;
 VelocityNode.prototype.nodeType = "Velocity";
 VelocityNode.prototype.nodeType = "Velocity";
 
 
-VelocityNode.prototype.isReadonly = function ( builder ) {
+VelocityNode.prototype.getReadonly = function ( builder ) {
 
 
 	return false;
 	return false;
 
 

+ 1 - 1
examples/js/postprocessing/SSAOPass.js

@@ -15,7 +15,7 @@ THREE.SSAOPass = function ( scene, camera, width, height ) {
 	this.scene = scene;
 	this.scene = scene;
 
 
 	this.kernelRadius = 8;
 	this.kernelRadius = 8;
-	this.kernelSize = 64;
+	this.kernelSize = 32;
 	this.kernel = [];
 	this.kernel = [];
 	this.noiseTexture = null;
 	this.noiseTexture = null;
 	this.output = 0;
 	this.output = 0;

+ 1 - 1
examples/js/renderers/SVGRenderer.js

@@ -252,7 +252,7 @@ THREE.SVGRenderer = function () {
 				_vector3.setFromMatrixPosition( object.matrixWorld );
 				_vector3.setFromMatrixPosition( object.matrixWorld );
 				_vector3.applyMatrix4( _viewProjectionMatrix );
 				_vector3.applyMatrix4( _viewProjectionMatrix );
 
 
-				if ( _vector3.z < 0 || _vector3.z > 1 ) return; // #15476
+				if ( _vector3.z < - 1 || _vector3.z > 1 ) return;
 
 
 				var x = _vector3.x * _svgWidthHalf;
 				var x = _vector3.x * _svgWidthHalf;
 				var y = - _vector3.y * _svgHeightHalf;
 				var y = - _vector3.y * _svgHeightHalf;

+ 1 - 1
examples/js/shaders/SSAOShader.js

@@ -11,7 +11,7 @@ THREE.SSAOShader = {
 
 
 	defines: {
 	defines: {
 		"PERSPECTIVE_CAMERA": 1,
 		"PERSPECTIVE_CAMERA": 1,
-		"KERNEL_SIZE": 64
+		"KERNEL_SIZE": 32
 	},
 	},
 
 
 	uniforms: {
 	uniforms: {

+ 2 - 2
examples/webgl_buffergeometry_instancing_lambert.html

@@ -135,11 +135,11 @@
 				#endif
 				#endif
 
 
 				varying vec3 vLightFront;
 				varying vec3 vLightFront;
+				varying vec3 vIndirectFront;
 
 
 				#ifdef DOUBLE_SIDED
 				#ifdef DOUBLE_SIDED
-
 					varying vec3 vLightBack;
 					varying vec3 vLightBack;
-
+					varying vec3 vIndirectBack;
 				#endif
 				#endif
 
 
 				#include <common>
 				#include <common>

+ 5 - 3
examples/webgl_camera_array.html

@@ -26,10 +26,12 @@
 
 
 			function init() {
 			function init() {
 
 
-				var AMOUNT = 6;
-				var SIZE = 1 / AMOUNT;
 				var ASPECT_RATIO = window.innerWidth / window.innerHeight;
 				var ASPECT_RATIO = window.innerWidth / window.innerHeight;
 
 
+				var AMOUNT = 6;
+				var WIDTH = ( window.innerWidth / AMOUNT ) * window.devicePixelRatio;
+				var HEIGHT = ( window.innerHeight / AMOUNT ) * window.devicePixelRatio;
+
 				var cameras = [];
 				var cameras = [];
 
 
 				for ( var y = 0; y < AMOUNT; y ++ ) {
 				for ( var y = 0; y < AMOUNT; y ++ ) {
@@ -37,7 +39,7 @@
 					for ( var x = 0; x < AMOUNT; x ++ ) {
 					for ( var x = 0; x < AMOUNT; x ++ ) {
 
 
 						var subcamera = new THREE.PerspectiveCamera( 40, ASPECT_RATIO, 0.1, 10 );
 						var subcamera = new THREE.PerspectiveCamera( 40, ASPECT_RATIO, 0.1, 10 );
-						subcamera.bounds = new THREE.Vector4( x / AMOUNT, y / AMOUNT, SIZE, SIZE );
+						subcamera.viewport = new THREE.Vector4( Math.floor( x * WIDTH ), Math.floor( y * HEIGHT ), Math.ceil( WIDTH ), Math.ceil( HEIGHT ) );
 						subcamera.position.x = ( x / AMOUNT ) - 0.5;
 						subcamera.position.x = ( x / AMOUNT ) - 0.5;
 						subcamera.position.y = 0.5 - ( y / AMOUNT );
 						subcamera.position.y = 0.5 - ( y / AMOUNT );
 						subcamera.position.z = 1.5;
 						subcamera.position.z = 1.5;

+ 9 - 5
examples/webgl_lights_hemisphere.html

@@ -152,15 +152,14 @@
 				// GROUND
 				// GROUND
 
 
 				var groundGeo = new THREE.PlaneBufferGeometry( 10000, 10000 );
 				var groundGeo = new THREE.PlaneBufferGeometry( 10000, 10000 );
-				var groundMat = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x050505 } );
+				var groundMat = new THREE.MeshLambertMaterial( { color: 0xffffff } );
 				groundMat.color.setHSL( 0.095, 1, 0.75 );
 				groundMat.color.setHSL( 0.095, 1, 0.75 );
 
 
 				var ground = new THREE.Mesh( groundGeo, groundMat );
 				var ground = new THREE.Mesh( groundGeo, groundMat );
-				ground.rotation.x = - Math.PI / 2;
 				ground.position.y = - 33;
 				ground.position.y = - 33;
-				scene.add( ground );
-
+				ground.rotation.x = - Math.PI / 2;
 				ground.receiveShadow = true;
 				ground.receiveShadow = true;
+				scene.add( ground );
 
 
 				// SKYDOME
 				// SKYDOME
 
 
@@ -177,7 +176,12 @@
 				scene.fog.color.copy( uniforms[ "bottomColor" ].value );
 				scene.fog.color.copy( uniforms[ "bottomColor" ].value );
 
 
 				var skyGeo = new THREE.SphereBufferGeometry( 4000, 32, 15 );
 				var skyGeo = new THREE.SphereBufferGeometry( 4000, 32, 15 );
-				var skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } );
+				var skyMat = new THREE.ShaderMaterial( {
+					uniforms: uniforms,
+					vertexShader: vertexShader,
+					fragmentShader: fragmentShader,
+					side: THREE.BackSide
+				} );
 
 
 				var sky = new THREE.Mesh( skyGeo, skyMat );
 				var sky = new THREE.Mesh( skyGeo, skyMat );
 				scene.add( sky );
 				scene.add( sky );

+ 3 - 3
examples/webgl_materials_envmaps_exr.html

@@ -169,9 +169,9 @@
 				var gui = new dat.GUI();
 				var gui = new dat.GUI();
 
 
 				gui.add( params, 'envMap', [ 'EXR', 'PNG' ] );
 				gui.add( params, 'envMap', [ 'EXR', 'PNG' ] );
-				gui.add( params, 'roughness', 0, 1 );
-				gui.add( params, 'metalness', 0, 1 );
-				gui.add( params, 'exposure', 0, 2 );
+				gui.add( params, 'roughness', 0, 1, 0.01 );
+				gui.add( params, 'metalness', 0, 1, 0.01 );
+				gui.add( params, 'exposure', 0, 2, 0.01 );
 				gui.add( params, 'debug', false );
 				gui.add( params, 'debug', false );
 				gui.open();
 				gui.open();
 
 

+ 6 - 3
examples/webgl_materials_envmaps_hdr.html

@@ -117,6 +117,9 @@
 
 
 						hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 						hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
 
 
+						hdrCubeMap.magFilter = THREE.LinearFilter;
+						hdrCubeMap.needsUpdate = true;
+
 						pmremGenerator.dispose();
 						pmremGenerator.dispose();
 						pmremCubeUVPacker.dispose();
 						pmremCubeUVPacker.dispose();
 
 
@@ -183,9 +186,9 @@
 				var gui = new dat.GUI();
 				var gui = new dat.GUI();
 
 
 				gui.add( params, 'envMap', [ 'LDR', 'HDR', 'RGBM16' ] );
 				gui.add( params, 'envMap', [ 'LDR', 'HDR', 'RGBM16' ] );
-				gui.add( params, 'roughness', 0, 1 );
-				gui.add( params, 'metalness', 0, 1 );
-				gui.add( params, 'exposure', 0, 2 );
+				gui.add( params, 'roughness', 0, 1, 0.01 );
+				gui.add( params, 'metalness', 0, 1, 0.01 );
+				gui.add( params, 'exposure', 0, 2, 0.01 );
 				gui.add( params, 'debug', false );
 				gui.add( params, 'debug', false );
 				gui.open();
 				gui.open();
 
 

+ 264 - 9
examples/webgl_materials_nodes.html

@@ -180,6 +180,8 @@
 					'adv / skin-phong': 'skin-phong',
 					'adv / skin-phong': 'skin-phong',
 					'adv / caustic': 'caustic',
 					'adv / caustic': 'caustic',
 					'adv / displace': 'displace',
 					'adv / displace': 'displace',
+					'adv / dissolve': 'dissolve',
+					'adv / dissolve-fire': 'dissolve-fire',
 					'adv / plush': 'plush',
 					'adv / plush': 'plush',
 					'adv / toon': 'toon',
 					'adv / toon': 'toon',
 					'adv / camera-depth': 'camera-depth',
 					'adv / camera-depth': 'camera-depth',
@@ -201,6 +203,7 @@
 					'misc / varying': 'varying',
 					'misc / varying': 'varying',
 					'misc / void-function': 'void-function',
 					'misc / void-function': 'void-function',
 					'misc / readonly': 'readonly',
 					'misc / readonly': 'readonly',
+					'misc / label': 'label',
 					'misc / custom-attribute': 'custom-attribute'
 					'misc / custom-attribute': 'custom-attribute'
 				} ).onFinishChange( function () {
 				} ).onFinishChange( function () {
 
 
@@ -272,8 +275,9 @@
 
 
 				}
 				}
 
 
-				var name = param.example;
-				var mtl;
+				var name = param.example,
+					defaultSide = THREE.DoubleSide,
+					mtl;
 
 
 				clearGui();
 				clearGui();
 
 
@@ -1321,6 +1325,214 @@
 
 
 						break;
 						break;
 
 
+						
+					case 'dissolve':
+
+						// MATERIAL
+
+						mtl = new THREE.StandardNodeMaterial();
+
+						var color = new THREE.ColorNode( 0xEEEEEE );
+						var borderColor = new THREE.ColorNode( 0x0054df );
+						var threshold = new THREE.FloatNode( .1 );
+						var borderSize = new THREE.FloatNode( .2 );
+
+						var tex = new THREE.TextureNode( getTexture( "cloud" ) );
+						var texArea = new THREE.SwitchNode( tex, 'w' );
+
+						var thresholdBorder = new THREE.Math3Node(
+							new THREE.OperatorNode( threshold, borderSize, THREE.OperatorNode.ADD ),
+							threshold,
+							texArea,
+							THREE.Math3Node.SMOOTHSTEP
+						);
+
+						var thresholdEmissive = new THREE.OperatorNode(
+							borderColor,
+							thresholdBorder,
+							THREE.OperatorNode.MUL
+						);
+
+						// APPLY
+
+						mtl.color = color;
+						mtl.emissive = thresholdEmissive;
+						mtl.mask = new THREE.CondNode(
+							texArea, // a: value
+							threshold, // b: value
+							THREE.CondNode.GREATER // condition
+						);
+
+						// GUI
+
+						addGui( 'threshold', threshold.value, function ( val ) {
+
+							threshold.value = val;
+
+						}, false, -.3, 1.3 );
+
+						addGui( 'borderSize', borderSize.value, function ( val ) {
+
+							borderSize.value = val;
+
+						}, false, 0, .5 );
+
+						addGui( 'color', color.value.getHex(), function ( val ) {
+
+							color.value.setHex( val );
+
+						}, true );
+
+						addGui( 'borderColor', borderColor.value.getHex(), function ( val ) {
+
+							borderColor.value.setHex( val );
+
+						}, true );
+
+						break;
+
+					case 'dissolve-fire':
+
+						// MATERIAL
+
+						mtl = new THREE.StandardNodeMaterial();
+
+						var color = new THREE.ColorNode( 0xEEEEEE );
+						var fireStartColor = new THREE.ColorNode( 0xF7CA78 );
+						var fireEndColor = new THREE.ColorNode( 0xFF0000 );
+						var burnedColor = new THREE.ColorNode( 0x000000 );
+						var burnedFinalColor = new THREE.ColorNode( 0x000000 );
+						var threshold = new THREE.FloatNode( .1 );
+						var fireSize = new THREE.FloatNode( .16 );
+						var burnedSize = new THREE.FloatNode( .5 );
+						var timer = new THREE.TimerNode( 0.8 );
+
+						var sinCycleInSecs = new THREE.OperatorNode(
+							timer,
+							new THREE.ConstNode( THREE.ConstNode.PI2 ),
+							THREE.OperatorNode.MUL
+						);
+
+						var cycle = new THREE.Math1Node( sinCycleInSecs, THREE.Math1Node.SIN );
+
+						// round sin to 0 at 1
+						cycle = new THREE.OperatorNode( cycle, new THREE.FloatNode( 1 ), THREE.OperatorNode.ADD );
+						cycle = new THREE.OperatorNode( cycle, new THREE.FloatNode( 2 ), THREE.OperatorNode.DIV );
+
+						// offset to +.9
+						cycle = new THREE.OperatorNode( cycle, new THREE.FloatNode( .9 ), THREE.OperatorNode.ADD );
+
+						var tex = new THREE.TextureNode( getTexture( "cloud" ) );
+						var texArea = new THREE.SwitchNode( tex, 'w' );
+
+						var thresholdBorder = new THREE.Math3Node(
+							new THREE.OperatorNode( threshold, fireSize, THREE.OperatorNode.ADD ),
+							threshold,
+							texArea,
+							THREE.Math3Node.SMOOTHSTEP
+						);
+
+						var fireStartAnimatedColor = new THREE.ColorAdjustmentNode( 
+							fireStartColor, 
+							cycle, 
+							THREE.ColorAdjustmentNode.SATURATION 
+						);
+
+						var fireEndAnimatedColor = new THREE.ColorAdjustmentNode( 
+							fireEndColor, 
+							cycle, 
+							THREE.ColorAdjustmentNode.SATURATION 
+						);
+
+						var fireColor = new THREE.Math3Node(
+							fireEndAnimatedColor,
+							fireStartAnimatedColor,
+							thresholdBorder,
+							THREE.Math3Node.MIX
+						);
+
+						var thresholdBurnedBorder = new THREE.Math3Node(
+							new THREE.OperatorNode( threshold, burnedSize, THREE.OperatorNode.ADD ),
+							threshold,
+							texArea,
+							THREE.Math3Node.SMOOTHSTEP
+						);
+
+						var fireEmissive = new THREE.OperatorNode(
+							fireColor,
+							thresholdBorder,
+							THREE.OperatorNode.MUL
+						);
+
+						var burnedResultColor = new THREE.Math3Node(
+							color,
+							burnedColor,
+							thresholdBurnedBorder,
+							THREE.Math3Node.MIX
+						);
+
+						// APPLY
+
+						mtl.color = burnedResultColor;
+						mtl.emissive = fireEmissive;
+						mtl.mask = new THREE.CondNode(
+							texArea, // a: value
+							threshold, // b: value
+							THREE.CondNode.GREATER // condition
+						);
+
+						// GUI
+
+						addGui( 'threshold', threshold.value, function ( val ) {
+
+							threshold.value = val;
+
+						}, false, -.5, 1.5 );
+
+						addGui( 'fireSize', fireSize.value, function ( val ) {
+
+							fireSize.value = val;
+
+						}, false, 0, .5 );
+
+						addGui( 'burnedSize', burnedSize.value, function ( val ) {
+
+							burnedSize.value = val;
+
+						}, false, 0, 1 );
+
+						addGui( 'color', color.value.getHex(), function ( val ) {
+
+							color.value.setHex( val );
+
+						}, true );
+
+						addGui( 'fireStartColor', fireStartColor.value.getHex(), function ( val ) {
+
+							fireStartColor.value.setHex( val );
+
+						}, true );
+
+						addGui( 'fireEndColor', fireEndColor.value.getHex(), function ( val ) {
+
+							fireEndColor.value.setHex( val );
+
+						}, true );
+
+						addGui( 'burnedColor', burnedColor.value.getHex(), function ( val ) {
+
+							burnedColor.value.setHex( val );
+
+						}, true );
+
+						addGui( 'timeScale', timer.scale, function ( val ) {
+
+							timer.scale = val;
+
+						}, false, 0, 2 );
+
+						break;
+
 					case 'smoke':
 					case 'smoke':
 
 
 						// MATERIAL
 						// MATERIAL
@@ -1366,6 +1578,8 @@
 						mtl.environment = new THREE.ColorNode( 0xFFFFFF );
 						mtl.environment = new THREE.ColorNode( 0xFFFFFF );
 						mtl.alpha = clouds;
 						mtl.alpha = clouds;
 
 
+						defaultSide = THREE.FrontSide;
+
 						// GUI
 						// GUI
 
 
 						addGui( 'color', mtl.environment.value.getHex(), function ( val ) {
 						addGui( 'color', mtl.environment.value.getHex(), function ( val ) {
@@ -2033,6 +2247,7 @@
 						//THREE.NodeLib.add( new THREE.ConstNode("float MY_CONST .05") )
 						//THREE.NodeLib.add( new THREE.ConstNode("float MY_CONST .05") )
 
 
 						// reserved keywords
 						// reserved keywords
+
 						console.log( THREE.NodeLib.keywords );
 						console.log( THREE.NodeLib.keywords );
 
 
 						// keywords conflit? use this to disable:
 						// keywords conflit? use this to disable:
@@ -2172,7 +2387,7 @@
 							ifNode = new THREE.ColorNode( 0x0000FF ),
 							ifNode = new THREE.ColorNode( 0x0000FF ),
 							elseNode = new THREE.ColorNode( 0xFF0000 );
 							elseNode = new THREE.ColorNode( 0xFF0000 );
 
 
-						var cond = new THREE.CondNode( a, b, ifNode, elseNode, THREE.CondNode.EQUAL );
+						var cond = new THREE.CondNode( a, b, THREE.CondNode.EQUAL, ifNode, elseNode );
 
 
 						mtl.color = cond;
 						mtl.color = cond;
 
 
@@ -2311,15 +2526,55 @@
 
 
 						mtl = new THREE.PhongNodeMaterial();
 						mtl = new THREE.PhongNodeMaterial();
 
 
-						mtl.color = new THREE.ColorNode( 0xFFFFFF );
-						mtl.specular = new THREE.FloatNode( .5 );
-						mtl.shininess = new THREE.FloatNode( 15 );
-
 						// not use "uniform" input ( for optimization )
 						// not use "uniform" input ( for optimization )
 						// instead use explicit declaration, for example:
 						// instead use explicit declaration, for example:
 						// vec3( 1.0, 1.0, 1.0 ) instead "uniform vec3"
 						// vec3( 1.0, 1.0, 1.0 ) instead "uniform vec3"
 						// if readonly is true not allow change the value after build the shader material
 						// if readonly is true not allow change the value after build the shader material
-						mtl.color.readonly = mtl.specular.readonly = mtl.shininess.readonly = true;
+
+						mtl.color = new THREE.ColorNode( 0xFFFFFF ).setReadonly( true );
+						mtl.specular = new THREE.FloatNode( .5 ).setReadonly( true );
+						mtl.shininess = new THREE.FloatNode( 15 ).setReadonly( true );
+
+						break;
+
+					case 'label':
+
+						// MATERIAL
+
+						mtl = new THREE.PhongNodeMaterial();
+
+						// label can be useful for finding the nodes as variables in debug level
+						// but this always force the creation of a variable
+						// same as the code can be writed in the same line (inline)
+						// for optimization this is not recommended
+
+						var colorInput = new THREE.ColorNode( 0xFFFFFF ).setLabel( "colorInput" );
+						var specularInput = new THREE.FloatNode( .5 ).setLabel( "specularInput" );
+
+						var colorMix = new THREE.OperatorNode(
+							colorInput,
+							new THREE.ColorNode( 0x6495ED ).setReadonly( true ),
+							THREE.OperatorNode.MUL
+						).setLabel("colorMix");
+
+						mtl.color = colorMix;
+						mtl.specular = specularInput;
+
+						// default: without use label
+						// this is optimized writed the code in a single line (inline)
+						// for the reason that this node is used only once in this shader program
+						mtl.shininess = new THREE.OperatorNode(
+							new THREE.FloatNode( 10 ).setReadonly( true ),
+							new THREE.FloatNode( 5 ).setReadonly( true ),
+							THREE.OperatorNode.ADD
+						);
+
+						mtl.build();
+
+						// show names glsl fragment shader
+						// open console e find using CTRL+F "colorMix" for example
+
+						console.log( mtl.fragmentShader );
 
 
 						break;
 						break;
 
 
@@ -2638,7 +2893,7 @@
 
 
 				// set material
 				// set material
 
 
-				mtl.side = THREE.DoubleSide;
+				mtl.side = defaultSide;
 
 
 				mesh.material = mtl;
 				mesh.material = mtl;
 
 

+ 4 - 11
examples/webgl_materials_standard.html

@@ -102,16 +102,6 @@
 
 
 				//
 				//
 
 
-				new THREE.CubeTextureLoader()
-					.setPath( 'textures/cube/pisa/' )
-					.load( [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ], function ( textureCube ) {
-
-						scene.background = textureCube;
-
-					} );
-
-				//
-
 				var material = new THREE.MeshStandardMaterial();
 				var material = new THREE.MeshStandardMaterial();
 
 
 				new THREE.OBJLoader()
 				new THREE.OBJLoader()
@@ -174,7 +164,10 @@
 					material.envMap = hdrCubeRenderTarget.texture;
 					material.envMap = hdrCubeRenderTarget.texture;
 					material.needsUpdate = true; // is this needed?
 					material.needsUpdate = true; // is this needed?
 
 
-					hdrCubeMap.dispose();
+					hdrCubeMap.magFilter = THREE.LinearFilter;
+					hdrCubeMap.needsUpdate = true;
+					scene.background = hdrCubeMap;
+
 					pmremGenerator.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 					pmremCubeUVPacker.dispose();
 
 

+ 4 - 7
examples/webgl_materials_variations_physical.html

@@ -82,13 +82,7 @@
 
 
 				};
 				};
 
 
-
-				var textureCube = new THREE.CubeTextureLoader()
-					.setPath( 'textures/cube/pisa/' )
-					.load( [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ] );
-
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
-				scene.background = textureCube;
 
 
 				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
 				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
 				var hdrCubeRenderTarget = null;
 				var hdrCubeRenderTarget = null;
@@ -150,7 +144,10 @@
 
 
 					}
 					}
 
 
-					hdrCubeMap.dispose();
+					hdrCubeMap.magFilter = THREE.LinearFilter;
+					hdrCubeMap.needsUpdate = true;
+					scene.background = hdrCubeMap;
+
 					pmremGenerator.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 					pmremCubeUVPacker.dispose();
 
 

+ 4 - 6
examples/webgl_materials_variations_standard.html

@@ -80,12 +80,7 @@
 
 
 				};
 				};
 
 
-				var textureCube = new THREE.CubeTextureLoader()
-					.setPath( 'textures/cube/pisa/' )
-					.load( [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ] );
-
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
-				scene.background = textureCube;
 
 
 				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
 				var hdrUrls = genCubeUrls( './textures/cube/pisaHDR/', '.hdr' );
 				var hdrCubeRenderTarget = null;
 				var hdrCubeRenderTarget = null;
@@ -154,7 +149,10 @@
 
 
 					}
 					}
 
 
-					hdrCubeMap.dispose();
+					hdrCubeMap.magFilter = THREE.LinearFilter;
+					hdrCubeMap.needsUpdate = true;
+					scene.background = hdrCubeMap;
+
 					pmremGenerator.dispose();
 					pmremGenerator.dispose();
 					pmremCubeUVPacker.dispose();
 					pmremCubeUVPacker.dispose();
 
 

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "three",
   "name": "three",
-  "version": "0.100.0",
+  "version": "0.101.0",
   "description": "JavaScript 3D library",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",
   "repository": "mrdoob/three.js",

+ 0 - 162
src/Three.ts

@@ -1,162 +0,0 @@
-import './polyfills';
-
-export {
-  WebGLMultisampleRenderTarget,
-} from './renderers/WebGLMultisampleRenderTarget';
-export { WebGLRenderTargetCube } from './renderers/WebGLRenderTargetCube';
-export { WebGLRenderTarget } from './renderers/WebGLRenderTarget';
-export { WebGLRenderer } from './renderers/WebGLRenderer';
-export { ShaderLib } from './renderers/shaders/ShaderLib';
-export { UniformsLib } from './renderers/shaders/UniformsLib';
-export { UniformsUtils } from './renderers/shaders/UniformsUtils';
-export { ShaderChunk } from './renderers/shaders/ShaderChunk';
-export { FogExp2 } from './scenes/FogExp2';
-export { Fog } from './scenes/Fog';
-export { Scene } from './scenes/Scene';
-export { Sprite } from './objects/Sprite';
-export { LOD } from './objects/LOD';
-export { SkinnedMesh } from './objects/SkinnedMesh';
-export { Skeleton } from './objects/Skeleton';
-export { Bone } from './objects/Bone';
-export { Mesh } from './objects/Mesh';
-export { LineSegments } from './objects/LineSegments';
-export { LineLoop } from './objects/LineLoop';
-export { Line } from './objects/Line';
-export { Points } from './objects/Points';
-export { Group } from './objects/Group';
-export { VideoTexture } from './textures/VideoTexture';
-export { DataTexture } from './textures/DataTexture';
-export { DataTexture3D } from './textures/DataTexture3D';
-export { CompressedTexture } from './textures/CompressedTexture';
-export { CubeTexture } from './textures/CubeTexture';
-export { CanvasTexture } from './textures/CanvasTexture';
-export { DepthTexture } from './textures/DepthTexture';
-export { Texture } from './textures/Texture';
-export * from './geometries/Geometries';
-export * from './materials/Materials';
-export { AnimationLoader } from './loaders/AnimationLoader';
-export { CompressedTextureLoader } from './loaders/CompressedTextureLoader';
-export { DataTextureLoader } from './loaders/DataTextureLoader';
-export { CubeTextureLoader } from './loaders/CubeTextureLoader';
-export { TextureLoader } from './loaders/TextureLoader';
-export { ObjectLoader } from './loaders/ObjectLoader';
-export { MaterialLoader } from './loaders/MaterialLoader';
-export { BufferGeometryLoader } from './loaders/BufferGeometryLoader';
-export {
-  LoadingManager,
-  DefaultLoadingManager,
-} from './loaders/LoadingManager';
-export { ImageLoader } from './loaders/ImageLoader';
-export { ImageBitmapLoader } from './loaders/ImageBitmapLoader';
-export { FontLoader } from './loaders/FontLoader';
-export { FileLoader } from './loaders/FileLoader';
-export { Loader } from './loaders/Loader';
-export { LoaderUtils } from './loaders/LoaderUtils';
-export { Cache } from './loaders/Cache';
-export { AudioLoader } from './loaders/AudioLoader';
-export { SpotLightShadow } from './lights/SpotLightShadow';
-export { SpotLight } from './lights/SpotLight';
-export { PointLight } from './lights/PointLight';
-export { RectAreaLight } from './lights/RectAreaLight';
-export { HemisphereLight } from './lights/HemisphereLight';
-export { DirectionalLightShadow } from './lights/DirectionalLightShadow';
-export { DirectionalLight } from './lights/DirectionalLight';
-export { AmbientLight } from './lights/AmbientLight';
-export { LightShadow } from './lights/LightShadow';
-export { Light } from './lights/Light';
-export { StereoCamera } from './cameras/StereoCamera';
-export { PerspectiveCamera } from './cameras/PerspectiveCamera';
-export { OrthographicCamera } from './cameras/OrthographicCamera';
-export { CubeCamera } from './cameras/CubeCamera';
-export { ArrayCamera } from './cameras/ArrayCamera';
-export { Camera } from './cameras/Camera';
-export { AudioListener } from './audio/AudioListener';
-export { PositionalAudio } from './audio/PositionalAudio';
-export { AudioContext } from './audio/AudioContext';
-export { AudioAnalyser } from './audio/AudioAnalyser';
-export { Audio } from './audio/Audio';
-export { VectorKeyframeTrack } from './animation/tracks/VectorKeyframeTrack';
-export { StringKeyframeTrack } from './animation/tracks/StringKeyframeTrack';
-export {
-  QuaternionKeyframeTrack,
-} from './animation/tracks/QuaternionKeyframeTrack';
-export { NumberKeyframeTrack } from './animation/tracks/NumberKeyframeTrack';
-export { ColorKeyframeTrack } from './animation/tracks/ColorKeyframeTrack';
-export { BooleanKeyframeTrack } from './animation/tracks/BooleanKeyframeTrack';
-export { PropertyMixer } from './animation/PropertyMixer';
-export { PropertyBinding } from './animation/PropertyBinding';
-export { KeyframeTrack } from './animation/KeyframeTrack';
-export { AnimationUtils } from './animation/AnimationUtils';
-export { AnimationObjectGroup } from './animation/AnimationObjectGroup';
-export { AnimationMixer } from './animation/AnimationMixer';
-export { AnimationClip } from './animation/AnimationClip';
-export { Uniform } from './core/Uniform';
-export { InstancedBufferGeometry } from './core/InstancedBufferGeometry';
-export { BufferGeometry } from './core/BufferGeometry';
-export { Geometry } from './core/Geometry';
-export { InterleavedBufferAttribute } from './core/InterleavedBufferAttribute';
-export { InstancedInterleavedBuffer } from './core/InstancedInterleavedBuffer';
-export { InterleavedBuffer } from './core/InterleavedBuffer';
-export { InstancedBufferAttribute } from './core/InstancedBufferAttribute';
-export * from './core/BufferAttribute';
-export { Face3 } from './core/Face3';
-export { Object3D } from './core/Object3D';
-export { Raycaster } from './core/Raycaster';
-export { Layers } from './core/Layers';
-export { EventDispatcher } from './core/EventDispatcher';
-export { Clock } from './core/Clock';
-export {
-  QuaternionLinearInterpolant,
-} from './math/interpolants/QuaternionLinearInterpolant';
-export { LinearInterpolant } from './math/interpolants/LinearInterpolant';
-export { DiscreteInterpolant } from './math/interpolants/DiscreteInterpolant';
-export { CubicInterpolant } from './math/interpolants/CubicInterpolant';
-export { Interpolant } from './math/Interpolant';
-export { Triangle } from './math/Triangle';
-export { _Math as Math } from './math/Math';
-export { Spherical } from './math/Spherical';
-export { Cylindrical } from './math/Cylindrical';
-export { Plane } from './math/Plane';
-export { Frustum } from './math/Frustum';
-export { Sphere } from './math/Sphere';
-export { Ray } from './math/Ray';
-export { Matrix4 } from './math/Matrix4';
-export { Matrix3 } from './math/Matrix3';
-export { Box3 } from './math/Box3';
-export { Box2 } from './math/Box2';
-export { Line3 } from './math/Line3';
-export { Euler } from './math/Euler';
-export { Vector4 } from './math/Vector4';
-export { Vector3 } from './math/Vector3';
-export { Vector2 } from './math/Vector2';
-export { Quaternion } from './math/Quaternion';
-export { Color } from './math/Color';
-export { ImmediateRenderObject } from './extras/objects/ImmediateRenderObject';
-export { VertexNormalsHelper } from './helpers/VertexNormalsHelper';
-export { SpotLightHelper } from './helpers/SpotLightHelper';
-export { SkeletonHelper } from './helpers/SkeletonHelper';
-export { PointLightHelper } from './helpers/PointLightHelper';
-export { RectAreaLightHelper } from './helpers/RectAreaLightHelper';
-export { HemisphereLightHelper } from './helpers/HemisphereLightHelper';
-export { GridHelper } from './helpers/GridHelper';
-export { PolarGridHelper } from './helpers/PolarGridHelper';
-export { FaceNormalsHelper } from './helpers/FaceNormalsHelper';
-export { DirectionalLightHelper } from './helpers/DirectionalLightHelper';
-export { CameraHelper } from './helpers/CameraHelper';
-export { BoxHelper } from './helpers/BoxHelper';
-export { Box3Helper } from './helpers/Box3Helper';
-export { PlaneHelper } from './helpers/PlaneHelper';
-export { ArrowHelper } from './helpers/ArrowHelper';
-export { AxesHelper } from './helpers/AxesHelper';
-export * from './extras/curves/Curves';
-export { Shape } from './extras/core/Shape';
-export { Path } from './extras/core/Path';
-export { ShapePath } from './extras/core/ShapePath';
-export { Font } from './extras/core/Font';
-export { CurvePath } from './extras/core/CurvePath';
-export { Curve } from './extras/core/Curve';
-export { ImageUtils } from './extras/ImageUtils';
-export { ShapeUtils } from './extras/ShapeUtils';
-//export { WebGLUtils } from './renderers/webgl/WebGLUtils';
-export * from './constants';
-export * from './Three.Legacy';

+ 1 - 1
src/constants.js

@@ -1,4 +1,4 @@
-export var REVISION = '101dev';
+export var REVISION = '101';
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var CullFaceNone = 0;
 export var CullFaceNone = 0;
 export var CullFaceBack = 1;
 export var CullFaceBack = 1;

+ 2 - 0
src/objects/Mesh.js

@@ -264,6 +264,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 								if ( intersection ) {
 								if ( intersection ) {
 
 
 									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
 									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
+									intersection.face.materialIndex = group.materialIndex;
 									intersects.push( intersection );
 									intersects.push( intersection );
 
 
 								}
 								}
@@ -321,6 +322,7 @@ Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
 								if ( intersection ) {
 								if ( intersection ) {
 
 
 									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
 									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics
+									intersection.face.materialIndex = group.materialIndex;
 									intersects.push( intersection );
 									intersects.push( intersection );
 
 
 								}
 								}

+ 4 - 2
src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl.js

@@ -12,9 +12,11 @@ backGeometry.normal = -geometry.normal;
 backGeometry.viewDir = geometry.viewDir;
 backGeometry.viewDir = geometry.viewDir;
 
 
 vLightFront = vec3( 0.0 );
 vLightFront = vec3( 0.0 );
+vIndirectFront = vec3( 0.0 );
 
 
 #ifdef DOUBLE_SIDED
 #ifdef DOUBLE_SIDED
 	vLightBack = vec3( 0.0 );
 	vLightBack = vec3( 0.0 );
+	vIndirectBack = vec3( 0.0 );
 #endif
 #endif
 
 
 IncidentLight directLight;
 IncidentLight directLight;
@@ -103,11 +105,11 @@ vec3 directLightColor_Diffuse;
 	#pragma unroll_loop
 	#pragma unroll_loop
 	for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
 	for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
 
 
-		vLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );
+		vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );
 
 
 		#ifdef DOUBLE_SIDED
 		#ifdef DOUBLE_SIDED
 
 
-			vLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );
+			vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );
 
 
 		#endif
 		#endif
 
 

+ 5 - 1
src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js

@@ -128,7 +128,11 @@ void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradia
 
 
 		BRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );
 		BRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );
 
 
-		vec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );
+		// The multiscattering paper uses the below formula for calculating diffuse 
+		// for dielectrics, but this is already handled when initially computing the 
+		// specular and diffuse color, so we can just use the diffuseColor directly.
+		//vec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );
+		vec3 diffuse = material.diffuseColor;
 
 
 		reflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;
 		reflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;
 		reflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;
 		reflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;

+ 13 - 3
src/renderers/shaders/ShaderLib/meshlambert_frag.glsl.js

@@ -4,13 +4,14 @@ uniform vec3 emissive;
 uniform float opacity;
 uniform float opacity;
 
 
 varying vec3 vLightFront;
 varying vec3 vLightFront;
+varying vec3 vIndirectFront;
 
 
 #ifdef DOUBLE_SIDED
 #ifdef DOUBLE_SIDED
-
 	varying vec3 vLightBack;
 	varying vec3 vLightBack;
-
+	varying vec3 vIndirectBack;
 #endif
 #endif
 
 
+
 #include <common>
 #include <common>
 #include <packing>
 #include <packing>
 #include <dithering_pars_fragment>
 #include <dithering_pars_fragment>
@@ -51,6 +52,16 @@ void main() {
 	// accumulation
 	// accumulation
 	reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );
 	reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );
 
 
+	#ifdef DOUBLE_SIDED
+
+		reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;
+
+	#else
+
+		reflectedLight.indirectDiffuse += vIndirectFront;
+
+	#endif
+
 	#include <lightmap_fragment>
 	#include <lightmap_fragment>
 
 
 	reflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );
 	reflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );
@@ -81,6 +92,5 @@ void main() {
 	#include <fog_fragment>
 	#include <fog_fragment>
 	#include <premultiplied_alpha_fragment>
 	#include <premultiplied_alpha_fragment>
 	#include <dithering_fragment>
 	#include <dithering_fragment>
-
 }
 }
 `;
 `;

+ 2 - 3
src/renderers/shaders/ShaderLib/meshlambert_vert.glsl.js

@@ -2,11 +2,11 @@ export default /* glsl */`
 #define LAMBERT
 #define LAMBERT
 
 
 varying vec3 vLightFront;
 varying vec3 vLightFront;
+varying vec3 vIndirectFront;
 
 
 #ifdef DOUBLE_SIDED
 #ifdef DOUBLE_SIDED
-
 	varying vec3 vLightBack;
 	varying vec3 vLightBack;
-
+	varying vec3 vIndirectBack;
 #endif
 #endif
 
 
 #include <common>
 #include <common>
@@ -47,6 +47,5 @@ void main() {
 	#include <lights_lambert_vertex>
 	#include <lights_lambert_vertex>
 	#include <shadowmap_vertex>
 	#include <shadowmap_vertex>
 	#include <fog_vertex>
 	#include <fog_vertex>
-
 }
 }
 `;
 `;

+ 1 - 1
src/renderers/webgl/WebGLBackground.js

@@ -60,7 +60,7 @@ function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
 						vertexShader: ShaderLib.cube.vertexShader,
 						vertexShader: ShaderLib.cube.vertexShader,
 						fragmentShader: ShaderLib.cube.fragmentShader,
 						fragmentShader: ShaderLib.cube.fragmentShader,
 						side: BackSide,
 						side: BackSide,
-						depthTest: true,
+						depthTest: false,
 						depthWrite: false,
 						depthWrite: false,
 						fog: false
 						fog: false
 					} )
 					} )

+ 19 - 19
src/renderers/webgl/WebGLTextures.js

@@ -83,9 +83,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 	}
 	}
 
 
-	function textureNeedsGenerateMipmaps( texture, isPowerOfTwo ) {
+	function textureNeedsGenerateMipmaps( texture, supportsMips ) {
 
 
-		return texture.generateMipmaps && isPowerOfTwo &&
+		return texture.generateMipmaps && supportsMips &&
 			texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
 			texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
 
 
 	}
 	}
@@ -355,12 +355,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 				}
 				}
 
 
 				var image = cubeImage[ 0 ],
 				var image = cubeImage[ 0 ],
-					isPowerOfTwoImage = isPowerOfTwo( image ),
+					supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2,
 					glFormat = utils.convert( texture.format ),
 					glFormat = utils.convert( texture.format ),
 					glType = utils.convert( texture.type ),
 					glType = utils.convert( texture.type ),
 					glInternalFormat = getInternalFormat( glFormat, glType );
 					glInternalFormat = getInternalFormat( glFormat, glType );
 
 
-				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
+				setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, supportsMips );
 
 
 				for ( var i = 0; i < 6; i ++ ) {
 				for ( var i = 0; i < 6; i ++ ) {
 
 
@@ -418,7 +418,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 				}
 				}
 
 
-				if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) {
+				if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
 
 
 					// We assume images for cube map have the same size.
 					// We assume images for cube map have the same size.
 					generateMipmap( _gl.TEXTURE_CUBE_MAP, texture, image.width, image.height );
 					generateMipmap( _gl.TEXTURE_CUBE_MAP, texture, image.width, image.height );
@@ -447,11 +447,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 	}
 	}
 
 
-	function setTextureParameters( textureType, texture, isPowerOfTwoImage ) {
+	function setTextureParameters( textureType, texture, supportsMips ) {
 
 
 		var extension;
 		var extension;
 
 
-		if ( isPowerOfTwoImage ) {
+		if ( supportsMips ) {
 
 
 			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, utils.convert( texture.wrapS ) );
 			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, utils.convert( texture.wrapS ) );
 			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, utils.convert( texture.wrapT ) );
 			_gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, utils.convert( texture.wrapT ) );
@@ -539,12 +539,12 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 		var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;
 		var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;
 		var image = resizeImage( texture.image, needsPowerOfTwo, false, capabilities.maxTextureSize );
 		var image = resizeImage( texture.image, needsPowerOfTwo, false, capabilities.maxTextureSize );
 
 
-		var isPowerOfTwoImage = isPowerOfTwo( image ),
+		var supportsMips = isPowerOfTwo( image ) || capabilities.isWebGL2,
 			glFormat = utils.convert( texture.format ),
 			glFormat = utils.convert( texture.format ),
 			glType = utils.convert( texture.type ),
 			glType = utils.convert( texture.type ),
 			glInternalFormat = getInternalFormat( glFormat, glType );
 			glInternalFormat = getInternalFormat( glFormat, glType );
 
 
-		setTextureParameters( textureType, texture, isPowerOfTwoImage );
+		setTextureParameters( textureType, texture, supportsMips );
 
 
 		var mipmap, mipmaps = texture.mipmaps;
 		var mipmap, mipmaps = texture.mipmaps;
 
 
@@ -610,7 +610,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 			// if there are no manual mipmaps
 			// if there are no manual mipmaps
 			// set 0 level mipmap and then use GL to generate other mipmap levels
 			// set 0 level mipmap and then use GL to generate other mipmap levels
 
 
-			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
+			if ( mipmaps.length > 0 && supportsMips ) {
 
 
 				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
 				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
 
 
@@ -670,7 +670,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 			// if there are no manual mipmaps
 			// if there are no manual mipmaps
 			// set 0 level mipmap and then use GL to generate other mipmap levels
 			// set 0 level mipmap and then use GL to generate other mipmap levels
 
 
-			if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
+			if ( mipmaps.length > 0 && supportsMips ) {
 
 
 				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
 				for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
 
 
@@ -691,7 +691,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 		}
 		}
 
 
-		if ( textureNeedsGenerateMipmaps( texture, isPowerOfTwoImage ) ) {
+		if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
 
 
 			generateMipmap( _gl.TEXTURE_2D, texture, image.width, image.height );
 			generateMipmap( _gl.TEXTURE_2D, texture, image.width, image.height );
 
 
@@ -880,7 +880,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 		var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
 		var isCube = ( renderTarget.isWebGLRenderTargetCube === true );
 		var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true );
 		var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true );
-		var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
+		var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2;
 
 
 		// Setup framebuffer
 		// Setup framebuffer
 
 
@@ -941,7 +941,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 		if ( isCube ) {
 		if ( isCube ) {
 
 
 			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
 			state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
-			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
+			setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, supportsMips );
 
 
 			for ( var i = 0; i < 6; i ++ ) {
 			for ( var i = 0; i < 6; i ++ ) {
 
 
@@ -949,7 +949,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 			}
 			}
 
 
-			if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) {
+			if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
 
 
 				generateMipmap( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, renderTarget.width, renderTarget.height );
 				generateMipmap( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, renderTarget.width, renderTarget.height );
 
 
@@ -960,10 +960,10 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 		} else {
 		} else {
 
 
 			state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
 			state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
-			setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
+			setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, supportsMips );
 			setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
 			setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
 
 
-			if ( textureNeedsGenerateMipmaps( renderTarget.texture, isTargetPowerOfTwo ) ) {
+			if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
 
 
 				generateMipmap( _gl.TEXTURE_2D, renderTarget.texture, renderTarget.width, renderTarget.height );
 				generateMipmap( _gl.TEXTURE_2D, renderTarget.texture, renderTarget.width, renderTarget.height );
 
 
@@ -986,9 +986,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 	function updateRenderTargetMipmap( renderTarget ) {
 	function updateRenderTargetMipmap( renderTarget ) {
 
 
 		var texture = renderTarget.texture;
 		var texture = renderTarget.texture;
-		var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
+		var supportsMips = isPowerOfTwo( renderTarget ) || capabilities.isWebGL2;
 
 
-		if ( textureNeedsGenerateMipmaps( texture, isTargetPowerOfTwo ) ) {
+		if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
 
 
 			var target = renderTarget.isWebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
 			var target = renderTarget.isWebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
 			var webglTexture = properties.get( texture ).__webglTexture;
 			var webglTexture = properties.get( texture ).__webglTexture;

+ 2 - 0
src/scenes/Scene.js

@@ -22,6 +22,8 @@ Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 
 	constructor: Scene,
 	constructor: Scene,
 
 
+	isScene: true,
+
 	copy: function ( source, recursive ) {
 	copy: function ( source, recursive ) {
 
 
 		Object3D.prototype.copy.call( this, source, recursive );
 		Object3D.prototype.copy.call( this, source, recursive );

部分文件因为文件数量过多而无法显示