webgl_geometry_teapot.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>three.js webgl - teapot geometry</title>
  5. <meta charset="utf-8">
  6. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  7. <style>
  8. body {
  9. color: #fff;
  10. font-family: Monospace;
  11. font-size: 13px;
  12. text-align: center;
  13. font-weight: bold;
  14. background-color: #000;
  15. margin: 0px;
  16. overflow: hidden;
  17. }
  18. #info {
  19. position: relative;
  20. margin: 0 auto -2.1em;
  21. top: 0px;
  22. width: 550px;
  23. padding: 5px;
  24. z-index:100;
  25. }
  26. a { color: blue; }
  27. #stats #fps { background: transparent !important }
  28. #stats #fps #fpsText { color: #444 !important }
  29. #stats #fps #fpsGraph { display: none }
  30. </style>
  31. </head>
  32. <body>
  33. <div id="info">
  34. <a href="http://threejs.org" target="_blank">three.js</a> - the Utah Teapot from the <a href="https://www.udacity.com/course/interactive-3d-graphics--cs291">Udacity Interactive 3D Graphics course</a>
  35. </div>
  36. <script src="../build/three.min.js"></script>
  37. <script src="js/controls/OrbitControls.js"></script>
  38. <script src="js/Detector.js"></script>
  39. <script src="js/libs/stats.min.js"></script>
  40. <script src='js/libs/dat.gui.min.js'></script>
  41. <script src='js/geometries/TeapotGeometry.js'></script>
  42. <script>
  43. ////////////////////////////////////////////////////////////////////////////////
  44. // Utah/Newell Teapot demo
  45. ////////////////////////////////////////////////////////////////////////////////
  46. /*global THREE, requestAnimationFrame, Detector, container, Stats, dat, window */
  47. if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
  48. var camera, scene, sceneCube, renderer, stats;
  49. var cameraControls;
  50. var effectController;
  51. var clock = new THREE.Clock();
  52. var teapotSize = 400;
  53. var ambientLight, light;
  54. var skybox;
  55. var tess = -1; // force initialization
  56. var bBottom ;
  57. var bLid;
  58. var bBody;
  59. var bFitLid;
  60. var bNonBlinn;
  61. var shading;
  62. var wireMaterial, flatGouraudMaterial, gouraudMaterial, phongMaterial, texturedMaterial, reflectiveMaterial;
  63. init();
  64. animate();
  65. function init() {
  66. container = document.createElement( 'div' );
  67. document.body.appendChild( container );
  68. var canvasWidth = window.innerWidth;
  69. var canvasHeight = window.innerHeight;
  70. // CAMERA
  71. camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 80000 );
  72. camera.position.set( -600, 550, 1300 );
  73. // LIGHTS
  74. ambientLight = new THREE.AmbientLight( 0x333333 ); // 0.2
  75. light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 );
  76. // direction is set in GUI
  77. // RENDERER
  78. renderer = new THREE.WebGLRenderer( { antialias: true } );
  79. renderer.setSize( canvasWidth, canvasHeight );
  80. renderer.setClearColor( 0xAAAAAA );
  81. renderer.gammaInput = true;
  82. renderer.gammaOutput = true;
  83. container.appendChild( renderer.domElement );
  84. // STATS
  85. stats = new Stats();
  86. stats.domElement.style.position = 'absolute';
  87. stats.domElement.style.top = '0px';
  88. container.appendChild( stats.domElement );
  89. // EVENTS
  90. window.addEventListener( 'resize', onWindowResize, false );
  91. // CONTROLS
  92. cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
  93. cameraControls.target.set(0, 0, 0);
  94. // TEXTURE MAP
  95. var textureMap = THREE.ImageUtils.loadTexture( 'textures/UV_Grid_Sm.jpg' );
  96. textureMap.wrapS = textureMap.wrapT = THREE.RepeatWrapping;
  97. textureMap.anisotropy = 16;
  98. // REFLECTION MAP
  99. var path = "textures/cube/skybox/";
  100. var urls = [path + "px.jpg", path + "nx.jpg",
  101. path + "py.jpg", path + "ny.jpg",
  102. path + "pz.jpg", path + "nz.jpg" ];
  103. var textureCube = THREE.ImageUtils.loadTextureCube( urls );
  104. // MATERIALS
  105. var materialColor = new THREE.Color();
  106. materialColor.setRGB( 1.0, 1.0, 1.0 );
  107. wireMaterial = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe: true } ) ;
  108. flatGouraudMaterial = new THREE.MeshLambertMaterial( { color: materialColor, shading: THREE.FlatShading, side: THREE.DoubleSide } );
  109. gouraudMaterial = new THREE.MeshLambertMaterial( { color: materialColor, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
  110. phongMaterial = new THREE.MeshPhongMaterial( { color: materialColor, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
  111. texturedMaterial = new THREE.MeshPhongMaterial( { color: materialColor, map: textureMap, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
  112. reflectiveMaterial = new THREE.MeshPhongMaterial( { color: materialColor, envMap: textureCube, shading: THREE.SmoothShading, side: THREE.DoubleSide } );
  113. // SKYBOX
  114. var shader = THREE.ShaderLib[ "cube" ];
  115. shader.uniforms[ "tCube" ].value = textureCube;
  116. var skyboxMaterial = new THREE.ShaderMaterial( {
  117. fragmentShader: shader.fragmentShader,
  118. vertexShader: shader.vertexShader,
  119. uniforms: shader.uniforms,
  120. depthWrite: false,
  121. side: THREE.BackSide
  122. } );
  123. skybox = new THREE.Mesh( new THREE.BoxGeometry( 5000, 5000, 5000 ), skyboxMaterial );
  124. // skybox scene - keep camera centered here
  125. sceneCube = new THREE.Scene();
  126. sceneCube.add( skybox );
  127. // GUI
  128. setupGui();
  129. }
  130. // EVENT HANDLERS
  131. function onWindowResize() {
  132. var canvasWidth = window.innerWidth;
  133. var canvasHeight = window.innerHeight;
  134. renderer.setSize( canvasWidth, canvasHeight );
  135. camera.aspect = canvasWidth/ canvasHeight;
  136. camera.updateProjectionMatrix();
  137. }
  138. function setupGui() {
  139. effectController = {
  140. shininess: 40.0,
  141. ka: 0.17,
  142. kd: 0.51,
  143. ks: 0.2,
  144. metallic: true,
  145. hue: 0.121,
  146. saturation: 0.73,
  147. lightness: 0.66,
  148. lhue: 0.04,
  149. lsaturation: 0.01, // non-zero so that fractions will be shown
  150. llightness: 1.0,
  151. // bizarrely, if you initialize these with negative numbers, the sliders
  152. // will not show any decimal places.
  153. lx: 0.32,
  154. ly: 0.39,
  155. lz: 0.7,
  156. newTess: 15,
  157. bottom: true,
  158. lid: true,
  159. body: true,
  160. fitLid: false,
  161. nonblinn: false,
  162. newShading: "glossy"
  163. };
  164. var h;
  165. var gui = new dat.GUI();
  166. // material (attributes)
  167. h = gui.addFolder( "Material control" );
  168. h.add( effectController, "shininess", 1.0, 400.0, 1.0 ).name("Shininess");
  169. h.add( effectController, "ka", 0.0, 1.0, 0.025 ).name("Ka");
  170. h.add( effectController, "kd", 0.0, 1.0, 0.025 ).name("Kd");
  171. h.add( effectController, "ks", 0.0, 1.0, 0.025 ).name("Ks");
  172. h.add( effectController, "metallic" );
  173. // material (color)
  174. h = gui.addFolder( "Material color" );
  175. h.add( effectController, "hue", 0.0, 1.0, 0.025 ).name("Hue");
  176. h.add( effectController, "saturation", 0.0, 1.0, 0.025 ).name("Saturation");
  177. h.add( effectController, "lightness", 0.0, 1.0, 0.025 ).name("Lightness");
  178. // light (point)
  179. h = gui.addFolder( "Light color" );
  180. h.add( effectController, "lhue", 0.0, 1.0, 0.025 ).name("Hue");
  181. h.add( effectController, "lsaturation", 0.0, 1.0, 0.025 ).name("Saturation");
  182. h.add( effectController, "llightness", 0.0, 1.0, 0.025 ).name("Lightness");
  183. // light (directional)
  184. h = gui.addFolder( "Light direction" );
  185. h.add( effectController, "lx", -1.0, 1.0, 0.025 ).name("x");
  186. h.add( effectController, "ly", -1.0, 1.0, 0.025 ).name("y");
  187. h.add( effectController, "lz", -1.0, 1.0, 0.025 ).name("z");
  188. h = gui.addFolder( "Tessellation control" );
  189. h.add(effectController, "newTess", [2,3,4,5,6,8,10,15,20,30,40,50] ).name("Tessellation Level");
  190. h.add(effectController, "lid").name("display lid");
  191. h.add(effectController, "body").name("display body");
  192. h.add(effectController, "bottom").name("display bottom");
  193. h.add(effectController, "fitLid").name("snug lid");
  194. h.add(effectController, "nonblinn").name("original scale");
  195. // shading
  196. h = gui.add(effectController, "newShading", ["wireframe","flat","smooth","glossy","textured","reflective"] ).name("Shading");
  197. }
  198. //
  199. function animate() {
  200. requestAnimationFrame( animate );
  201. render();
  202. stats.update();
  203. }
  204. function render() {
  205. var delta = clock.getDelta();
  206. cameraControls.update( delta );
  207. if ( effectController.newTess !== tess ||
  208. effectController.bottom !== bBottom ||
  209. effectController.lid !== bLid ||
  210. effectController.body !== bBody ||
  211. effectController.fitLid !== bFitLid ||
  212. effectController.nonblinn !== bNonBlinn ||
  213. effectController.newShading !== shading)
  214. {
  215. tess = effectController.newTess;
  216. bBottom = effectController.bottom;
  217. bLid = effectController.lid;
  218. bBody = effectController.body;
  219. bFitLid = effectController.fitLid;
  220. bNonBlinn = effectController.nonblinn;
  221. shading = effectController.newShading;
  222. fillScene();
  223. }
  224. phongMaterial.shininess = effectController.shininess;
  225. texturedMaterial.shininess = effectController.shininess;
  226. var diffuseColor = new THREE.Color();
  227. diffuseColor.setHSL( effectController.hue, effectController.saturation, effectController.lightness );
  228. var specularColor = new THREE.Color();
  229. if ( effectController.metallic )
  230. {
  231. // make colors match to give a more metallic look
  232. specularColor.copy( diffuseColor );
  233. }
  234. else
  235. {
  236. // more of a plastic look
  237. specularColor.setRGB(1,1,1);
  238. }
  239. diffuseColor.multiplyScalar(effectController.kd);
  240. flatGouraudMaterial.color.copy( diffuseColor );
  241. gouraudMaterial.color.copy( diffuseColor );
  242. phongMaterial.color.copy( diffuseColor );
  243. texturedMaterial.color.copy( diffuseColor );
  244. specularColor.multiplyScalar(effectController.ks);
  245. phongMaterial.specular.copy( specularColor );
  246. texturedMaterial.specular.copy( specularColor );
  247. // Ambient's actually controlled by the light for this demo
  248. ambientLight.color.setHSL( effectController.hue, effectController.saturation, effectController.lightness * effectController.ka );
  249. light.position.set( effectController.lx, effectController.ly, effectController.lz );
  250. light.color.setHSL( effectController.lhue, effectController.lsaturation, effectController.llightness );
  251. // skybox is rendered separately, so that it is always behind the teapot.
  252. if ( shading === "reflective" )
  253. {
  254. // clear to skybox
  255. renderer.autoClear = false;
  256. skybox.position.copy( camera.position );
  257. renderer.render( sceneCube, camera );
  258. }
  259. else
  260. {
  261. // clear to regular background color
  262. renderer.autoClear = true;
  263. }
  264. renderer.render( scene, camera );
  265. }
  266. function fillScene() {
  267. scene = new THREE.Scene();
  268. //scene.fog = new THREE.Fog( 0x808080, 2000, 4000 );
  269. // LIGHTS
  270. scene.add( ambientLight );
  271. scene.add( light );
  272. var teapot = new THREE.Mesh(
  273. new THREE.TeapotGeometry( teapotSize,
  274. tess,
  275. effectController.bottom,
  276. effectController.lid,
  277. effectController.body,
  278. effectController.fitLid,
  279. !effectController.nonblinn ),
  280. shading === "wireframe" ? wireMaterial : (
  281. shading === "flat" ? flatGouraudMaterial : (
  282. shading === "smooth" ? gouraudMaterial : (
  283. shading === "glossy" ? phongMaterial : (
  284. shading === "textured" ? texturedMaterial : reflectiveMaterial ))))); // if no match, pick Phong
  285. scene.add( teapot );
  286. }
  287. </script>
  288. </body>
  289. </html>