【Three.js 入门指南】第三章 几何形状

EngineBUS 发表于 2016-11-8 22:40:26 | 显示全部楼层 |阅读模式 [复制链接]
0 555
在创建物体时,需要传入两个参数,一个是几何形状(Geometry),另一个是材质(Material)。本章将介绍几何形状的创建,第4章介绍材质,第5章介绍如何使用这两者创建网格。
几何形状(Geometry)最主要的功能是储存了一个物体的顶点信息。WebGL需要程序员指定每个顶点的位置,而在Three.js中,可以通过指定一些特征来创建几何形状,例如使用半径创建一个球体,从而省去程序员一个个指定顶点的工作量。
本节将分别介绍立方体、平面、球体、圆柱体、四面体、八面体等几何形状,以及以三维文字作为几何形状的方法。本节还会介绍通过手动定义顶点位置和面片信息组成几何形状。

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus3.1 基本几何形状立方体
EngineBUS enginebus EngineBUS enginebus虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也就是长宽高可以设置为不同的值。其构造函数是:
EngineBUS enginebus EngineBUS enginebus
  1. THREE.CubeGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)
复制代码
这里,width是x方向上的长度;height是y方向上的长度;depth是z方向上的长度;后三个参数分别是在三个方向上的分段数,如widthSegments为3的话,代表x方向上水平分为三份。一般情况下不需要分段的话,可以不设置后三个参数,后三个参数的缺省值为1。其他几何形状中的分段也是类似的,下面不做说明。
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus长宽高
EngineBUS enginebus EngineBUS enginebus
创建立方体直观简单,如:new THREE.CubeGeometry(1, 2, 3);可以创建一个x方向长度为1,y方向长度为2,z方向长度为3的立方体。
为了更好地表现参数效果,我们在场景中用长度为1的红、绿、蓝线段分别表示x、y、z三个轴。在设置材质,并添加到场景之后(具体方法参见第4章及第5章)的效果是:
物体的默认位置是原点,对于立方体而言,是其几何中心在原点的位置。
分段
而在设置了分段new THREE.CubeGeometry(1, 2, 3, 2, 2, 3)后,效果如下:
注意这个分段是对六个面进行分段,而不是对立方体的体素分段,因此在立方体的中间是不分段的,只有六个侧面被分段。
平面
这里的平面(PlaneGeometry)其实是一个长方形,而不是数学意义上无限大小的平面。其构造函数为:
  1. THREE.PlaneGeometry(width, height, widthSegments, heightSegments)
复制代码
其中,width是x方向上的长度;height是y方向上的长度;后两个参数同样表示分段。
new THREE.PlaneGeometry(2, 4);创建的平面在x轴和y轴所在平面内,效果如下:

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
如果需要创建的平面在x轴和z轴所在的平面内,可以通过物体的旋转来实现,具体的做法将在5.2节作介绍。
球体
球体(SphereGeometry)的构造函数是:
  1. THREE.SphereGeometry(radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength)
复制代码
其中,radius是半径;segmentsWidth表示经度上的切片数;segmentsHeight表示纬度上的切片数;phiStart表示经度开始的弧度;phiLength表示经度跨过的弧度;thetaStart表示纬度开始的弧度;thetaLength表示纬度跨过的弧度。
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus分段
首先,我们来理解下segmentsWidth和segmentsHeight。使用var sphere = new THREE.SphereGeometry(3, 8, 6)可以创建一个半径为3,经度划分成8份,纬度划分成6份的球体。
segmentsWidth相当于经度被切成了几瓣,而segmentsHeight相当于纬度被切成了几层。因为在图形底层的实现中,并没有曲线的概念,曲线都是由多个折线近似构成的。对于球体而言,当这两个值较大的时候,形成的多面体就可以近似看做是球体了。
new THREE.SphereGeometry(3, 8, 6)的效果:

EngineBUS enginebus EngineBUS enginebus经度弧度
new THREE.SphereGeometry(3, 8, 6, Math.PI / 6, Math.PI / 3)表示起始经度为Math.PI / 6,经度跨度为Math.PI / 3。效果如下:
需要注意的是,这里segmentsWidth为8意味着对于经度从Math.PI / 6跨过Math.PI / 3的区域内划分为8块,而不是整个球体的经度划分成8块后再判断在此经度范围内的部分。
纬度弧度
理解了经度之后,纬度可以同理理解。new THREE.SphereGeometry(3, 8, 6, 0, Math.PI * 2, Math.PI / 6, Math.PI / 3)意味着纬度从Math.PI / 6跨过Math.PI / 3。效果如下:

EngineBUS enginebus EngineBUS enginebus圆形
圆形(CircleGeometry)可以创建圆形或者扇形,其构造函数是:
  1. THREE.CircleGeometry(radius, segments, thetaStart, thetaLength)
    EngineBUS enginebus EngineBUS enginebus
复制代码
这四个参数都是球体中介绍过的,这里不再赘述,直接来看个例子。new THREE.CircleGeometry(3, 18, Math.PI / 3, Math.PI / 3 * 4)可以创建一个在x轴和y轴所在平面的三分之二圆的扇形:

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus圆柱体
圆柱体(CylinderGeometry)的构造函数是:
  1. THREE.CylinderGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded)
复制代码
其中,radiusTop与radiusBottom分别是顶面和底面的半径,由此可知,当这两个参数设置为不同的值时,实际上创建的是一个圆台;height是圆柱体的高度;radiusSegments与heightSegments可类比球体中的分段;openEnded是一个布尔值,表示是否没有顶面和底面,缺省值为false,表示有顶面和底面。
标准圆柱体
new THREE.CylinderGeometry(2, 2, 4, 18, 3)创建一个顶面与底面半径都为2,高度为4的圆柱体,效果如下:

EngineBUS enginebus EngineBUS enginebus
圆台
将底面半径设为3创建一个圆台:new THREE.CylinderGeometry(2, 3, 4, 18, 3),效果如下:
正四面体、正八面体、正二十面体正四面体(TetrahedronGeometry)、正八面体(OctahedronGeometry)、正二十面体(IcosahedronGeometry)的构造函数较为类似,分别为:
EngineBUS enginebus EngineBUS enginebus
  1. THREE.TetrahedronGeometry(radius, detail)
    EngineBUS enginebus EngineBUS enginebus
  2. THREE.OctahedronGeometry(radius, detail)
    EngineBUS enginebus EngineBUS enginebus
  3. THREE.IcosahedronGeometry(radius, detail)
复制代码
其中,radius是半径;detail是细节层次(Level of Detail)的层数,对于大面片数模型,可以控制在视角靠近物体时,显示面片数多的精细模型,而在离物体较远时,显示面片数较少的粗略模型。这里我们不对detail多作展开,一般可以对这个值缺省。
new THREE.TetrahedronGeometry(3)创建一个半径为3的正四面体:

EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
new THREE.OctahedronGeometry(3)创建一个半径为3的正八面体
new THREE.IcosahedronGeometry(3)创建一个半径为3的正二十面体
圆环面
圆环面(TorusGeometry)就是甜甜圈的形状,其构造函数是:
  1. THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments, arc)
复制代码
其中,radius是圆环半径;tube是管道半径;radialSegments与tubularSegments分别是两个分段数,详见上图;arc是圆环面的弧度,缺省值为Math.PI * 2。
new THREE.TorusGeometry(3, 1, 4, 8)创建一个粗糙的圆环面

EngineBUS enginebus EngineBUS enginebusnew THREE.TorusGeometry(3, 1, 12, 18)创建一个较为精细的圆环面
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus圆环结
如果说圆环面是甜甜圈,那么圆环结(TorusKnotGeometry)就是打了结的甜甜圈,其构造参数为:
  1. THREE.TorusKnotGeometry(radius, tube, radialSegments, tubularSegments, p, q, heightScale)
复制代码
前四个参数在圆环面中已经有所介绍,p和q是控制其样式的参数,一般可以缺省,如果需要详细了解,请学习圆环结的相关知识;heightScale是在z轴方向上的缩放。
new THREE.TorusKnotGeometry(2, 0.5, 32, 8)的效果:

EngineBUS enginebus EngineBUS enginebus
本小节完整代码请参见例3.1.1

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus3.2 文字形状
文字形状(TextGeometry)可以用来创建三维的文字形状。
下载使用
使用文字形状需要下载和引用额外的字体库,具体参见Three.js GitHub说明
这里,我们以 helvetiker字体为例。我们在Three.js GitHub master/examples/fonts目录下,下载helvetiker_regular.typeface.json文件放在你的目录下,然后用以下方法加载:
  1. var loader = new THREE.FontLoader();
    EngineBUS enginebus EngineBUS enginebus
  2. loader.load('../lib/helvetiker_regular.typeface.json', function(font) {
    EngineBUS enginebus EngineBUS enginebus
  3.     var mesh = new THREE.Mesh(new THREE.TextGeometry('Hello', {
    EngineBUS enginebus EngineBUS enginebus
  4.         font: font,
    EngineBUS enginebus EngineBUS enginebus
  5.         size: 1,
    EngineBUS enginebus EngineBUS enginebus
  6.         height: 1
    EngineBUS enginebus EngineBUS enginebus
  7.     }), material);
    EngineBUS enginebus EngineBUS enginebus
  8.     scene.add(mesh);
    EngineBUS enginebus EngineBUS enginebus

  9. EngineBUS enginebus EngineBUS enginebus
  10.     // render
    EngineBUS enginebus EngineBUS enginebus
  11.     renderer.render(scene, camera);
    EngineBUS enginebus EngineBUS enginebus
  12. });
复制代码
参数介绍
创建文字形状的流程和之前介绍的基本几何形状是类似的,其构造函数是:

EngineBUS enginebus EngineBUS enginebus
  1. THREE.TextGeometry(text, parameters)
    EngineBUS enginebus EngineBUS enginebus
复制代码
其中,text是文字字符串,parameters是以下参数组成的对象:
  • size:字号大小,一般为大写字母的高度
  • height:文字的厚度
  • curveSegments:弧线分段数,使得文字的曲线更加光滑
  • font:字体,默认是'helvetiker',需对应引用的字体文件
  • weight:值为'normal'或'bold',表示是否加粗
  • style:值为'normal'或'italics',表示是否斜体
  • bevelEnabled:布尔值,是否使用倒角,意为在边缘处斜切
  • bevelThickness:倒角厚度
  • bevelSize:倒角宽度
    EngineBUS enginebus EngineBUS enginebus
实例说明
创建一个三维文字:new THREE.TextGeometry('Hello', {size: 1, height: 1}),其效果为:
3.3 自定义形状
EngineBUS enginebus EngineBUS enginebus
对于Three.js没有提供的形状,可以提供自定义形状来创建。
由于自定义形状需要手动指定每个顶点位置,以及顶点连接情况,如果该形状非常复杂,程序员的计算量就会比较大。在这种情况下,建议在3ds Max之类的建模软件中创建模型,然后使用Three.js导入到场景中,这样会更高效方便。
自定义形状使用的是Geometry类,它是其他如CubeGeometry、SphereGeometry等几何形状的父类,其构造函数是:
  1. THREE.Geometry()
    EngineBUS enginebus EngineBUS enginebus
复制代码
我们以创建一个梯台为例,首先,初始化一个几何形状,然后设置顶点位置以及顶点连接情况。
  1. // 初始化几何形状
    EngineBUS enginebus EngineBUS enginebus
  2. var geometry = new THREE.Geometry();
    EngineBUS enginebus EngineBUS enginebus

  3. EngineBUS enginebus EngineBUS enginebus
  4. // 设置顶点位置
    EngineBUS enginebus EngineBUS enginebus
  5. // 顶部4顶点
    EngineBUS enginebus EngineBUS enginebus
  6. geometry.vertices.push(new THREE.Vector3(-1, 2, -1));
    EngineBUS enginebus EngineBUS enginebus
  7. geometry.vertices.push(new THREE.Vector3(1, 2, -1));
    EngineBUS enginebus EngineBUS enginebus
  8. geometry.vertices.push(new THREE.Vector3(1, 2, 1));
    EngineBUS enginebus EngineBUS enginebus
  9. geometry.vertices.push(new THREE.Vector3(-1, 2, 1));
    EngineBUS enginebus EngineBUS enginebus
  10. // 底部4顶点
    EngineBUS enginebus EngineBUS enginebus
  11. geometry.vertices.push(new THREE.Vector3(-2, 0, -2));
    EngineBUS enginebus EngineBUS enginebus
  12. geometry.vertices.push(new THREE.Vector3(2, 0, -2));
    EngineBUS enginebus EngineBUS enginebus
  13. geometry.vertices.push(new THREE.Vector3(2, 0, 2));
    EngineBUS enginebus EngineBUS enginebus
  14. geometry.vertices.push(new THREE.Vector3(-2, 0, 2));
    EngineBUS enginebus EngineBUS enginebus

  15. EngineBUS enginebus EngineBUS enginebus
  16. // 设置顶点连接情况
    EngineBUS enginebus EngineBUS enginebus
  17. // 顶面
    EngineBUS enginebus EngineBUS enginebus
  18. geometry.faces.push(new THREE.Face3(0, 1, 3));
    EngineBUS enginebus EngineBUS enginebus
  19. geometry.faces.push(new THREE.Face3(1, 2, 3));
    EngineBUS enginebus EngineBUS enginebus
  20. // 底面
    EngineBUS enginebus EngineBUS enginebus
  21. geometry.faces.push(new THREE.Face3(4, 5, 6));
    EngineBUS enginebus EngineBUS enginebus
  22. geometry.faces.push(new THREE.Face3(5, 6, 7));
    EngineBUS enginebus EngineBUS enginebus
  23. // 四个侧面
    EngineBUS enginebus EngineBUS enginebus
  24. geometry.faces.push(new THREE.Face3(1, 5, 6));
    EngineBUS enginebus EngineBUS enginebus
  25. geometry.faces.push(new THREE.Face3(6, 2, 1));
    EngineBUS enginebus EngineBUS enginebus
  26. geometry.faces.push(new THREE.Face3(2, 6, 7));
    EngineBUS enginebus EngineBUS enginebus
  27. geometry.faces.push(new THREE.Face3(7, 3, 2));
    EngineBUS enginebus EngineBUS enginebus
  28. geometry.faces.push(new THREE.Face3(3, 7, 0));
    EngineBUS enginebus EngineBUS enginebus
  29. geometry.faces.push(new THREE.Face3(7, 4, 0));
    EngineBUS enginebus EngineBUS enginebus
  30. geometry.faces.push(new THREE.Face3(0, 4, 5));
    EngineBUS enginebus EngineBUS enginebus
  31. geometry.faces.push(new THREE.Face3(0, 5, 1));
复制代码

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
需要注意的是,new THREE.Vector3(-1, 2, -1)创建一个矢量,作为顶点位置追加到geometry.vertices数组中。
而由new THREE.Face3(0, 1, 3)创建一个三个顶点组成的面片,追加到geometry.faces数组中。三个参数分别是四个顶点在geometry.vertices中的序号。
在之前版本的Three.js中,可以使用Face4创建四边形,如今已经弃用。由于四个点未必共面,所以使用三角形永远是最安全的方法。

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus

EngineBUS enginebus EngineBUS enginebus
EngineBUS enginebus EngineBUS enginebus

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?Sign Up

x
您需要登录后才可以回帖 登录 | Sign Up

本版积分规则

推荐阅读

QQ| Archiver|手机版|小黑屋| 引擎巴士 EngineBUS  

Powered by Discuz! X3.2© 2001-2013 Comsenz Inc.  

返回顶部 返回列表