Three.js学习02

提示:本系列文章参考http://www.webgl3d.cn/Three.js/的three.js教程。


前言

本篇主要介绍几何体的顶点、法向量,重复的顶点可以使用索引。


一、顶点

1.几何体由三角形构成,三角形由3个顶点构成面

首先明确几何体都由三角形构成,两个三角形拼成一个矩形平面。比如一个立方体网格模型由6个矩形构成。
球体网格模型也是通过三角形构成一个球面,三角形数量越多,网格模型表面越接近于球形。
那么我们只需要构建出一个个三角形即可。
在这里插入图片描述
我们通过坐标直接刻画出三角形的顶点,三个顶点为一组,网格模型就可以构建成一个三角形。

var geometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
//类型数组创建顶点数据
var vertices = new Float32Array([
  0, 0, 0, //顶点1坐标
  50, 0, 0, //顶点2坐标
  0, 100, 0, //顶点3坐标
  0, 0, 10, //顶点4坐标
  0, 0, 100, //顶点5坐标
  50, 0, 10, //顶点6坐标
]);
// 创建属性缓冲区对象
var attribue = new THREE.BufferAttribute(vertices, 3); //3个为一组,表示一个顶点的xyz坐标
// 设置几何体attributes属性的位置属性
geometry.attributes.position = attribue;

我们通过坐标直接刻画出三角形的顶点,三个顶点为一组,网格模型就可以构建成一个三角形。

// 三角面(网格)渲染模式
var material = new THREE.MeshBasicMaterial({
  color: 0x0000ff, //三角面颜色
  side: THREE.DoubleSide //两面可见
}); //材质对象
var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh

如果用点模型只反映顶点,不显示线和面。

// 点渲染模式
var material = new THREE.PointsMaterial({
  color: 0xff0000,
  size: 10.0 //点对象像素尺寸
}); //材质对象
var points = new THREE.Points(geometry, material); //点模型对象
scene.add(points); //点对象添加到场景中

如果用线模型只反映顶点构成的线条,不显示面。

// 线条渲染模式
var material=new THREE.LineBasicMaterial({
    color:0xff0000 //线条颜色
});//材质对象
var line=new THREE.Line(geometry,material);//线条模型对象
scene.add(line);//线条对象添加到场景中

2.顶点法向量

2.1 不设置顶点法向量

不设置顶点法向量则在分界位置没有棱角感(如果各顶点颜色不一致则各顶点的面自动形成渐变的颜色效果)
效果如下:
在这里插入图片描述
代码如下:

<script>
    /**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene();
    var geometry = new THREE.BufferGeometry(); //声明一个缓冲几何体对象

    //类型数组创建顶点位置position数据
    var vertices = new Float32Array([
        0, 0, 0, //顶点1坐标
        50, 0, 0, //顶点2坐标
        0, 100, 0, //顶点3坐标

        0, 0, 0, //顶点4坐标
        0, 0, 100, //顶点5坐标
        50, 0, 0, //顶点6坐标
    ]);
    // 创建属性缓冲区对象
    var attribue = new THREE.BufferAttribute(vertices, 3); //3个为一组,作为一个顶点的xyz坐标
    // 设置几何体attributes属性的位置position属性
    geometry.attributes.position = attribue;
    //类型数组创建顶点颜色color数据
    var colors = new Float32Array([
        1, 0, 0, //顶点1颜色
        1, 0, 0, //顶点2颜色
        1, 0, 0, //顶点3颜色

        1, 0, 0, //顶点4颜色
        1, 0, 0, //顶点5颜色
        1, 0, 0, //顶点6颜色
    ]);
    // 设置几何体attributes属性的颜色color属性
    geometry.attributes.color = new THREE.BufferAttribute(colors, 3); //3个为一组,表示一个顶点的颜色数据RGB
    //材质对象
    var material = new THREE.PointsMaterial({
        // 使用顶点颜色数据渲染模型,不需要再定义color属性
        // color: 0xff0000,
        vertexColors: THREE.VertexColors, //以顶点颜色为准
        size: 10.0 //点对象像素尺寸
    });
    // 点渲染模式  点模型对象Points
    var points = new THREE.Mesh(geometry, material); //点模型对象
    scene.add(points); //点对象添加到场景

    // 辅助坐标系  参数250表示坐标系大小,可以根据场景大小去设置
    var axesHelper = new THREE.AxesHelper(1000);
    scene.add(axesHelper);

    /**
     * 相机设置
     */
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度
    var k = width / height; //窗口宽高比
    var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(200, 300, 200); //设置相机位置
    camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);//设置渲染区域尺寸
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

    function render() {
        renderer.render(scene,camera);//执行渲染操作
        // mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
        requestAnimationFrame(render);//请求再次执行渲染函数render
    }
    render();
    var controls = new THREE.OrbitControls(camera,renderer.domElement);//创建控件对象
    // 已经通过requestAnimationFrame(render);周期性执行render函数,没必要再通过监听鼠标事件执行render函数
    // controls.addEventListener('change', render)
</script>

2.2 添加法向量使光源参与光照计算

添加法向量可以使点光源、平行光等带有方向性的光源参与光照计算,在分界位置有棱角感。

var 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法向量
    ]);
    // 设置几何体attributes属性的位置normal属性
    geometry.attributes.normal = new THREE.BufferAttribute(normals, 3); //3个为一组,表示一个顶点的法向量数据

效果如下,
在这里插入图片描述

2.3 添加法向量没有效果的问题

为什么没有显示效果,一个可能是材质的问题,材质THREE.MeshBasicMaterial可能不反射光,需要调整材质对象为MeshPhongMaterial。
在这里插入图片描述

另一个可能是光源的照射角度问题,需要调整光源位置。

3.重复的顶点数据可以用顶点索引

三角形有顶点位置重复,重复的顶点位置数据、顶点法向量数据只需要定义1个就可以。通过顶点索引组织顶点数据,顶点索引数组indexes通过索引值指向顶点位置
geometry.attributes.position、顶点法向量geometry.attributes.normal中顶面数组。

如之前的矩形由两个三角形构成,顶点4、5重复,只需创建4个顶点和4个法向量即可,利用Uint16Array类型数组创建顶点索引数据, Uint16Array([ 0, 1, 2, 0, 2, 3,])内表示了012和023两个三角形,再将索引赋值给几何体的index属性。
顶点索引数组当然是整型,可以使用Uint16Array也可以选择其他整型数组。顶点数组需要使用浮点类型。

代码如下:

/**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene();
    var geometry = new THREE.BufferGeometry(); //声明一个空几何体对象
    //类型数组创建顶点位置position数据
    var vertices = new Float32Array([
        0, 0, 0, //顶点1坐标
        80, 0, 0, //顶点2坐标
        80, 80, 0, //顶点3坐标

        /*0, 0, 0, //顶点4坐标   和顶点1位置相同
        80, 80, 0, //顶点5坐标  和顶点3位置相同*/
        0, 80, 0, //顶点6坐标
    ]);

    // 创建属性缓冲区对象
    var attribue = new THREE.BufferAttribute(vertices, 3); //3个为一组

    // 设置几何体attributes属性的位置position属性
    geometry.attributes.position = attribue

    var normals = new Float32Array([
        0, 0, 1, //顶点1法向量
        0, 0, 1, //顶点2法向量
        0, 0, 1, //顶点3法向量

        /*0, 0, 1, //顶点4法向量
        0, 0, 1, //顶点5法向量*/
        0, 0, 1, //顶点6法向量
    ]);
    // 设置几何体attributes属性的位置normal属性
    geometry.attributes.normal = new THREE.BufferAttribute(normals, 3); //3个为一组,表示一个顶点的xyz坐标

    // Uint16Array类型数组创建顶点索引数据
    var indexes = new Uint16Array([
        // 0对应第1个顶点位置数据、第1个顶点法向量数据
        // 1对应第2个顶点位置数据、第2个顶点法向量数据
        // 索引值3个为一组,表示一个三角形的3个顶点
        0, 1, 2,
        0, 2, 3,
    ])
    // 索引数据赋值给几何体的index属性
    geometry.index = new THREE.BufferAttribute(indexes, 1); //1个为一组

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值