webgl_clipping.html 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>three.js webgl - clipping planes</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. <link type="text/css" rel="stylesheet" href="main.css">
  8. </head>
  9. <body>
  10. <script type="module">
  11. import {
  12. AmbientLight,
  13. DirectionalLight,
  14. DoubleSide,
  15. Mesh,
  16. MeshPhongMaterial,
  17. PerspectiveCamera,
  18. Plane,
  19. PlaneBufferGeometry,
  20. Scene,
  21. SpotLight,
  22. TorusKnotBufferGeometry,
  23. Vector3,
  24. WebGLRenderer
  25. } from "../build/three.module.js";
  26. import Stats from './jsm/libs/stats.module.js';
  27. import { GUI } from './jsm/libs/dat.gui.module.js';
  28. import { OrbitControls } from './jsm/controls/OrbitControls.js';
  29. var camera, scene, renderer, startTime, object, stats;
  30. init();
  31. animate();
  32. function init() {
  33. camera = new PerspectiveCamera( 36, window.innerWidth / window.innerHeight, 0.25, 16 );
  34. camera.position.set( 0, 1.3, 3 );
  35. scene = new Scene();
  36. // Lights
  37. scene.add( new AmbientLight( 0x505050 ) );
  38. var spotLight = new SpotLight( 0xffffff );
  39. spotLight.angle = Math.PI / 5;
  40. spotLight.penumbra = 0.2;
  41. spotLight.position.set( 2, 3, 3 );
  42. spotLight.castShadow = true;
  43. spotLight.shadow.camera.near = 3;
  44. spotLight.shadow.camera.far = 10;
  45. spotLight.shadow.mapSize.width = 1024;
  46. spotLight.shadow.mapSize.height = 1024;
  47. scene.add( spotLight );
  48. var dirLight = new DirectionalLight( 0x55505a, 1 );
  49. dirLight.position.set( 0, 3, 0 );
  50. dirLight.castShadow = true;
  51. dirLight.shadow.camera.near = 1;
  52. dirLight.shadow.camera.far = 10;
  53. dirLight.shadow.camera.right = 1;
  54. dirLight.shadow.camera.left = - 1;
  55. dirLight.shadow.camera.top = 1;
  56. dirLight.shadow.camera.bottom = - 1;
  57. dirLight.shadow.mapSize.width = 1024;
  58. dirLight.shadow.mapSize.height = 1024;
  59. scene.add( dirLight );
  60. // ***** Clipping planes: *****
  61. var localPlane = new Plane( new Vector3( 0, - 1, 0 ), 0.8 );
  62. var globalPlane = new Plane( new Vector3( - 1, 0, 0 ), 0.1 );
  63. // Geometry
  64. var material = new MeshPhongMaterial( {
  65. color: 0x80ee10,
  66. shininess: 100,
  67. side: DoubleSide,
  68. // ***** Clipping setup (material): *****
  69. clippingPlanes: [ localPlane ],
  70. clipShadows: true
  71. } );
  72. var geometry = new TorusKnotBufferGeometry( 0.4, 0.08, 95, 20 );
  73. object = new Mesh( geometry, material );
  74. object.castShadow = true;
  75. scene.add( object );
  76. var ground = new Mesh(
  77. new PlaneBufferGeometry( 9, 9, 1, 1 ),
  78. new MeshPhongMaterial( { color: 0xa0adaf, shininess: 150 } )
  79. );
  80. ground.rotation.x = - Math.PI / 2; // rotates X/Y to X/Z
  81. ground.receiveShadow = true;
  82. scene.add( ground );
  83. // Stats
  84. stats = new Stats();
  85. document.body.appendChild( stats.dom );
  86. // Renderer
  87. renderer = new WebGLRenderer();
  88. renderer.shadowMap.enabled = true;
  89. renderer.setPixelRatio( window.devicePixelRatio );
  90. renderer.setSize( window.innerWidth, window.innerHeight );
  91. window.addEventListener( 'resize', onWindowResize, false );
  92. document.body.appendChild( renderer.domElement );
  93. // ***** Clipping setup (renderer): *****
  94. var globalPlanes = [ globalPlane ],
  95. Empty = Object.freeze( [] );
  96. renderer.clippingPlanes = Empty; // GUI sets it to globalPlanes
  97. renderer.localClippingEnabled = true;
  98. // Controls
  99. var controls = new OrbitControls( camera, renderer.domElement );
  100. controls.target.set( 0, 1, 0 );
  101. controls.update();
  102. // GUI
  103. var gui = new GUI(),
  104. folderLocal = gui.addFolder( 'Local Clipping' ),
  105. propsLocal = {
  106. get 'Enabled'() {
  107. return renderer.localClippingEnabled;
  108. },
  109. set 'Enabled'( v ) {
  110. renderer.localClippingEnabled = v;
  111. },
  112. get 'Shadows'() {
  113. return material.clipShadows;
  114. },
  115. set 'Shadows'( v ) {
  116. material.clipShadows = v;
  117. },
  118. get 'Plane'() {
  119. return localPlane.constant;
  120. },
  121. set 'Plane'( v ) {
  122. localPlane.constant = v;
  123. }
  124. },
  125. folderGlobal = gui.addFolder( 'Global Clipping' ),
  126. propsGlobal = {
  127. get 'Enabled'() {
  128. return renderer.clippingPlanes !== Empty;
  129. },
  130. set 'Enabled'( v ) {
  131. renderer.clippingPlanes = v ? globalPlanes : Empty;
  132. },
  133. get 'Plane'() {
  134. return globalPlane.constant;
  135. },
  136. set 'Plane'( v ) {
  137. globalPlane.constant = v;
  138. }
  139. };
  140. folderLocal.add( propsLocal, 'Enabled' );
  141. folderLocal.add( propsLocal, 'Shadows' );
  142. folderLocal.add( propsLocal, 'Plane', 0.3, 1.25 );
  143. folderGlobal.add( propsGlobal, 'Enabled' );
  144. folderGlobal.add( propsGlobal, 'Plane', - 0.4, 3 );
  145. // Start
  146. startTime = Date.now();
  147. }
  148. function onWindowResize() {
  149. camera.aspect = window.innerWidth / window.innerHeight;
  150. camera.updateProjectionMatrix();
  151. renderer.setSize( window.innerWidth, window.innerHeight );
  152. }
  153. function animate() {
  154. var currentTime = Date.now();
  155. var time = ( currentTime - startTime ) / 1000;
  156. requestAnimationFrame( animate );
  157. object.position.y = 0.8;
  158. object.rotation.x = time * 0.5;
  159. object.rotation.y = time * 0.2;
  160. object.scale.setScalar( Math.cos( time ) * 0.125 + 0.875 );
  161. stats.begin();
  162. renderer.render( scene, camera );
  163. stats.end();
  164. }
  165. </script>
  166. </body>
  167. </html>