ThreeJs入门04-三维世界的组成(点、线)

1,130 阅读4分钟

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

示例代码采用three.js-r73版本:cdnjs.cloudflare.com/ajax/libs/t…

yuque_diagram.jpg

1. 三维世界的组成

  • 在计算机世界里,3D世界是由点组成,两个点能够组成一条直线,三个不在一条直线上的点就能够组成一个三角形面,无数三角形面就能够组成各种形状的物体

image.png

  • 这种网格模型叫做Mesh模型。
  • 给物体贴上纹理(俗称:纹理),那么这个物体就有了色彩。
  • 最后无数的物体就组成了我们的3D世界。

2. 在three.js中定义一个点

在三维空间中的某一个点可以用一个坐标点来表示。一个坐标点由x,y,z三个分量构成。

THREE.Vector3 = function ( x, y, z ) {
  this.x = x || 0;
  this.y = y || 0;
  this.z = z || 0;
};
var a = new THREE.Vecotr3(1,0,0);
  • 在three.js中,点可以在右手坐标系中表示:

image.png

  • THREE.Vector3表示一个三维向量,包含标x、y和z

3. 几何体Geometry

  • Geometry 利用 Vector3 或 Color 存储了几何体的相关 attributes(如顶点位置,面信息,颜色等)
  • 几何体是一个包含必要三维数据的一个数据结构
    • 点:this.vertices= []
    • 颜色: this.colors= []
    • 面:this.faces= []
var geometry = new THREE.Geometry();
geometry.vertices.push(
	new THREE.Vector3( -10, 10, 0 ),
  new THREE.Vector3( -10, -10, 0 ),
  new THREE.Vector3( 10, -10, 0 )
);

4. 线材质THREE.LineBasicMaterial

  • 材质,简单来说就是物体看起来是什么质地。材质可以看成是材料和质感的结合。
  • 在程序中,它是表面各可视属性(视觉效果)的结合, 这些可视属性是指表面的色彩、纹理、光滑度、透明度、反射率、折射率、发光度等。
THREE.LineBasicMaterial = function(parameters)
  • parameters是一个元组(js中就是一个对象,由key-value组成)
  • color : 线条的颜色,用16进制来表示,默认的颜色是白色。
  • linewidth:线条的宽度,默认是1个单位宽度。(WebGlRenderer渲染器不支持线的宽度
  • linecap :线条两端的外观,默认是圆角端点,当线条较粗的时候才看得出效果,如果线条很细,那么你几乎看不出效果了。
  • linejoin :两个线条的连接点处的外观,默认是"round" , 表示圆角。
  • lertexColors :定义线条材质是否使用顶点颜色,这是一个boolean值。意思是,线条各部分的颜色会根据项点的颜色来进行插值。
  • vertexColors
    • 设置为true,使用顶点颜色。两个端点渐变成一条线的颜色
    • 设置为false,不使用颜色(默认为白色),此时可以设置color

插值

  • 给线的两个端点设置不同的颜色,就会产生一条渐变色的线,线中间的颜色如何产生的呢?这里涉及到了一个插值的概念。
  • 想要理解插值,还需要先理解下什么是颜色插值
  • 我们定义两个点(x0, y0)值为A,(x1, y1)值为B
  • 直线插值为y=p1(x)
  • 曲线插值为y=f(x)

image.png

颜色插值

下面是一个取色板,假定我们要在上面取两个点,两个点绘制一条线,那这条线所经过的颜色绘制成线的颜色,这个就是颜色插值。 image.pngimage.png

5. webgl线绘制方式

  • 我们有几个点GL_POINTS: v0,v1,v2,v3,v4,v5
  • 每两个点绘制一条线GL_LINES:v0-v1,v2-v3,v4-v5
  • 相邻的点连接起来绘制成GL_LINE_STRIP: v0-v1-v2-v3-v4-v5
    • 相邻点的意思是前一个点作为当前线段的起点,也叫带状线段
  • threejs绘制线采用的是GL_LINES``GL_LINE_STRIP这两种,其他目前不做介绍

image.png

6. 绘制一个三角形

  • 修改我们上节画线的代码,添加一个顶点,将三个点的线连接起来。
  • 画个草图:

image.png

// 创建几何体
var geometry = new THREE.Geometry();
//   创建线的材质
// 不使用顶点的颜色就会使用color的颜色
var material = new THREE.LineBasicMaterial({
    vertexColors: true,
});
//   定义颜色
var color1 = new THREE.Color(0x444444),
    color2 = new THREE.Color(0xff0000),
    color3 = new THREE.Color(0x00ff00)

// 线的材质可以由2点的颜色决定
var p1 = new THREE.Vector3(-100, 0, 100);
var p2 = new THREE.Vector3(100, 0, -100);
var p3 = new THREE.Vector3(100, 0, 100);
geometry.vertices.push(p1);
geometry.vertices.push(p2);
geometry.vertices.push(p3);
geometry.colors.push(color1, color2, color3);
//   创建线
var line = new THREE.Line(geometry, material, THREE.LineStrip);
scene.add(line);

image.png

  • 现在我们绘制完成图只有两条线,这是为什么呢
    • 我们现在绘制线的顺序是p1-p2绘制一条线,p2-p3绘制一条线
    • 所以我们还需要p3-p1绘制一条线
geometry.vertices.push(p1);
geometry.vertices.push(p2);
geometry.vertices.push(p3);
geometry.vertices.push(p1);

geometry.colors.push(color1, color2, color3, color1);
  • 此时的效果

image.png