Explorar el Código

Merge pull request #5375 from TatumCreative/materials

Documentation: Materials browser
Mr.doob hace 10 años
padre
commit
2adb583342

+ 5 - 4
docs/api/materials/Material.html

@@ -53,14 +53,15 @@
 		</div>
 		<div>Default is *false*.</div>
 
-		<h3>[property:Blending blending]</h3>
+		<h3>.[page:Blending blending]</h3>
 		<div>
-		Which blending to use when displaying objects with this material. Default is [page:Materials NormalBlending].
+		Which blending to use when displaying objects with this material. Default is [page:Materials NormalBlending]. See the blending mode [page:Materials constants] for all possible values.
+
 		</div>
 
-		<h3>[property:Integer blendSrc]</h3>
+		<h3>.[page:Integer blendSrc]</h3>
 		<div>
-		Blending source. It's one of the blending mode constants defined in [page:Three Three.js]. Default is [page:CustomBlendingEquation SrcAlphaFactor]
+		Blending source. It's one of the blending mode constants defined in Three.js. Default is [page:CustomBlendingEquation SrcAlphaFactor]. See the destination factors [page:CustomBlendingEquation constants] for all possible values.
 		</div>
 
 		<h3>[property:Integer blendDst]</h3>

+ 1 - 0
docs/api/materials/MeshBasicMaterial.html

@@ -14,6 +14,7 @@
 		<div class="desc">A material for drawing geometries in a simple shaded (flat or wireframe) way.</div>
 		<div class="desc">The default will render as flat polygons. To draw the mesh as wireframe, simply set the 'wireframe' property to true.</div>
 
+		<iframe src='../../scenes/material-browser.html#MeshBasicMaterial'></iframe>
 
 		<h2>Constructor</h2>
 

+ 2 - 0
docs/api/materials/MeshDepthMaterial.html

@@ -12,6 +12,8 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A material for drawing geometry by depth. Depth is based off of the camera near and far plane. White is nearest, black is farthest.</div>
+		
+		<iframe src='../../scenes/material-browser.html#MeshDepthMaterial'></iframe>
 
 		<h2>Constructor</h2>
 

+ 1 - 1
docs/api/materials/MeshFaceMaterial.html

@@ -10,7 +10,7 @@
 		<h1>[name]</h1>
 
 		<div class="desc">
-		A Material to define multiple materials for the same geometry.
+		A Material to define multiple materials for the same geometry. 
 		The geometry decides which material is used for which faces by the [page:Face3 faces materialindex].
 		The materialindex corresponds with the index of the material in the materials array.
 		</div>

+ 2 - 1
docs/api/materials/MeshLambertMaterial.html

@@ -12,7 +12,8 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A material for non-shiny (Lambertian) surfaces, evaluated per vertex.</div>
-
+		
+		<iframe src='../../scenes/material-browser.html#MeshLambertMaterial'></iframe>
 
 		<h2>Constructor</h2>
 

+ 2 - 0
docs/api/materials/MeshNormalMaterial.html

@@ -12,6 +12,8 @@
 		<h1>[name]</h1>
 
 		<div class="desc">A material that maps the normal vectors to RGB colors.</div>
+		
+		<iframe src='../../scenes/material-browser.html#MeshNormalMaterial'></iframe>
 
 
 		<h2>Constructor</h2>

+ 1 - 0
docs/api/materials/MeshPhongMaterial.html

@@ -13,6 +13,7 @@
 
 		<div class="desc">A material for shiny surfaces, evaluated per pixel.</div>
 
+		<iframe src='../../scenes/material-browser.html#MeshPhongMaterial'></iframe>
 
 		<h2>Constructor</h2>
 

+ 5 - 1
docs/page.css

@@ -66,7 +66,11 @@ code {
 	overflow: auto;
 }
 
-
+iframe {
+	width: 100%;
+	height: 420px;
+	border:0;
+}
 
 th {
 	padding: 10px;

+ 535 - 0
docs/scenes/js/material.js

@@ -0,0 +1,535 @@
+/**
+ * @author TatumCreative (Greg Tatum) / http://gregtatum.com/
+ */
+
+var constants = {
+	
+	combine: {
+		
+		"THREE.MultiplyOperation" : THREE.MultiplyOperation,
+		"THREE.MixOperation" : THREE.MixOperation,
+		"THREE.AddOperation" : THREE.AddOperation
+		
+	},
+	
+	side : {
+		
+		"THREE.FrontSide" : THREE.FrontSide,
+		"THREE.BackSide" : THREE.BackSide,
+		"THREE.DoubleSide" : THREE.DoubleSide
+		
+	},
+	
+	shading : {
+		
+		"THREE.NoShading" : THREE.NoShading,
+		"THREE.FlatShading" : THREE.FlatShading,
+		"THREE.SmoothShading" : THREE.SmoothShading
+		
+	},
+
+	colors : {
+		
+		"THREE.NoColors" : THREE.NoColors,
+		"THREE.FaceColors" : THREE.FaceColors,
+		"THREE.VertexColors" : THREE.VertexColors
+		
+	},
+	
+	blendingMode : {
+		
+		"THREE.NoBlending" : THREE.NoBlending,
+		"THREE.NormalBlending" : THREE.NormalBlending,
+		"THREE.AdditiveBlending" : THREE.AdditiveBlending,
+		"THREE.SubtractiveBlending" : THREE.SubtractiveBlending,
+		"THREE.MultiplyBlending" : THREE.MultiplyBlending,
+		"THREE.CustomBlending" : THREE.CustomBlending
+		
+	},
+	
+	equations : {
+		
+		"THREE.AddEquation" : THREE.AddEquation,
+		"THREE.SubtractEquation" : THREE.SubtractEquation,
+		"THREE.ReverseSubtractEquation" : THREE.ReverseSubtractEquation
+		
+	},
+	
+	destinationFactors : {
+		
+		"THREE.ZeroFactor" : THREE.ZeroFactor,
+		"THREE.OneFactor" : THREE.OneFactor,
+		"THREE.SrcColorFactor" : THREE.SrcColorFactor,
+		"THREE.OneMinusSrcColorFactor" : THREE.OneMinusSrcColorFactor,
+		"THREE.SrcAlphaFactor" : THREE.SrcAlphaFactor,
+		"THREE.OneMinusSrcAlphaFactor" : THREE.OneMinusSrcAlphaFactor,
+		"THREE.DstAlphaFactor" : THREE.DstAlphaFactor,
+		"THREE.OneMinusDstAlphaFactor" : THREE.OneMinusDstAlphaFactor
+		
+	},
+	
+	sourceFactors : {
+		
+		"THREE.DstColorFactor" : THREE.DstColorFactor,
+		"THREE.OneMinusDstColorFactor" : THREE.OneMinusDstColorFactor,
+		"THREE.SrcAlphaSaturateFactor" : THREE.SrcAlphaSaturateFactor
+		
+	}
+	
+}
+
+function getObjectsKeys( obj ) {
+	
+	var keys = [];
+	
+	for ( var key in obj ) {
+		
+		if ( obj.hasOwnProperty( key ) ) {
+			
+			keys.push( key );
+			
+		}
+		
+	}
+	
+	return keys;
+}
+
+var envMaps = (function () {
+	
+	var path = "../../examples/textures/cube/SwedishRoyalCastle/";
+	var format = '.jpg';
+	var urls = [
+		path + 'px' + format, path + 'nx' + format,
+		path + 'py' + format, path + 'ny' + format,
+		path + 'pz' + format, path + 'nz' + format
+	];
+
+	var textureCube = THREE.ImageUtils.loadTextureCube( urls, new THREE.CubeRefractionMapping() );
+	var reflectionCube = THREE.ImageUtils.loadTextureCube( urls );
+	reflectionCube.format = THREE.RGBFormat;
+
+	var refractionCube = new THREE.Texture( reflectionCube.image, new THREE.CubeRefractionMapping() );
+	reflectionCube.format = THREE.RGBFormat;
+	
+	return {
+		none : null,
+		reflection : reflectionCube,
+		refraction : refractionCube
+	};
+	
+})();
+
+var envMapKeys = getObjectsKeys( envMaps );
+
+var textureMaps = (function () {
+	
+	return {
+		none : null,
+		grass : THREE.ImageUtils.loadTexture( "../../examples/textures/terrain/grasslight-thin.jpg" )
+	};
+	
+})();
+
+var textureMapKeys = getObjectsKeys( textureMaps );
+
+function generateVertexColors ( geometry ) {
+	
+	for ( var i=0, il = geometry.faces.length; i < il; i++ ) {
+				
+		geometry.faces[i].vertexColors.push( new THREE.Color().setHSL(
+			i / il * Math.random(),
+			0.5,
+			0.5
+		) );
+		geometry.faces[i].vertexColors.push( new THREE.Color().setHSL(
+			i / il * Math.random(),
+			0.5,
+			0.5
+		) );
+		geometry.faces[i].vertexColors.push( new THREE.Color().setHSL(
+			i / il * Math.random(),
+			0.5,
+			0.5
+		) );
+		
+		geometry.faces[i].color = new THREE.Color().setHSL(
+			i / il * Math.random(),
+			0.5,
+			0.5
+		);
+		
+	}
+	
+}
+
+function generateMorphTargets ( mesh, geometry ) {
+
+	var vertices = [], scale;
+
+	for ( var i = 0; i < geometry.vertices.length; i++ ) {
+
+		vertices.push( geometry.vertices[ i ].clone() );
+
+		scale = 1 + Math.random() * 0.3;
+		
+		vertices[ vertices.length - 1 ].x *= scale;
+		vertices[ vertices.length - 1 ].y *= scale;
+		vertices[ vertices.length - 1 ].z *= scale;
+
+	}
+
+	geometry.morphTargets.push( { name: "target1", vertices: vertices } );
+	
+	geometry.update
+
+}
+
+function handleColorChange ( color ) {
+	
+	return function ( value ){
+		
+		if (typeof value === "string") {
+			
+			value = value.replace('#', '0x');
+			
+		}
+		
+		color.setHex( value );
+		
+    };
+	
+}
+
+function needsUpdate ( material, geometry ) {
+	
+	return function () {
+		
+		material.shading = +material.shading; //Ensure number
+		material.vertexColors = +material.vertexColors; //Ensure number
+		material.side = +material.side; //Ensure number
+		material.needsUpdate = true;
+		geometry.verticesNeedUpdate = true;
+		geometry.normalsNeedUpdate = true;
+		geometry.colorsNeedUpdate = true;
+		
+	};
+	
+};
+
+function updateMorphs ( torus, material ) {
+
+	return function () {
+		
+		torus.updateMorphTargets();
+		material.needsUpdate = true;
+		
+	};
+	
+}
+
+function updateTexture ( material, materialKey, textures ) {
+
+	return function ( key ) {
+		
+		material[materialKey] = textures[key];
+		material.needsUpdate = true;
+		
+	};
+	
+}
+
+function guiScene ( gui, scene ) {
+	
+	var folder = gui.addFolder('Scene');
+	
+	var data = {
+		background : "#000000",
+		"ambient light" : ambientLight.color.getHex()
+	}
+	
+	var color = new THREE.Color();
+	var colorConvert = handleColorChange( color );
+	
+	folder.addColor( data, "background" ).onChange( function ( value ) {
+		
+		colorConvert( value );
+		
+		renderer.setClearColor(color.getHex(), 1);
+		
+	} );
+	
+	folder.addColor( data, "ambient light" ).onChange( handleColorChange( ambientLight.color ) )
+	
+	guiSceneFog( folder, scene );
+	
+}
+
+function guiSceneFog ( folder, scene ) {
+	
+	var fogFolder = folder.addFolder('scene.fog');
+	
+	var fog = new THREE.Fog( 0x3f7b9d, 0, 60 );
+
+	var data = {
+		fog : {
+			"THREE.Fog()" : false,
+			"scene.fog.color" : fog.color.getHex()
+		}
+	};
+	
+	fogFolder.add( data.fog, 'THREE.Fog()' ).onChange( function ( useFog ) {
+		
+		if ( useFog ) {
+			
+			scene.fog = fog;
+			
+		} else {
+			
+			scene.fog = null;
+			
+		}
+		
+	} );
+	
+	fogFolder.addColor( data.fog, 'scene.fog.color').onChange( handleColorChange( fog.color ) );
+	
+}
+
+function guiMaterial ( gui, mesh, material, geometry ) {
+	
+	var folder = gui.addFolder('THREE.Material');
+	
+	folder.add( material, 'transparent' );
+	folder.add( material, 'opacity', 0, 1 );
+	// folder.add( material, 'blending', constants.blendingMode );
+	// folder.add( material, 'blendSrc', constants.destinationFactors );
+	// folder.add( material, 'blendDst', constants.destinationFactors );
+	// folder.add( material, 'blendEquation', constants.equations );
+	folder.add( material, 'depthTest' );
+	folder.add( material, 'depthWrite' );
+	// folder.add( material, 'polygonOffset' );
+	// folder.add( material, 'polygonOffsetFactor' );
+	// folder.add( material, 'polygonOffsetUnits' );
+	folder.add( material, 'alphaTest', 0, 1 );
+	// folder.add( material, 'overdraw', 0, 5 );
+	folder.add( material, 'visible' );
+	folder.add( material, 'side', constants.side ).onChange( needsUpdate( material, geometry ) );
+	
+}
+
+function guiMeshBasicMaterial ( gui, mesh, material, geometry ) {
+	
+	var data = {
+		color : material.color.getHex(),
+		envMaps : envMapKeys,
+		map : textureMapKeys,
+		lightMap : textureMapKeys,
+		specularMap : textureMapKeys,
+		alphaMap : textureMapKeys
+	};
+		
+	var folder = gui.addFolder('THREE.MeshBasicMaterial');
+
+	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
+	folder.add( material, 'wireframe' );
+	folder.add( material, 'wireframeLinewidth', 0, 10 );
+	folder.add( material, 'shading', constants.shading);
+	folder.add( material, 'vertexColors', constants.colors).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'fog' );
+	
+	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
+	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
+	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
+	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
+	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
+	folder.add( material, 'combine', constants.combine ).onChange( updateMorphs( mesh, material ) );
+	folder.add( material, 'reflectivity', 0, 1 );
+	folder.add( material, 'refractionRatio', 0, 1 );
+	//folder.add( material, 'skinning' );
+	
+}
+
+function guiMeshDepthMaterial ( gui, mesh, material, geometry ) {
+	
+	var folder = gui.addFolder('THREE.MeshDepthMaterial');
+		
+	folder.add( material, 'wireframe' );
+	folder.add( material, 'wireframeLinewidth', 0, 10 );
+	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
+	
+}
+
+function guiMeshNormalMaterial ( gui, mesh, material, geometry ) {
+	
+	var folder = gui.addFolder('THREE.MeshNormalMaterial');
+	
+	folder.add( material, 'shading', constants.shading).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'wireframe' );
+	folder.add( material, 'wireframeLinewidth', 0, 10 );
+	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
+	
+}
+
+function guiLineBasicMaterial ( gui, mesh, material, geometry ) {
+	
+	var data = {
+		color : material.color.getHex()
+	};
+		
+	var folder = gui.addFolder('THREE.LineBasicMaterial');
+
+	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
+	folder.add( material, 'linewidth', 0, 10 );
+	folder.add( material, 'linecap', ["butt", "round", "square"] );
+	folder.add( material, 'linejoin', ["round", "bevel", "miter"] );
+	folder.add( material, 'vertexColors', constants.colors).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'fog' );
+	
+}
+
+function guiMeshLambertMaterial ( gui, mesh, material, geometry ) {
+	
+	var data = {
+		color : material.color.getHex(),
+		ambient : material.ambient.getHex(),
+		emissive : material.emissive.getHex(),
+		envMaps : envMapKeys,
+		map : textureMapKeys,
+		lightMap : textureMapKeys,
+		specularMap : textureMapKeys,
+		alphaMap : textureMapKeys
+	};
+	
+	var envObj = {};
+			
+	var folder = gui.addFolder('THREE.MeshLambertMaterial');
+
+	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
+	folder.addColor( data, 'ambient' ).onChange( handleColorChange( material.ambient ) );
+	folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) );
+	
+	folder.add( material, 'shading', constants.shading ).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'wireframe' );
+	folder.add( material, 'wireframeLinewidth', 0, 10 );
+	folder.add( material, 'vertexColors', constants.colors ).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'fog' );
+
+	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
+	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
+	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
+	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
+	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	folder.add( material, 'morphTargets' ).onChange( updateMorphs( mesh, material ) );
+	folder.add( material, 'combine', constants.combine ).onChange( updateMorphs( mesh, material ) );
+	folder.add( material, 'reflectivity', 0, 1 );
+	folder.add( material, 'refractionRatio', 0, 1 );
+	//folder.add( material, 'skinning' );
+	
+}
+
+function guiMeshPhongMaterial ( gui, mesh, material, geometry ) {
+	
+	var data = {
+		color : material.color.getHex(),
+		ambient : material.ambient.getHex(),
+		emissive : material.emissive.getHex(),
+		specular : material.specular.getHex(),
+		envMaps : envMapKeys,
+		map : textureMapKeys,
+		lightMap : textureMapKeys,
+		specularMap : textureMapKeys,
+		alphaMap : textureMapKeys
+	};
+		
+	var folder = gui.addFolder('THREE.MeshPhongMaterial');
+
+	folder.addColor( data, 'color' ).onChange( handleColorChange( material.color ) );
+	folder.addColor( data, 'ambient' ).onChange( handleColorChange( material.ambient ) );
+	folder.addColor( data, 'emissive' ).onChange( handleColorChange( material.emissive ) );
+	folder.addColor( data, 'specular' ).onChange( handleColorChange( material.specular ) );
+
+	folder.add( material, 'shininess', 0, 100);
+	folder.add( material, 'shading', constants.shading).onChange( needsUpdate( material, geometry ) );
+	folder.add( material, 'wireframe' );
+	folder.add( material, 'wireframeLinewidth', 0, 10 );
+	folder.add( material, 'vertexColors', constants.colors);
+	folder.add( material, 'fog' );
+	folder.add( data, 'envMaps', envMapKeys ).onChange( updateTexture( material, 'envMap', envMaps ) );
+	folder.add( data, 'map', textureMapKeys ).onChange( updateTexture( material, 'map', textureMaps ) );
+	folder.add( data, 'lightMap', textureMapKeys ).onChange( updateTexture( material, 'lightMap', textureMaps ) );
+	folder.add( data, 'specularMap', textureMapKeys ).onChange( updateTexture( material, 'specularMap', textureMaps ) );
+	folder.add( data, 'alphaMap', textureMapKeys ).onChange( updateTexture( material, 'alphaMap', textureMaps ) );
+	
+}
+
+function chooseFromHash ( gui, mesh, geometry ) {
+
+	var selectedMaterial = window.location.hash.substring(1) || "MeshBasicMaterial";
+	var material;
+	
+	switch (selectedMaterial) {
+		
+	case "MeshBasicMaterial" :
+
+		material = new THREE.MeshBasicMaterial({color: 0x2194CE});
+		guiMaterial( gui, mesh, material, geometry );
+		guiMeshBasicMaterial( gui, mesh, material, geometry );
+
+		return material;
+
+		break;
+	
+	case "MeshLambertMaterial" :
+
+		material = new THREE.MeshLambertMaterial({color: 0x2194CE});
+		guiMaterial( gui, mesh, material, geometry );
+		guiMeshLambertMaterial( gui, mesh, material, geometry );
+
+		return material;
+
+		break;
+	
+	case "MeshPhongMaterial" :
+
+		material = new THREE.MeshPhongMaterial({color: 0x2194CE});
+		guiMaterial( gui, mesh, material, geometry );
+		guiMeshPhongMaterial( gui, mesh, material, geometry );
+
+		return material;
+
+		break;
+	
+	case "MeshDepthMaterial" :
+		
+		material = new THREE.MeshDepthMaterial({color: 0x2194CE});
+		guiMaterial( gui, mesh, material, geometry );
+		guiMeshDepthMaterial( gui, mesh, material, geometry );
+
+		return material;
+		
+		break;
+	
+	case "MeshNormalMaterial" :
+		
+		material = new THREE.MeshNormalMaterial();
+		guiMaterial( gui, mesh, material, geometry );
+		guiMeshNormalMaterial( gui, mesh, material, geometry );
+
+		return material;
+		
+		break;
+		
+	case "LineBasicMaterial" :
+
+		material = new THREE.LineBasicMaterial({color: 0x2194CE});
+		guiMaterial( gui, mesh, material, geometry );
+		guiLineBasicMaterial( gui, mesh, material, geometry );
+
+		return material;
+
+		break;
+	}
+	
+}

+ 123 - 0
docs/scenes/material-browser.html

@@ -0,0 +1,123 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<title>Three.js Material Browser</title>
+		<style>
+			@font-face {
+				font-family: 'inconsolata';
+				src: url('../files/inconsolata.woff') format('woff');
+				font-weight: normal;
+				font-style: normal;
+			}
+			
+			body {
+				margin:0;
+				font-family: 'inconsolata';
+				font-size: 15px;
+				line-height: 18px;
+			}
+			
+			canvas { width: 100%; height: 100% }
+			
+			#newWindow {
+				display:block;
+				position:absolute;
+				bottom:0.3em;
+				left:0.5em;
+				color:#fff;
+			}
+		</style>
+	</head>
+	<body>
+		
+		<a id='newWindow' href='./material-browser.html' target='_blank'>Open in New Window</a>
+		
+		<script src="../../build/three.min.js"></script>
+		<script src='../../examples/js/libs/dat.gui.min.js'></script>
+		<script src='js/material.js'></script>
+		
+		<script>
+			
+			document.getElementById('newWindow').href += window.location.hash;
+			
+			var gui = new dat.GUI();
+			var scene = new THREE.Scene();
+			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 50 );
+			camera.position.z = 30;
+			
+			var renderer = new THREE.WebGLRenderer();
+			renderer.setSize( window.innerWidth, window.innerHeight );
+			document.body.appendChild( renderer.domElement );
+
+			var ambientLight = new THREE.AmbientLight( 0x000000 );
+			scene.add( ambientLight );
+
+			var lights = [];
+			lights[0] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[1] = new THREE.PointLight( 0xffffff, 1, 0 );
+			lights[2] = new THREE.PointLight( 0xffffff, 1, 0 );
+			
+			lights[0].position.set( 0, 200, 0 );
+			lights[1].position.set( 100, 200, 100 );
+			lights[2].position.set( -100, -200, -100 );
+
+			scene.add( lights[0] );
+			scene.add( lights[1] );
+			scene.add( lights[2] );
+
+			guiScene( gui, scene, camera );
+
+			var geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 );
+			var mesh = new THREE.Mesh( geometry );
+			
+			generateVertexColors( geometry );
+			
+			mesh.material = chooseFromHash( gui, mesh, geometry );
+
+			generateMorphTargets( mesh, geometry );
+
+			scene.add( mesh );
+			
+			var prevFog = false;
+			
+			var render = function () {
+				
+				requestAnimationFrame( render );
+
+				var time = Date.now() * 0.001;
+
+				mesh.rotation.x += 0.005;
+				mesh.rotation.y += 0.005;
+				
+				if ( prevFog !== scene.fog ) {
+					
+					mesh.material.needsUpdate = true;
+					prevFog = scene.fog;
+					
+				}
+				
+				if ( mesh.morphTargetInfluences ) {
+					
+					mesh.morphTargetInfluences[ 0 ] = ( 1 + Math.sin( 4 * time ) ) / 2;
+					
+				}
+
+				renderer.render( scene, camera );
+				
+			};
+			
+			window.addEventListener( 'resize', function () {
+				
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				
+			}, false );
+
+			render();
+			
+		</script>
+	</body>
+</html>

BIN
examples/textures/terrain/grasslight-thin.jpg