three.js顶点篇

简介: three.js顶点篇

目录


基础篇

顶点是什么

顶点几何体和geometry.attributes.position

顶点颜色geometry.attributes.color

顶点法向量geometry.attributes.normal

顶点复用geometry.index

基础篇


阅读顶点篇之前如果没有学习基础篇请先移步,方便了解学习环境:three.js基础篇


顶点是什么



基础篇中我们学会了网络模型mesh,网络模型基础包括了集合体Geometry和材质material。


其中几何体中我们可以很容易的使用BoxGeometry或者SphereGeometry创建柱状几何体或者球形几何体。


这些几何体其实都是通过顶点这个概念创建的,只不过它们在内部封装好了。


顶点几何体和geometry.attributes.position



面、线、点有效的几何体表达名为BufferGeometry


 const geometry = new THREE.BufferGeometry()

1

当然它不像BoxGeometry或者SphereGeometry传递尺寸等参数就形成了几何体,它麻烦一些。


想要使用它我们得先借助js的内置对象Float32Array,32位浮点数对象生成一份矩阵数据。

  const vertices = new Float32Array([
            0, 0, 0, 
            50, 0, 0, 
            0, 100, 0, 
            0, 0, 10, 
            0, 0, 100, 
            50, 0, 10, 
  ]);

这份数据有什么用呢?

我们可以把它赋值给几何体属性值上的位置position。

当然还得使用到three能够搭配这份数据的方法BufferAttribute。

后面的3表示前面的数据3个为一组,一组3个数字分别代表一个点的xyz轴值,也就是这个模型总共包括了6个点。

  geometry.attributes.position = new THREE.BufferAttribute(vertices, 3)

我们先不加材质,渲染一下试试啥样。

顺便复习一下基础篇生成网络模型再把模型加进场景的代码。

    const mesh = new THREE.Mesh(geometry)
    scene.add(mesh)

image.png

会发现渲染出这几个点包围的图形,要明白最少三个点才可以包围出一个面。

我们如果旋转一下模型,往上转到底部,会发现这个面只有一个面能看见,背面看不见。

image.png

这是因为得在相应的材质上加上属性。

加上一个简单着色材质MeshBasicMaterial重新构建网络模型

注意这个材质不受光照影响,所以你现在可以看见颜色,等到后面介绍法向量时你可能会产生为啥现在可以看见光照的疑惑,这里已经先解释了。

        const material = new THREE.MeshBasicMaterial({
            color: 0x0000ff, //三角面颜色
            side: THREE.DoubleSide //两面可见
        })
        const mesh = new THREE.Mesh(geometry,material)
        scene.add(mesh)

image.png

现在有颜色了而且可以看见背面。


顶点颜色geometry.attributes.color



创建几何体时我们使用到了geometry.attributes.position,它可以设置顶点的位置,同理我们还可以设置顶点的颜色。


同样也是以定点为单位设置,借助Float32Array。


同样是3个数一组,不过这次的3个数代表的是3原色,一组三原色构成一个点的颜色,取值范围0-1。

       const colors = new Float32Array([
            1, 0, 0, //顶点1颜色
            0, 1, 0, //顶点2颜色
            0, 0, 1, //顶点3颜色
            1, 1, 0, //顶点4颜色
            0, 1, 1, //顶点5颜色
            1, 0, 1, //顶点6颜色
       ]);
       geometry.attributes.color = new THREE.BufferAttribute(colors, 3)

为了先理解顶点着色,我们还得改改材质和模型。

我们用点材质PointsMaterial代替简单材质,再使用Points模型代替mesh网络模型。

        const material = new THREE.PointsMaterial({
            vertexColors: THREE.VertexColors, 
            size: 10.0
        })
        const points = new THREE.Points(geometry, material)
        scene.add(points)

image.png

可以看见六个点分别着上对应的颜色。

我们可以不换材质,换回网络模型。

        const mesh = new THREE.Mesh(geometry, material)
        scene.add(mesh)

image.png

我们会发现当顶点颜色不同时,在顶点形成面的过程中会出现渐变,两个顶点形成线时会自动在中间自动插入过渡色,看起来就是渐变了。


顶点法向量geometry.attributes.normal


这个是法向量与光照有关,我们先把顶点着色改成全蓝。


之前用的MeshBasicMaterial不受光照影响看不出特别,随便换个MeshPhongMaterial材质好了。


去掉顶点着色,给材质颜色上个蓝色。


挪动一下下面两个点让两个面重合。


然后顺便加上环境光和点光源。

        const vertices = new Float32Array([
            0, 0, 0,
            50, 0, 0,
            0, 100, 0,
            0, 0, 0,
            0, 0, 100,
            50, 0, 0,
        ]);
        geometry.attributes.position = new THREE.BufferAttribute(vertices, 3)
        const material = new THREE.MeshPhongMaterial({
            color: 0x0000ff,
            side: THREE.DoubleSide
        })
        const mesh = new THREE.Mesh(geometry, material)
        scene.add(mesh)
        //环境光
        const ambient = new THREE.AmbientLight(0x444444);
        scene.add(ambient);
        // 点光源
        const point = new THREE.PointLight(0xffffff);
        point.position.set(200, 400, 300); //点光源位置
        scene.add(point); //点光源添加到场景中

image.png

会发现乌漆嘛黑,没有光照效果,颜色都看不见,我们明明加上了光源为什么没有效果呢。


因为用BufferGeometry的话,如果需要用普通材质,想要看到光照效果,必须设置顶点法向量。


设置时沿着三个点顺时针构成面的这面也就是我们看见的正面,让法向量从它们的反面穿过来,这样子正面将会作为光照到的外面。


听不懂就算了直接设置看效果,设置的属性换成normal,这次的三个数代表一个法向量,不知道法向量先学习数学。

        const normals = new Float32Array([
            0, 0, 1, //顶点1法向量
            0, 0, 1, //顶点2法向量
            0, 0, 1, //顶点3法向量
            0, 1, 0, //顶点4法向量
            0, 1, 0, //顶点5法向量
            0, 1, 0, //顶点6法向量
        ]);
        geometry.attributes.normal = new THREE.BufferAttribute(normals, 3)

image.png

设置完就看见了,有棱角,有光照,我们分析一下法向量在哪里。

六个顶点的法向量是这样的,不明白原理知道怎么设置就行了。

image.png

顶点复用geometry.index


就在上面的例子,当两个三角形粘连的时候,每个三角形有两个顶点是重复了的。

因此我们没必要写出6个顶点,只要4个就可以表示同样的内容了。

把重复的顶点删除,再删除对应的法向量。

        const vertices = new Float32Array([
            0, 0, 0,
            50, 0, 0,
            0, 100, 0,
            // 0, 0, 0,
            0, 0, 100,
            // 50, 0, 0,
        ]);
        geometry.attributes.position = new THREE.BufferAttribute(vertices, 3)
        const normals = new Float32Array([
            0, 0, 1, //顶点1法向量
            0, 0, 1, //顶点2法向量
            0, 0, 1, //顶点3法向量
            // 0, 1, 0, //顶点4法向量
            0, 1, 0, //顶点5法向量
            // 0, 1, 0, //顶点6法向量
        ]);
        geometry.attributes.normal = new THREE.BufferAttribute(normals, 3)

然后就是使用我们的geometry.index来表明如何复用顶点。


根据顶点的数量选择类型数组Uint8Array、Uint16Array、Uint32Array。对于顶点索引而言选择整型类型数组,对于非索引的顶点数据,需要使用浮点类型数组Float32Array等。


这里的每个数字代表的是哪个顶点,我们上方设置了4个顶点,计数同数组从0开始,0、1、2三个顶点构成一个三角形,0,3,1三个顶点构成一个三角形。

        const indexes = new Uint16Array([
            0, 1, 2,
            0, 3, 1,
        ])
        geometry.index = new THREE.BufferAttribute(indexes, 1)

image.png

能够显示出六个顶点要的效果,不过感觉连接处有一些粘连,所以可能还是得复用需要组合成一个形状的顶点才好,比如两个三角形拼成一个矩形,为了方便学习就就这么做了,可以自行尝试多加一个顶点在某个面上让三角形成为矩形。

相关文章
|
7月前
|
前端开发 JavaScript 定位技术
threejs绘制风羽
threejs绘制风羽
103 0
|
8月前
|
存储 前端开发 JavaScript
three.js 纹理
纹理是添加到材料中的图像或颜色,以提供更多细节或美感。纹理是Three.js中必不可少的主题。在本节中,我们将了解如何将基本纹理应用于我们的材质。
64 0
|
2月前
Three.js点线几何空间图形代码
Three.js点线几何空间图形代码
15 2
Three.js点线几何空间图形代码
|
7月前
154Echarts - 平行坐标系(Prices and Earnings 2012)
154Echarts - 平行坐标系(Prices and Earnings 2012)
20 0
|
4月前
|
存储 算法 JavaScript
JS算法-三角形最小路径和
JS算法-三角形最小路径和
|
JavaScript
js获取屏幕上圆和椭圆的点坐标
js获取屏幕上圆和椭圆的点坐标
js获取屏幕上圆和椭圆的点坐标
|
11月前
Three.js绘制管
使用Three.js绘制中空的圆柱管道
149 0
|
JavaScript 前端开发 API
|
前端开发 JavaScript API
⚡初识Three.js,在场景中创建一个旋转的正方体~
⚡初识Three.js,在场景中创建一个旋转的正方体~
259 3
⚡初识Three.js,在场景中创建一个旋转的正方体~