提示:本系列文章参考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个为一组