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


Posted in Javascript onSeptember 27, 2017

前言

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

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

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

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

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

立方体的形状如下:

// 创建一个立方体
  // v6----- v5
  // /|  /|
  // v1------v0|
  // | |  | |
  // | |v7---|-|v4
  // |/  |/
  // v2------v3

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

//创建立方体的顶点
  var vertices = [
   new THREE.Vector3(10, 10, 10), //v0
   new THREE.Vector3(-10, 10, 10), //v1
   new THREE.Vector3(-10, -10, 10), //v2
   new THREE.Vector3(10, -10, 10), //v3
   new THREE.Vector3(10, -10, -10), //v4
   new THREE.Vector3(10, 10, -10), //v5
   new THREE.Vector3(-10, 10, -10), //v6
   new THREE.Vector3(-10, -10, -10) //v7
  ];

  cubeGeometry.vertices = vertices;

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

//创建立方的面
  var faces=[
   new THREE.Face3(0,1,2),
   new THREE.Face3(0,2,3),
   new THREE.Face3(0,3,4),
   new THREE.Face3(0,4,5),
   new THREE.Face3(1,6,7),
   new THREE.Face3(1,7,2),
   new THREE.Face3(6,5,4),
   new THREE.Face3(6,4,7),
   new THREE.Face3(5,6,1),
   new THREE.Face3(5,1,0),
   new THREE.Face3(3,2,7),
   new THREE.Face3(3,7,4)
  ];

  cubeGeometry.faces = faces;

在这里需要注意:

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

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

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

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

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

var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x00ffff});

  cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

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

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

全部代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <style type="text/css">
  html, body {
   margin: 0;
   height: 100%;
  }

  canvas {
   display: block;
  }

 </style>
</head>
<body onload="draw();">

</body>
<script src="build/three.js"></script>
<script src="examples/js/controls/OrbitControls.js"></script>
<script src="examples/js/libs/stats.min.js"></script>
<script src="examples/js/libs/dat.gui.min.js"></script>
<script>
 var renderer;
 function initRender() {
  renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setSize(window.innerWidth, window.innerHeight);
  //告诉渲染器需要阴影效果
  renderer.shadowMap.enabled = true;
  renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默认的是,没有设置的这个清晰 THREE.PCFShadowMap
  document.body.appendChild(renderer.domElement);
 }

 var camera;
 function initCamera() {
  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 40, 100);
  camera.lookAt(new THREE.Vector3(0, 0, 0));
 }

 var scene;
 function initScene() {
  scene = new THREE.Scene();
 }

 //初始化dat.GUI简化试验流程
 var gui;
 function initGui() {
  //声明一个保存需求修改的相关数据的对象
  gui = {
   lightY: 30, //灯光y轴的位置
   cubeX: 25, //立方体的x轴位置
   cubeY: 10, //立方体的x轴位置
   cubeZ: -5 //立方体的z轴的位置
  };
  var datGui = new dat.GUI();
  //将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)
  datGui.add(gui, "lightY", 0, 100);
  datGui.add(gui, "cubeX", -30, 30);
  datGui.add(gui, "cubeY", -30, 30);
  datGui.add(gui, "cubeZ", -30, 30);
 }

 var light;
 function initLight() {
  scene.add(new THREE.AmbientLight(0x444444));

  light = new THREE.PointLight(0xffffff);
  light.position.set(15, 30, 10);

  //告诉平行光需要开启阴影投射
  light.castShadow = true;

  scene.add(light);
 }

 var cube;
 function initModel() {

  //辅助工具
  var helper = new THREE.AxisHelper(10);
  scene.add(helper);

  // 创建一个立方体
  // v6----- v5
  // /|  /|
  // v1------v0|
  // | |  | |
  // | |v7---|-|v4
  // |/  |/
  // v2------v3

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

  //创建立方体的顶点
  var vertices = [
   new THREE.Vector3(10, 10, 10), //v0
   new THREE.Vector3(-10, 10, 10), //v1
   new THREE.Vector3(-10, -10, 10), //v2
   new THREE.Vector3(10, -10, 10), //v3
   new THREE.Vector3(10, -10, -10), //v4
   new THREE.Vector3(10, 10, -10), //v5
   new THREE.Vector3(-10, 10, -10), //v6
   new THREE.Vector3(-10, -10, -10) //v7
  ];

  cubeGeometry.vertices = vertices;

  //创建立方的面
  var faces=[
   new THREE.Face3(0,1,2),
   new THREE.Face3(0,2,3),
   new THREE.Face3(0,3,4),
   new THREE.Face3(0,4,5),
   new THREE.Face3(1,6,7),
   new THREE.Face3(1,7,2),
   new THREE.Face3(6,5,4),
   new THREE.Face3(6,4,7),
   new THREE.Face3(5,6,1),
   new THREE.Face3(5,1,0),
   new THREE.Face3(3,2,7),
   new THREE.Face3(3,7,4)
  ];

  cubeGeometry.faces = faces;

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

  var cubeMaterial = new THREE.MeshLambertMaterial({color: 0x00ffff});

  cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
  cube.position.x = 25;
  cube.position.y = 5;
  cube.position.z = -5;

  //告诉立方体需要投射阴影
  cube.castShadow = true;

  scene.add(cube);

  //底部平面
  var planeGeometry = new THREE.PlaneGeometry(100, 100);
  var planeMaterial = new THREE.MeshLambertMaterial({color: 0xaaaaaa});

  var plane = new THREE.Mesh(planeGeometry, planeMaterial);
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.y = -0;

  //告诉底部平面需要接收阴影
  plane.receiveShadow = true;

  scene.add(plane);

 }

 //初始化性能插件
 var stats;
 function initStats() {
  stats = new Stats();
  document.body.appendChild(stats.dom);
 }

 //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
 var controls;
 function initControls() {

  controls = new THREE.OrbitControls(camera, renderer.domElement);

  // 如果使用animate方法时,将此函数删除
  //controls.addEventListener( 'change', render );
  // 使动画循环使用时阻尼或自转 意思是否有惯性
  controls.enableDamping = true;
  //动态阻尼系数 就是鼠标拖拽旋转灵敏度
  //controls.dampingFactor = 0.25;
  //是否可以缩放
  controls.enableZoom = true;
  //是否自动旋转
  controls.autoRotate = false;
  //设置相机距离原点的最远距离
  controls.minDistance = 50;
  //设置相机距离原点的最远距离
  controls.maxDistance = 200;
  //是否开启右键拖拽
  controls.enablePan = true;
 }

 function render() {
  renderer.render(scene, camera);
 }

 //窗口变动触发的函数
 function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  render();
  renderer.setSize(window.innerWidth, window.innerHeight);

 }

 function animate() {
  //更新控制器
  render();

  //更新性能插件
  stats.update();

  //更新相关位置
  light.position.y = gui.lightY;
  cube.position.x = gui.cubeX;
  cube.position.y = gui.cubeY;
  cube.position.z = gui.cubeZ;

  controls.update();

  requestAnimationFrame(animate);
 }

 function draw() {
  initGui();
  initRender();
  initScene();
  initCamera();
  initLight();
  initModel();
  initControls();
  initStats();

  animate();
  window.onresize = onWindowResize;
 }
</script>
</html>

总结

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

Javascript 相关文章推荐
Javascript继承机制的设计思想分享
Aug 28 Javascript
window.print打印指定div指定网页指定区域的方法
Aug 04 Javascript
JavaScript中String.match()方法的使用详解
Jun 06 Javascript
javaScript中Math()函数注意事项
Jun 18 Javascript
Javascript实现的简单右键菜单类
Sep 23 Javascript
巧用weui.topTips验证数据的实例
Apr 17 Javascript
JavaScript中最常用的10种代码简写技巧总结
Jun 28 Javascript
JavaScript类的继承方法小结【组合继承分析】
Jul 11 Javascript
JavaScript刷新页面的几种方法总结
Mar 28 Javascript
vue在响应头response中获取自定义headers操作
Jul 24 Javascript
vue等两个接口都返回结果再执行下一步的实例
Sep 08 Javascript
用React Native制作一个简单的游戏引擎
May 27 Javascript
js实现扫雷小程序的示例代码
Sep 27 #Javascript
Three.js如何实现雾化效果示例代码
Sep 27 #Javascript
浅谈Angular4中常用管道
Sep 27 #Javascript
深入理解Vue.js源码之事件机制
Sep 27 #Javascript
js截取字符串功能的实现方法
Sep 27 #Javascript
详解node+express+ejs+bootstrap构建项目
Sep 27 #Javascript
Three.js基础学习之场景对象
Sep 27 #Javascript
You might like
模仿OSO的论坛(一)
2006/10/09 PHP
PHP crypt()函数的用法讲解
2019/02/15 PHP
Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
2010/03/16 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
2010/10/11 Javascript
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
jQuery基本选择器选择元素使用介绍
2013/04/18 Javascript
js jq 单击和双击区分示例介绍
2013/11/05 Javascript
js读写cookie实现一个底部广告浮层效果的两种方法
2013/12/29 Javascript
jquery实现类似EasyUI的页面布局可改变左右的宽度
2020/09/12 Javascript
生成二维码方法汇总
2014/12/26 Javascript
浅谈js的url解析函数封装
2016/06/28 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
2016/12/28 Javascript
Avalonjs双向数据绑定与监听的实例代码
2017/06/23 Javascript
vue组件watch属性实例讲解
2017/11/07 Javascript
three.js中3D视野的缩放实现代码
2017/11/16 Javascript
微信小程序页面间跳转传参方式总结
2019/06/13 Javascript
小程序自定义导航栏兼容适配所有机型(附完整案例)
2020/04/26 Javascript
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
2020/08/27 Javascript
vscode 调试 node.js的方法步骤
2020/09/15 Javascript
[03:58]兄弟们,回来开黑了!DOTA2昔日战友招募宣传视频
2016/07/17 DOTA
[01:02:38]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第二场 1月10日
2021/03/11 DOTA
Python实现基于HTTP文件传输实例
2014/11/08 Python
Python对数据进行插值和下采样的方法
2018/07/03 Python
python分数表示方式和写法
2019/06/26 Python
python自动生成model文件过程详解
2019/11/02 Python
Python利用Pillow(PIL)库实现验证码图片的全过程
2020/10/04 Python
完美解决Pycharm中matplotlib画图中文乱码问题
2021/01/11 Python
CSS3绘制不规则图形的一些方法示例
2015/11/07 HTML / CSS
css3给背景图片加颜色遮罩的方法
2019/11/05 HTML / CSS
Clarins娇韵诗英国官网:来自法国的天然护肤品牌
2017/04/18 全球购物
环境工程专业个人求职信
2013/12/05 职场文书
结婚邀请函范文
2014/01/14 职场文书
护理专科毕业自荐信范文
2014/04/21 职场文书
服务标兵事迹材料
2014/05/04 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
文艺有韵味的诗句(生命类、亲情类...)
2019/07/11 职场文书