当前位置:Gxlcms > JavaScript > Three.js利用顶点绘制立方体的方法详解

Three.js利用顶点绘制立方体的方法详解

时间:2021-07-01 10:21:17 帮助过:47人阅读

前言

之前我们在学些WebGL基础的时候每天都是在一直研究顶点位置,法向量,绘制下标什么的。虽然复杂,但是毕竟原生,性能没得说。

three.js也给我们提供了相关的接口供我们使用原生的方法绘制模型,下面话不多说了,来一起看看详细的介绍吧。

下面是我的个人一个案例。

首先,我创建了一个空白的形状:

  1. //立方体
  2. var cubeGeometry = new THREE.Geometry();

立方体的形状如下:

  1. // 创建一个立方体
  2. // v6----- v5
  3. // /| /|
  4. // v1------v0|
  5. // | | | |
  6. // | |v7---|-|v4
  7. // |/ |/
  8. // v2------v3

然后添加了立方体的顶点,一共8个

  1. //创建立方体的顶点
  2. var vertices = [
  3. new THREE.Vector3(10, 10, 10), //v0
  4. new THREE.Vector3(-10, 10, 10), //v1
  5. new THREE.Vector3(-10, -10, 10), //v2
  6. new THREE.Vector3(10, -10, 10), //v3
  7. new THREE.Vector3(10, -10, -10), //v4
  8. new THREE.Vector3(10, 10, -10), //v5
  9. new THREE.Vector3(-10, 10, -10), //v6
  10. new THREE.Vector3(-10, -10, -10) //v7
  11. ];
  12. cubeGeometry.vertices = vertices;

接着通过顶点的坐标生成了立方体的面

  1. //创建立方的面
  2. var faces=[
  3. new THREE.Face3(0,1,2),
  4. new THREE.Face3(0,2,3),
  5. new THREE.Face3(0,3,4),
  6. new THREE.Face3(0,4,5),
  7. new THREE.Face3(1,6,7),
  8. new THREE.Face3(1,7,2),
  9. new THREE.Face3(6,5,4),
  10. new THREE.Face3(6,4,7),
  11. new THREE.Face3(5,6,1),
  12. new THREE.Face3(5,1,0),
  13. new THREE.Face3(3,2,7),
  14. new THREE.Face3(3,7,4)
  15. ];
  16. cubeGeometry.faces = faces;

在这里需要注意:

(1)面是由三个顶点组成的一个三角形面,也是WebGL的实现面的方式。如果需要一个长方形,那就需要由两个三角形组合而成。

(2)如果要绘制的面是朝向相机的,那这个面的顶点的书写方式是逆时针绘制的,比如图上模型的第一个面的添加里面书写的是(0,1,2)。

(3)如果能使模型有灯光的效果,还需要设置法向量,让three.js自动生成即可,如下

  1. //生成法向量
  2. cubeGeometry.computeFaceNormals();

当前的这些步骤只是生成了形状,还需要和以前一样设置一个纹理,再通过THTEE.Mesh()方法生成网格

  1. var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x00ffff});
  2. cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

这样就实现了一个立方体的绘制:

全部代码如下:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <style type="text/css">
  7. html, body {
  8. margin: 0;
  9. height: 100%;
  10. }
  11. canvas {
  12. display: block;
  13. }
  14. </style>
  15. </head>
  16. <body onload="draw();">
  17. </body>
  18. <script src="build/three.js"></script>
  19. <script src="examples/js/controls/OrbitControls.js"></script>
  20. <script src="examples/js/libs/stats.min.js"></script>
  21. <script src="examples/js/libs/dat.gui.min.js"></script>
  22. <script>
  23. var renderer;
  24. function initRender() {
  25. renderer = new THREE.WebGLRenderer({antialias: true});
  26. renderer.setSize(window.innerWidth, window.innerHeight);
  27. //告诉渲染器需要阴影效果
  28. renderer.shadowMap.enabled = true;
  29. renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默认的是,没有设置的这个清晰 THREE.PCFShadowMap
  30. document.body.appendChild(renderer.domElement);
  31. }
  32. var camera;
  33. function initCamera() {
  34. camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
  35. camera.position.set(0, 40, 100);
  36. camera.lookAt(new THREE.Vector3(0, 0, 0));
  37. }
  38. var scene;
  39. function initScene() {
  40. scene = new THREE.Scene();
  41. }
  42. //初始化dat.GUI简化试验流程
  43. var gui;
  44. function initGui() {
  45. //声明一个保存需求修改的相关数据的对象
  46. gui = {
  47. lightY: 30, //灯光y轴的位置
  48. cubeX: 25, //立方体的x轴位置
  49. cubeY: 10, //立方体的x轴位置
  50. cubeZ: -5 //立方体的z轴的位置
  51. };
  52. var datGui = new dat.GUI();
  53. //将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)
  54. datGui.add(gui, "lightY", 0, 100);
  55. datGui.add(gui, "cubeX", -30, 30);
  56. datGui.add(gui, "cubeY", -30, 30);
  57. datGui.add(gui, "cubeZ", -30, 30);
  58. }
  59. var light;
  60. function initLight() {
  61. scene.add(new THREE.AmbientLight(0x444444));
  62. light = new THREE.PointLight(0xffffff);
  63. light.position.set(15, 30, 10);
  64. //告诉平行光需要开启阴影投射
  65. light.castShadow = true;
  66. scene.add(light);
  67. }
  68. var cube;
  69. function initModel() {
  70. //辅助工具
  71. var helper = new THREE.AxisHelper(10);
  72. scene.add(helper);
  73. // 创建一个立方体
  74. // v6----- v5
  75. // /| /|
  76. // v1------v0|
  77. // | | | |
  78. // | |v7---|-|v4
  79. // |/ |/
  80. // v2------v3
  81. //立方体
  82. var cubeGeometry = new THREE.Geometry();
  83. //创建立方体的顶点
  84. var vertices = [
  85. new THREE.Vector3(10, 10, 10), //v0
  86. new THREE.Vector3(-10, 10, 10), //v1
  87. new THREE.Vector3(-10, -10, 10), //v2
  88. new THREE.Vector3(10, -10, 10), //v3
  89. new THREE.Vector3(10, -10, -10), //v4
  90. new THREE.Vector3(10, 10, -10), //v5
  91. new THREE.Vector3(-10, 10, -10), //v6
  92. new THREE.Vector3(-10, -10, -10) //v7
  93. ];
  94. cubeGeometry.vertices = vertices;
  95. //创建立方的面
  96. var faces=[
  97. new THREE.Face3(0,1,2),
  98. new THREE.Face3(0,2,3),
  99. new THREE.Face3(0,3,4),
  100. new THREE.Face3(0,4,5),
  101. new THREE.Face3(1,6,7),
  102. new THREE.Face3(1,7,2),
  103. new THREE.Face3(6,5,4),
  104. new THREE.Face3(6,4,7),
  105. new THREE.Face3(5,6,1),
  106. new THREE.Face3(5,1,0),
  107. new THREE.Face3(3,2,7),
  108. new THREE.Face3(3,7,4)
  109. ];
  110. cubeGeometry.faces = faces;
  111. //生成法向量
  112. cubeGeometry.computeFaceNormals();
  113. var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x00ffff});
  114. cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  115. cube.position.x = 25;
  116. cube.position.y = 5;
  117. cube.position.z = -5;
  118. //告诉立方体需要投射阴影
  119. cube.castShadow = true;
  120. scene.add(cube);
  121. //底部平面
  122. var planeGeometry = new THREE.PlaneGeometry(100, 100);
  123. var planeMaterial = new THREE.MeshLambertMaterial({color: 0xaaaaaa});
  124. var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  125. plane.rotation.x = -0.5 * Math.PI;
  126. plane.position.y = -0;
  127. //告诉底部平面需要接收阴影
  128. plane.receiveShadow = true;
  129. scene.add(plane);
  130. }
  131. //初始化性能插件
  132. var stats;
  133. function initStats() {
  134. stats = new Stats();
  135. document.body.appendChild(stats.dom);
  136. }
  137. //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
  138. var controls;
  139. function initControls() {
  140. controls = new THREE.OrbitControls(camera, renderer.domElement);
  141. // 如果使用animate方法时,将此函数删除
  142. //controls.addEventListener( 'change', render );
  143. // 使动画循环使用时阻尼或自转 意思是否有惯性
  144. controls.enableDamping = true;
  145. //动态阻尼系数 就是鼠标拖拽旋转灵敏度
  146. //controls.dampingFactor = 0.25;
  147. //是否可以缩放
  148. controls.enableZoom = true;
  149. //是否自动旋转
  150. controls.autoRotate = false;
  151. //设置相机距离原点的最远距离
  152. controls.minDistance = 50;
  153. //设置相机距离原点的最远距离
  154. controls.maxDistance = 200;
  155. //是否开启右键拖拽
  156. controls.enablePan = true;
  157. }
  158. function render() {
  159. renderer.render(scene, camera);
  160. }
  161. //窗口变动触发的函数
  162. function onWindowResize() {
  163. camera.aspect = window.innerWidth / window.innerHeight;
  164. camera.updateProjectionMatrix();
  165. render();
  166. renderer.setSize(window.innerWidth, window.innerHeight);
  167. }
  168. function animate() {
  169. //更新控制器
  170. render();
  171. //更新性能插件
  172. stats.update();
  173. //更新相关位置
  174. light.position.y = gui.lightY;
  175. cube.position.x = gui.cubeX;
  176. cube.position.y = gui.cubeY;
  177. cube.position.z = gui.cubeZ;
  178. controls.update();
  179. requestAnimationFrame(animate);
  180. }
  181. function draw() {
  182. initGui();
  183. initRender();
  184. initScene();
  185. initCamera();
  186. initLight();
  187. initModel();
  188. initControls();
  189. initStats();
  190. animate();
  191. window.onresize = onWindowResize;
  192. }
  193. </script>
  194. </html>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用Three.js具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

人气教程排行