threejs学习day3:几何形状
Posted 简数
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了threejs学习day3:几何形状相关的知识,希望对你有一定的参考价值。
几何形状(Geometry)最主要的功能是储存了一个物体的顶点信息。WebGL需要程序员指定每个顶点的位置,而在Three.js中,可以通过指定一些特征来创建几何形状,例如使用半径创建一个球体,从而省去程序员一个个指定顶点的工作量。
本节将分别介绍立方体、平面、球体、圆柱体、四面体、八面体等几何形状,以及以三维文字作为几何形状的方法。本节还会介绍通过手动定义顶点位置和面片信息组成几何形状。
立方体
虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也就是长宽高可以设置为不同的值。其构造函数是:
THREE.CubeGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)
这里,width
是x方向上的长度;height
是y方向上的长度;depth
是z方向上的长度;后三个参数分别是在三个方向上的分段数,如widthSegments
为3
的话,代表x方向上水平分为三份。一般情况下不需要分段的话,可以不设置后三个参数,后三个参数的缺省值为1
。其他几何形状中的分段也是类似的,下面不做说明。
长宽高
创建立方体直观简单,如: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)
后,效果如下:
注意这个分段是对六个面进行分段,而不是对立方体的体素分段,因此在立方体的中间是不分段的,只有六个侧面被分段。
球体
球体(SphereGeometry)的构造函数是:
THREE.SphereGeometry(radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength)
其中,radius
是半径;segmentsWidth
表示经度上的切片数;segmentsHeight
表示纬度上的切片数;phiStart
表示经度开始的弧度;phiLength
表示经度跨过的弧度;thetaStart
表示纬度开始的弧度;thetaLength
表示纬度跨过的弧度。
分段
首先,我们来理解下segmentsWidth
和segmentsHeight
。使用var sphere = new THREE.SphereGeometry(3, 8, 6)
可以创建一个半径为3,经度划分成8份,纬度划分成6份的球体,如下图所示。
segmentsWidth
相当于经度被切成了几瓣,而segmentsHeight
相当于纬度被切成了几层。因为在图形底层的实现中,并没有曲线的概念,曲线都是由多个折线近似构成的。对于球体而言,当这两个值较大的时候,形成的多面体就可以近似看做是球体了。
new THREE.SphereGeometry(3, 8, 6)
的效果:
new THREE.SphereGeometry(3, 18, 12)
的效果:
经度弧度
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
。效果如下:
我们再来看一个经度纬度都改变了起始位置和跨度的例子:new THREE.SphereGeometry(3, 8, 6, Math.PI / 2, Math.PI, Math.PI / 6, Math.PI / 2)
的效果为:
文字形状
文字形状(TextGeometry)可以用来创建三维的文字形状。
下载使用
使用文字形状需要下载和引用额外的字体库,具体参见Three.js GitHub说明。
这里,我们以helvetiker
字体为例。我们在Three.js GitHub master/examples/fonts目录下,下载helvetiker_regular.typeface.json
文件放在你的目录下,然后用以下方法加载:
var loader = new THREE.FontLoader();
loader.load('../lib/helvetiker_regular.typeface.json', function(font) {
var mesh = new THREE.Mesh(new THREE.TextGeometry('Hello', {
font: font,
size: 1,
height: 1
}), material);
scene.add(mesh);
// render
renderer.render(scene, camera);
});
参数介绍
创建文字形状的流程和之前介绍的基本几何形状是类似的,其构造函数是:
THREE.TextGeometry(text, parameters)
其中,text
是文字字符串,parameters
是以下参数组成的对象:
size
:字号大小,一般为大写字母的高度height
:文字的厚度curveSegments
:弧线分段数,使得文字的曲线更加光滑font
:字体,默认是'helvetiker'
,需对应引用的字体文件weight
:值为'normal'
或'bold'
,表示是否加粗style
:值为'normal'
或'italics'
,表示是否斜体bevelEnabled
:布尔值,是否使用倒角,意为在边缘处斜切bevelThickness
:倒角厚度bevelSize
:倒角宽度
实例说明
创建一个三维文字:new THREE.TextGeometry('Hello', {size: 1, height: 1})
,其效果为:
改变材质和光照之后就能达到这样的效果:
自定义形状
对于Three.js没有提供的形状,可以提供自定义形状来创建。
由于自定义形状需要手动指定每个顶点位置,以及顶点连接情况,如果该形状非常复杂,程序员的计算量就会比较大。在这种情况下,建议在3ds Max之类的建模软件中创建模型,然后使用Three.js导入到场景中,这样会更高效方便。
自定义形状使用的是Geometry类,它是其他如CubeGeometry、SphereGeometry等几何形状的父类,其构造函数是:
THREE.Geometry()
我们以创建一个梯台为例,首先,初始化一个几何形状,然后设置顶点位置以及顶点连接情况。
// 初始化几何形状
var geometry = new THREE.Geometry();
// 设置顶点位置
// 顶部4顶点
geometry.vertices.push(new THREE.Vector3(-1, 2, -1));
geometry.vertices.push(new THREE.Vector3(1, 2, -1));
geometry.vertices.push(new THREE.Vector3(1, 2, 1));
geometry.vertices.push(new THREE.Vector3(-1, 2, 1));
// 底部4顶点
geometry.vertices.push(new THREE.Vector3(-2, 0, -2));
geometry.vertices.push(new THREE.Vector3(2, 0, -2));
geometry.vertices.push(new THREE.Vector3(2, 0, 2));
geometry.vertices.push(new THREE.Vector3(-2, 0, 2));
// 设置顶点连接情况
// 顶面
geometry.faces.push(new THREE.Face3(0, 1, 3));
geometry.faces.push(new THREE.Face3(1, 2, 3));
// 底面
geometry.faces.push(new THREE.Face3(4, 5, 6));
geometry.faces.push(new THREE.Face3(5, 6, 7));
// 四个侧面
geometry.faces.push(new THREE.Face3(1, 5, 6));
geometry.faces.push(new THREE.Face3(6, 2, 1));
geometry.faces.push(new THREE.Face3(2, 6, 7));
geometry.faces.push(new THREE.Face3(7, 3, 2));
geometry.faces.push(new THREE.Face3(3, 7, 0));
geometry.faces.push(new THREE.Face3(7, 4, 0));
geometry.faces.push(new THREE.Face3(0, 4, 5));
geometry.faces.push(new THREE.Face3(0, 5, 1));
效果是:
需要注意的是,new THREE.Vector3(-1, 2, -1)
创建一个矢量,作为顶点位置追加到geometry.vertices
数组中。
而由new THREE.Face3(0, 1, 3)
创建一个三个顶点组成的面片,追加到geometry.faces
数组中。三个参数分别是四个顶点在geometry.vertices
中的序号。
在之前版本的Three.js中,可以使用Face4创建四边形,如今已经弃用。由于四个点未必共面,所以使用三角形永远是最安全的方法。
以上是关于threejs学习day3:几何形状的主要内容,如果未能解决你的问题,请参考以下文章