Browse Source

Added linewidth support

WestLangley 8 years ago
parent
commit
dd9229b178

+ 31 - 0
examples/js/lines/Line2.js

@@ -0,0 +1,31 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ */
+
+THREE.Line2 = function ( geometry, material ) {
+
+	THREE.LineSegments2.call( this );
+
+	this.type = 'Line2';
+
+	this.geometry = geometry !== undefined ? geometry : new THREE.LineGeometry();
+	this.material = material !== undefined ? material : new THREE.LineMaterial( { color: Math.random() * 0xffffff } );
+
+};
+
+THREE.Line2.prototype = Object.assign( Object.create( THREE.LineSegments2.prototype ), {
+
+	constructor: THREE.Line2,
+
+	isLine2: true,
+
+	copy: function ( source ) {
+
+		// todo
+
+		return this;
+
+	}
+
+} );

+ 98 - 0
examples/js/lines/LineGeometry.js

@@ -0,0 +1,98 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ */
+
+THREE.LineGeometry = function () {
+
+	THREE.LineSegmentsGeometry.call( this );
+
+	this.type = 'LineGeometry';
+
+};
+
+THREE.LineGeometry.prototype = Object.assign( Object.create( THREE.LineSegmentsGeometry.prototype ), {
+
+	constructor: THREE.LineGeometry,
+
+	isLineGeometry: true,
+
+	setPositions: function ( array ) {
+
+		// converts [ x1, y1, z1,  x2, y2, z2, ... ] to pairs format
+
+		var length = array.length - 3;
+		var points = new Float32Array( 2 * length );
+
+		for ( var i = 0; i < length; i += 3 ) {
+
+			points[ 2 * i ] = array[ i ];
+			points[ 2 * i + 1 ] = array[ i + 1 ];
+			points[ 2 * i + 2 ] = array[ i + 2 ];
+
+			points[ 2 * i + 3 ] = array[ i + 3 ];
+			points[ 2 * i + 4 ] = array[ i + 4 ];
+			points[ 2 * i + 5 ] = array[ i + 5 ];
+
+		}
+
+		THREE.LineSegmentsGeometry.prototype.setPositions.call( this, points );
+
+		return this;
+
+	},
+
+	setColors: function ( array ) {
+
+		// converts [ r1, g1, b1,  r2, g2, b2, ... ] to pairs format
+
+		var length = array.length - 3;
+		var colors = new Float32Array( 2 * length );
+
+		for ( var i = 0; i < length; i += 3 ) {
+
+			colors[ 2 * i ] = array[ i ];
+			colors[ 2 * i + 1 ] = array[ i + 1 ];
+			colors[ 2 * i + 2 ] = array[ i + 2 ];
+
+			colors[ 2 * i + 3 ] = array[ i + 3 ];
+			colors[ 2 * i + 4 ] = array[ i + 4 ];
+			colors[ 2 * i + 5 ] = array[ i + 5 ];
+
+		}
+
+		THREE.LineSegmentsGeometry.prototype.setColors.call( this, colors );
+
+		return this;
+
+	},
+
+	fromLine: function ( line ) {
+
+		var geometry = line.geometry;
+
+		if ( geometry.isGeometry ) {
+
+			this.setPositions( geometry.vertices );
+
+		} else if ( geometry.isBufferGeometry ) {
+
+			this.setPositions( geometry.position.array ); // assumes non-indexed
+
+		}
+
+		// set colors, maybe
+
+		return this;
+
+	},
+
+	copy: function ( source ) {
+
+		// todo
+
+		return this;
+
+	}
+
+} );

+ 260 - 0
examples/js/lines/LineMaterial.js

@@ -0,0 +1,260 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ * parameters = {
+ *  color: <hex>,
+ *  linewidth: <float>,
+ *  resolution: <Vector2>, // to be set by renderer
+ * }
+ */
+
+THREE.UniformsLib.line = {
+
+	linewidth: { value: 1 },
+	resolution: { value: new THREE.Vector2( 1, 1 ) }
+
+};
+
+THREE.ShaderLib[ 'line' ] = {
+
+	uniforms: THREE.UniformsUtils.merge( [
+		THREE.UniformsLib.common,
+		THREE.UniformsLib.fog,
+		THREE.UniformsLib.line
+	] ),
+
+	vertexShader:
+		`
+		#include <common>
+		#include <color_pars_vertex>
+		#include <fog_pars_vertex>
+		#include <logdepthbuf_pars_vertex>
+		#include <clipping_planes_pars_vertex>
+
+		uniform float linewidth;
+		uniform vec2 resolution;
+
+		attribute vec3 instanceStart;
+		attribute vec3 instanceEnd;
+
+		attribute vec3 instanceColorStart;
+		attribute vec3 instanceColorEnd;
+
+		varying vec2 vUv;
+
+		void main() {
+
+			#ifdef USE_COLOR
+				vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
+			#endif
+
+			float aspect = resolution.x / resolution.y;
+
+			vUv = uv;
+
+			// camera space
+			vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
+			vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
+
+			// clip space
+			vec4 clipStart = projectionMatrix * start;
+			vec4 clipEnd = projectionMatrix * end;
+
+			// ndc space
+			vec2 ndcStart = clipStart.xy / clipStart.w;
+			vec2 ndcEnd = clipEnd.xy / clipEnd.w;
+
+			// direction
+			vec2 dir = ndcEnd - ndcStart;
+
+			// account for clip-space aspect ratio
+			dir.x *= aspect;
+			dir = normalize( dir );
+
+			// perpendicular to dir
+			vec2 offset = vec2( dir.y, - dir.x );
+
+			// undo aspect ratio adjustment
+			dir.x /= aspect;
+			offset.x /= aspect;
+
+			// sign flip
+			if ( position.x < 0.0 ) offset *= - 1.0;
+
+			// endcaps
+			if ( position.y < 0.0 ) {
+
+				offset += - dir;
+
+			} else if ( position.y > 1.0 ) {
+
+				offset += dir;
+
+			}
+
+			// adjust for linewidth
+			offset *= linewidth;
+
+			// adjust for clip-space to screen-space conversion // maybe it should be based on viewport ...
+			offset /= resolution.y;
+
+			// select end
+			vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
+
+			// back to clip space
+			offset *= clip.w;
+
+			clip.xy += offset;
+
+			gl_Position = clip;
+
+			#include <logdepthbuf_vertex>
+
+			#include <worldpos_vertex>
+			#include <clipping_planes_vertex>
+			#include <fog_vertex>
+
+		}
+		`,
+
+	fragmentShader:
+		`
+		uniform vec3 diffuse;
+		uniform float opacity;
+
+		#include <common>
+		#include <color_pars_fragment>
+		#include <fog_pars_fragment>
+		#include <logdepthbuf_pars_fragment>
+		#include <clipping_planes_pars_fragment>
+
+			varying vec2 vUv;
+
+		void main() {
+
+			#include <clipping_planes_fragment>
+
+			if ( vUv.y < 0.5 || vUv.y > 0.5 ) {
+
+				float a = vUv.x - 0.5;
+				float b = vUv.y - 0.5;
+				float len2 = a * a + b * b;
+
+				if ( len2 > 0.25 ) discard;
+
+			}
+
+			vec4 diffuseColor = vec4( diffuse, opacity );
+
+			#include <logdepthbuf_fragment>
+			#include <color_fragment>
+
+			gl_FragColor = vec4( diffuseColor.rgb, diffuseColor.a );
+
+			#include <premultiplied_alpha_fragment>
+			#include <tonemapping_fragment>
+			#include <encodings_fragment>
+			#include <fog_fragment>
+
+		}
+		`
+};
+
+THREE.LineMaterial = function ( parameters ) {
+
+	THREE.ShaderMaterial.call( this, {
+
+		type: 'LineMaterial',
+
+		side: THREE.DoubleSide, // for now. there is an issue with segments that terminate behind the camera
+
+		uniforms: THREE.UniformsUtils.clone( THREE.ShaderLib[ 'line' ].uniforms ),
+
+		vertexShader: THREE.ShaderLib[ 'line' ].vertexShader,
+		fragmentShader: THREE.ShaderLib[ 'line' ].fragmentShader
+
+	} );
+
+	Object.defineProperties( this, {
+
+		color: {
+
+			enumerable: true,
+
+			get: function () {
+
+				return this.uniforms.diffuse.value;
+
+			},
+
+			set: function ( value ) {
+
+				this.uniforms.diffuse.value = value;
+
+			}
+
+		},
+
+		linewidth: {
+
+			enumerable: true,
+
+			get: function () {
+
+				return this.uniforms.linewidth.value;
+
+			},
+
+			set: function ( value ) {
+
+				this.uniforms.linewidth.value = value;
+
+			}
+
+		},
+
+		resolution: {
+
+			enumerable: true,
+
+			get: function () {
+
+				return this.uniforms.resolution.value;
+
+			},
+
+			set: function ( value ) {
+
+				this.uniforms.resolution.value.copy( value );
+
+			}
+
+		}
+
+	} );
+
+	this.setValues( parameters );
+
+};
+
+THREE.LineMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype );
+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;
+
+};
+

+ 31 - 0
examples/js/lines/LineSegments2.js

@@ -0,0 +1,31 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ */
+
+THREE.LineSegments2 = function ( geometry, material ) {
+
+	THREE.Mesh.call( this );
+
+	this.type = 'LineSegments2';
+
+	this.geometry = geometry !== undefined ? geometry : new THREE.LineSegmentsGeometry();
+	this.material = material !== undefined ? material : new THREE.LineMaterial( { color: Math.random() * 0xffffff } );
+
+};
+
+THREE.LineSegments2.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
+
+	constructor: THREE.LineSegments2,
+
+	isLineSegments2: true,
+
+	copy: function ( source ) {
+
+		// todo
+
+		return this;
+
+	}
+
+} );

+ 207 - 0
examples/js/lines/LineSegmentsGeometry.js

@@ -0,0 +1,207 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ */
+
+THREE.LineSegmentsGeometry = function () {
+
+	THREE.InstancedBufferGeometry.call( this );
+
+	this.type = 'LineSegmentsGeometry';
+
+	var plane = new THREE.BufferGeometry();
+
+	var positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
+	var uvs = [ 0, 1, 1, 1, 0, .5, 1, .5, 0, .5, 1, .5, 0, 0, 1, 0 ];
+	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 ) );
+
+};
+
+THREE.LineSegmentsGeometry.prototype = Object.assign( Object.create( THREE.InstancedBufferGeometry.prototype ), {
+
+	constructor: THREE.LineSegmentsGeometry,
+
+	isLineSegmentsGeometry: true,
+
+	setPositions: function ( array ) {
+
+		var lineSegments;
+
+		if ( array instanceof Float32Array ) {
+
+			lineSegments = array;
+
+		} else if ( Array.isArray( array ) ) {
+
+			lineSegments = new Float32Array( array );
+
+		}
+
+		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.computeBoundingBox();
+		this.computeBoundingSphere();
+
+		return this;
+
+	},
+
+	setColors: function ( array ) {
+
+		var colors;
+
+		if ( array instanceof Float32Array ) {
+
+			colors = array;
+
+		} else if ( Array.isArray( array ) ) {
+
+			colors = new Float32Array( array );
+
+		}
+
+		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
+
+		return this;
+
+	},
+
+	fromWireframeGeometry: function ( geometry ) {
+
+		this.setPositions( geometry.attributes.position.array );
+
+		return this;
+
+	},
+
+	fromEdgesGeometry: function ( geometry ) {
+
+		this.setPositions( geometry.attributes.position.array );
+
+		return this;
+
+	},
+
+	fromMesh: function ( mesh ) {
+
+		this.fromWireframeGeometry( new THREE.WireframeGeometry( mesh.geometry ) );
+
+		// set colors, maybe
+
+		return this;
+
+	},
+
+	fromLineSegements: function ( lineSegments ) {
+
+		var geometry = lineSegments.geometry;
+
+		if ( geometry.isGeometry ) {
+
+			this.setPositions( geometry.vertices );
+
+		} else if ( geometry.isBufferGeometry ) {
+
+			this.setPositions( geometry.position.array ); // assumes non-indexed
+
+		}
+
+		// set colors, maybe
+
+		return this;
+
+	},
+
+	computeBoundingBox: function () {
+
+		if ( this.boundingBox === null ) {
+
+			this.boundingBox = new THREE.Box3();
+
+		}
+
+		if ( this.attributes.instanceStart !== undefined ) {
+
+			this.boundingBox.setFromBufferAttribute( this.attributes.instanceStart );
+			var box = new THREE.Box3().setFromBufferAttribute( this.attributes.instanceEnd );
+
+			this.boundingBox.union( box );
+
+		}
+
+	},
+
+	computeBoundingSphere: function () {
+
+		var vector = new THREE.Vector3();
+
+		return function computeBoundingSphere() {
+
+			if ( this.boundingSphere === null ) {
+
+				this.boundingSphere = new THREE.Sphere();
+
+			}
+
+			if ( this.boundingBox === null ) {
+
+				this.computeBoundingBox();
+
+			}
+
+			var start = this.attributes.instanceStart;
+			var end = this.attributes.instanceEnd;
+
+			if ( start && end ) {
+
+				var center = this.boundingSphere.center;
+
+				this.boundingBox.getCenter( center );
+
+				var maxRadiusSq = 0;
+
+				for ( var i = 0, il = start.count; i < il; i ++ ) {
+
+					vector.fromBufferAttribute( start, i );
+					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+
+					vector.fromBufferAttribute( end, i );
+					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+
+				}
+
+				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
+
+				if ( isNaN( this.boundingSphere.radius ) ) {
+
+					console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
+
+				}
+
+			}
+
+		};
+
+	}(),
+
+	copy: function ( source ) {
+
+		// todo
+
+		return this;
+
+	}
+
+} );

+ 31 - 0
examples/js/lines/Wireframe.js

@@ -0,0 +1,31 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ */
+
+THREE.Wireframe = function ( geometry, material ) {
+
+	THREE.Mesh.call( this );
+
+	this.type = 'Wireframe';
+
+	this.geometry = geometry !== undefined ? geometry : new THREE.LineSegmentsGeometry();
+	this.material = material !== undefined ? material : new THREE.LineMaterial( { color: Math.random() * 0xffffff } );
+
+};
+
+THREE.Wireframe.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
+
+	constructor: THREE.Wireframe,
+
+	isWireframe: true,
+
+	copy: function ( source ) {
+
+		// todo
+
+		return this;
+
+	}
+
+} );

+ 32 - 0
examples/js/lines/WireframeGeometry2.js

@@ -0,0 +1,32 @@
+/**
+ * @author WestLangley / http://github.com/WestLangley
+ *
+ */
+
+THREE.WireframeGeometry2 = function ( geometry ) {
+
+	THREE.LineSegmentsGeometry.call( this );
+
+	this.type = 'WireframeGeometry2';
+
+	this.fromWireframeGeometry( new THREE.WireframeGeometry( geometry ) );
+
+	// set colors, maybe
+
+};
+
+THREE.WireframeGeometry2.prototype = Object.assign( Object.create( THREE.LineSegmentsGeometry.prototype ), {
+
+	constructor: THREE.WireframeGeometry2,
+
+	isWireframeGeometry2: true,
+
+	copy: function ( source ) {
+
+		// todo
+
+		return this;
+
+	}
+
+} );

+ 288 - 0
examples/webgl_lines_fat.html

@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - lines - fat</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				background-color: #000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				color: #ffffff;
+				top: 0px;
+				width: 100%;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+			}
+			a {
+				color: #fff;
+			}
+		</style>
+	</head>
+
+	<body>
+
+		<div id="container"></div>
+
+		<div id="info"><a href="https://threejs.org" target="_blank">three.js</a> - fat lines</div>
+
+		<script src="../build/three.js"></script>
+		<script src="js/controls/OrbitControls.js"></script>
+
+		<script src="js/geometries/hilbert3D.js"></script>
+
+		<script src="js/Detector.js"></script>
+
+		<script src="js/libs/stats.min.js"></script>
+		<script src='js/libs/dat.gui.min.js'></script>
+
+		<script src='js/lines/LineSegmentsGeometry.js'></script>
+		<script src='js/lines/LineGeometry.js'></script>
+		<script src='js/lines/WireframeGeometry2.js'></script>
+
+		<script src='js/lines/LineMaterial.js'></script>
+
+		<script src='js/lines/LineSegments2.js'></script>
+		<script src='js/lines/Line2.js'></script>
+		<script src='js/lines/Wireframe.js'></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var line, wireframe, renderer, scene, camera, controls;
+			var line1, wireframe1;
+			var renderStats;
+			var gui;
+
+			// viewport
+			var insetWidth;
+			var insetHeight;
+
+			init();
+			animate();
+
+			function init() {
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setClearColor( 0x000000, 0.0 );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				scene = new THREE.Scene();
+
+				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( -40, 0, 60 );
+
+				controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.minDistance = 10;
+				controls.maxDistance = 500;
+
+
+				// Position and Color Data
+
+				var positions = [];
+				var colors = [];
+
+				var points = hilbert3D( new THREE.Vector3( 0, 0, 0 ), 20.0, 1, 0, 1, 2, 3, 4, 5, 6, 7 );
+
+				var spline = new THREE.CatmullRomCurve3( points );
+				var divisions = Math.round( 12 * points.length );
+				var color = new THREE.Color();
+
+				for ( var i = 0, l = divisions; i < l; i ++ ) {
+
+					var point = spline.getPoint( i / l );
+					positions.push( point.x, point.y, point.z );
+
+					color.setHSL( i / l, 1.0, 0.5 );
+					colors.push( color.r, color.g, color.b );
+
+				}
+
+
+				// THREE.Line2 ( LineGeometry, LineMaterial )
+
+				var geometry = new THREE.LineGeometry();
+				geometry.setPositions( positions );
+				geometry.setColors( colors );
+
+				var material = new THREE.LineMaterial( {
+
+					color: 0xffffff,
+					linewidth: 10, // in pixels
+					vertexColors: THREE.VertexColors,
+					//resolution:  // to be set by renderer, eventually
+
+				} );
+
+				line = new THREE.Line2( geometry, material );
+				line.scale.set( 1, 1, 1 );
+				scene.add( line );
+
+
+				// THREE.Line ( BufferGeometry, LineBasicMaterial ) - rendered with gl.LINE_STRIP
+
+				var geo = new THREE.BufferGeometry();
+				geo.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
+				geo.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
+
+				var mat = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
+
+				line1 = new THREE.Line( geo, mat );
+				line1.visible = false;
+				scene.add( line1 );
+
+
+				// THREE.Wireframe ( WireframeGeometry2, LineMaterial )
+
+				//var geo = new THREE.BoxBufferGeometry( 16, 16, 4, 2, 2, 1 );
+				//var geo = new THREE.IcosahedronBufferGeometry( 8, 0 );
+				var geo = new THREE.PlaneBufferGeometry( 16, 16, 2, 2 );
+
+				var geometry = new THREE.WireframeGeometry2( geo );
+
+				var material = new THREE.LineMaterial( {
+
+					color: 0x4080ff,
+					linewidth: 10, // in pixels
+					//resolution:  // to be set by renderer, eventually
+
+				} );
+
+				wireframe = new THREE.Wireframe( geometry, material );
+				wireframe.scale.set( 1, 1, 1 );
+				scene.add( wireframe );
+
+
+				// THREE.Line ( WireframeGeometry, LineBasicMaterial ) - rendered with gl.LINE
+
+				geo = new THREE.WireframeGeometry( geo );
+
+				var mat = new THREE.LineBasicMaterial( { color: 0x4080ff } );
+
+				wireframe1 = new THREE.LineSegments( geo, mat );
+				wireframe1.visible = false;
+				scene.add( wireframe1 );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+				onWindowResize();
+
+				stats = new Stats();
+				document.body.appendChild( stats.dom );
+
+				initGui();
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				insetWidth = window.innerWidth / 4;
+				insetHeight = window.innerHeight / 4;
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				stats.update();
+
+				wireframe.geometry.maxInstancedCount = Math.floor( Date.now() / 1000 ) % wireframe.geometry.index.count - 1; // why - 1 needed ?
+
+				// main scene
+
+				// renderer will set this eventually
+				line.material.resolution.set( window.innerWidth, window.innerHeight );
+				wireframe.material.resolution.set( window.innerWidth, window.innerHeight );
+
+				renderer.setViewport( 0, 0, window.innerWidth, window.innerHeight );
+
+				renderer.render( scene, camera );
+
+				// inset scene
+
+				// renderer will set this eventually
+				//line.material.resolution.set( insetWidth, insetHeight );
+				//wireframe.material.resolution.set( insetWidth, insetHeight );
+
+				renderer.clearDepth(); // important!
+
+				renderer.setScissorTest( true );
+				renderer.setScissor( 20, 20, insetWidth, insetHeight );
+
+				renderer.setViewport( 20, 20, insetWidth, insetHeight );
+
+				renderer.render( scene, camera );
+
+				renderer.setScissorTest( false );
+
+			}
+
+			//
+
+			function initGui() {
+
+				gui = new dat.GUI();
+
+				var param = {
+					'line type': 0,
+					'line width': 10
+				};
+
+
+				gui.add( param, 'line type', { 'LineGeometry': 0, 'gl.LINE': 1 } ).onChange( function ( val ) {
+
+					switch ( val ) {
+
+						case '0':
+							line.visible = true;
+							wireframe.visible = true;
+
+							line1.visible = false;
+							wireframe1.visible = false;
+
+							break;
+
+						case '1':
+							line.visible = false;
+							wireframe.visible = false;
+
+							line1.visible = true;
+							wireframe1.visible = true;
+
+							break;
+
+					}
+
+				} );
+
+				gui.add( param, 'line width', 1, 40, 1 ).onChange( function ( val ) {
+
+					line.material.linewidth = val;
+					wireframe.material.linewidth = val;
+
+				} );
+
+			}
+
+		</script>
+
+	</body>
+
+</html>