参考:http://www.yanhuangxueyuan.com/Three.js_course/face.html
直线模型对象
两个顶点确定一条直线,构造函数THREE.Vector3()可以用来创建一个顶点位置,下面代码中Vector3(10,0,0)表示三维笛卡尔坐标系中顶点坐标(10,0,0), vertices是几何体对象的顶点坐标属性,从Javascript语言的角度看vertices是数组对象,push()是Javascript语言支持的方法, 用于给数组增加元素。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>创建点线面</title>
</head>
<body>
</body>
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script>
var scene = new THREE.Scene();
//创建相机
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 pointlight=new THREE.PointLight(0xFFB400);
pointlight.position.set(200,300,200);
scene.add(pointlight);
//环境光
var ambient=new THREE.AmbientLight(0x0000FF);
scene.add(ambient)
/**
* 创建线条对象
*/
var geometry = new THREE.Geometry();//声明一个空几何体对象
var p1 = new THREE.Vector3(10,0,0);//顶点1坐标
var p2 = new THREE.Vector3(0,20,0);//顶点2坐标
geometry.vertices.push(p1,p2); //顶点坐标添加到geometry对象
var material=new THREE.LineBasicMaterial({
color:0x0000ff //线条颜色
});//材质对象
var line=new THREE.Line(geometry,material);//线条模型对象
scene.add(line);//线条对象添加到场景中
//渲染
var renderer=new THREE.WebGLRenderer();
renderer.setSize(width,height);
renderer.setClearColor(0xFA8072,1)
document.body.appendChild(renderer.domElement);
// renderer.render(scene,camera);
render();
function render(){
renderer.render(scene,camera);
}
/* 开启鼠标事件 */
var control=new THREE.OrbitControls(camera);
control.addEventListener("change",render);
</script>
</html>
效果:
点模型对象
一个顶点生成一个片元区域像素,材质模型参数的属性size表示顶点生成的矩形区域的宽高尺寸,单位是像素。(注:不知道为什么点不显示,侯勋查找原因)
/**
* 创建点对象
*/
var geometry = new THREE.Geometry();//声明一个空几何体对象
var p1 = new THREE.Vector3(10,0,0);//顶点1坐标
var p2 = new THREE.Vector3(0,20,0);//顶点2坐标
var p3 = new THREE.Vector3(15,15,0);//顶点3坐标
geometry.vertices.push(p1,p2,p3); //顶点坐标添加到geometry对象
var material=new THREE.PointsMaterial({
color:0x0000ff,
size:10.0//点对象像素尺寸
});//材质对象
var points=new THREE.Points(geometry,material);//点模型对象
scene.add(points);//点对象添加到场景中
三角面模型对象
/**
* 创建网格模型
*/
var geometry = new THREE.Geometry(); //声明一个空几何体对象
var p1 = new THREE.Vector3(0,0,0); //顶点1坐标
var p2 = new THREE.Vector3(80,0,0); //顶点2坐标
var p3 = new THREE.Vector3(0,80,0); //顶点3坐标
geometry.vertices.push(p1,p2,p3); //顶点坐标添加到geometry对象
var normal = new THREE.Vector3( 0, 0, 1 ); //三角面法向量
var face = new THREE.Face3( 0, 1, 2, normal); //创建三角面
geometry.faces.push( face ); //三角面添加到几何体
var material=new THREE.MeshLambertMaterial({
color:0x0000ff,//三角面颜色
side:THREE.DoubleSide//两面可见
});//材质对象
var mesh=new THREE.Mesh(geometry,material);//网格模型对象
scene.add(mesh);//网格模型添加到场景中
代码解释:THREE.Vector3( 0, 0, 1 )创建了一个顶点法向量,沿着Z轴方向,顶点p1、p2、p3组成的平面位于XOY平面上,说明法向量的方向是对的,平面的法向量垂直于平面本身。 如果实际开发的过程中,设置每一个顶点或者说顶点构成的三角面的法向量,手动设置是非常麻烦的,一般会借助其它的可视化三维软件,或者three.js已经封装了顶点法向量的几何体对象, 比如使用构造函数BoxGeometry、SphereGeometry创建立方体和球体几何体对象,这些几何体除了顶点法位置数据,还包含顶点的法向量数据,不需要手动设置。
使用构造函数BoxGeometry和Mesh创建一个立方体网格模型,实际上它是由至少12个三角面组成,立方体6个面,每个面是2个三角面。使用构造函数THREE.Face3()把任意三个顶点的索引、三个顶点的共用法向量作为参数可以创建一个三角面单元,作为几何体对象属性faces的元素, faces和vertices一样都是一个数组对象。对于立方体而言要创建12个三角面Face3对象,执行语句geometry.faces.push(face)把三角面添加到立方体对应的几何体对象。 构造函数BoxGeometry已经封装12个三角面创建的细节,直接创建几何体对象,无需手动设置三角面的参数。
side是网格材质对象参数的属性,值THREE.DoubleSide表示两面可见,从光照模型的角度看,当三角面法向量与光线方向的夹角大于90度的时候, 顶点法向量的方向只有一个,背光面不会显示,没有任何颜色值
下面的程序首先利用构造函数THREE.Vector3()创建了四个顶点,添加到顶点数组对象vertices中,四个顶点p1、p2、p3、p4会按照push的顺序自动排序,分别标记为0、1、2、3。 顶点0、1、2创建一个三角面,顶点0、2、3创建一个顶点,这里可以看出顶点0,、2共用,不需要创建6个顶点坐标来生成2个三角面。
/**
* 创建矩形平面网格模型
*/
var geometry = new THREE.Geometry(); //声明一个空几何体对象
var p1 = new THREE.Vector3(0,0,0); //顶点1坐标
var p2 = new THREE.Vector3(80,0,0); //顶点2坐标
var p3 = new THREE.Vector3(80,80,0); //顶点3坐标
var p4 = new THREE.Vector3(0,80,0); //顶点4坐标
geometry.vertices.push(p1,p2,p3,p4); //顶点坐标添加到geometry对象
var normal = new THREE.Vector3( 0, 0, 1 ); //三角面法向量
var face0 = new THREE.Face3( 0, 1, 2, normal); //创建三角面0
var face1 = new THREE.Face3( 0, 2, 3, normal); //创建三角面1
geometry.faces.push( face0,face1 ); //三角面添加到几何体
var material=new THREE.MeshLambertMaterial({
color:0x0000ff,//三角面颜色
side:THREE.DoubleSide//两面可见
});//材质对象
var mesh=new THREE.Mesh(geometry,material);//网格模型对象
scene.add(mesh);//网格模型添加到场景中
颜色插值
三维模型的颜色可以通过材质构造函数颜色属性定义,也可以通过顶点颜色数据定义。
1,彩色线条
/**
* 创建线条对象
*/
var geometry = new THREE.Geometry();//声明一个空几何体对象
var p1 = new THREE.Vector3(50,0,0);//顶点1坐标
var p2 = new THREE.Vector3(0,70,0);//顶点2坐标
geometry.vertices.push(p1,p2); //顶点坐标添加到geometry对象
var color1 = new THREE.Color(0xFF0000);//顶点1颜色——红色
var color2 = new THREE.Color(0x0000FF);//顶点3颜色——蓝色
geometry.colors.push(color1, color2);//顶点颜色传入几何体对象
var material=new THREE.LineBasicMaterial({
vertexColors: THREE.VertexColors,//以顶点颜色为准
});//材质对象
var line=new THREE.Line(geometry,material);//线条模型对象
scene.add(line);//线条对象添加到场景中
2,彩色三角形
/**
* 创建网格模型
*/
var geometry = new THREE.Geometry(); //声明一个空几何体对象
var p1 = new THREE.Vector3(0,0,0); //顶点1坐标
var p2 = new THREE.Vector3(80,0,0); //顶点2坐标
var p3 = new THREE.Vector3(0,80,0); //顶点3坐标
geometry.vertices.push(p1,p2,p3); //顶点坐标添加到geometry对象
var face = new THREE.Face3( 0, 1, 2, normal); //创建三角面
/**顶点颜色**/
var color1 = new THREE.Color(0xFF0000);//顶点1颜色——红色
var color2 = new THREE.Color(0x00FF00);//顶点2颜色——绿色
var color3 = new THREE.Color(0x0000FF);//顶点3颜色——蓝色
var normal = new THREE.Vector3( 0, 0, 1 ); //三角面法向量
face.vertexColors.push(color1, color2,color3);//定义三角面三个顶点的颜色
geometry.faces.push( face ); //三角面添加到几何体
var material=new THREE.MeshLambertMaterial({
vertexColors: THREE.VertexColors,//以顶点颜色为准
side:THREE.DoubleSide//两面可见
});//材质对象
var mesh=new THREE.Mesh(geometry,material);//网格模型对象
scene.add(mesh);//网格模型添加到场景中
THREE.Color()
顶点位置数据、法向量数据通过构造函数THREE.Vector3创建,顶点颜色数据通过构造函数THREE.Color()创建,对于创建线条直接把颜色数据插入到colors数组,colors和vertices一样都是几何体的属性,数据类型也一样都是数组对象。对于创建三角面的时候,一般通过三角面对象把顶点颜色数据传递给几何体对象,具体代码参照上面“彩色三角形”代码,vertexColors是三角面的属性,数据类型是数组,用法和colors一样,最终的功能也是一样的。
vertexColors: THREE.VertexColors
材质对象参数的属性vertexColors用来设置,哪一种颜色数据起作用,vertexColors的默认值是THREE.NoColors,表示三维模型的颜色取决材质对象参数的颜色属性color的值,属性vertexColors的值设置为THREE.VertexColors, 三维模型的颜色取决顶点颜色插值后计算出来的结果,如果不定义vertexColors的属性值为THREE.VertexColors,顶点颜色数据不会起作用。
几何体三种渲染方式
构造函数BoxGeometry创建的立方体几何对象,本质上就是顶点的相关数据,使用Point构造函数渲染出点的效果,使用Line()构造函数渲染出线条效果,使用Mesh()构造函数渲染出网格模型效果。
面:
/**
* 创建网格模型
*/
//立方体(长宽高均为100)
var box=new THREE.BoxGeometry(100,100,100);
var material=new THREE.MeshLambertMaterial({color:0x0000ff});//材质对象
var mesh=new THREE.Mesh(box,material);//网格模型对象
scene.add(mesh);//网格模型添加到场景中
线:
THREE.Line、THREE.LineLoop、THREE.LineSegments三个构造函数定义的是描点划线的方式,对应WebGL中的绘制模式mode,初学的时候不用深究,有个影响即可, 对于LineSegments方式而言,两个点确定一条直线,四个点确定2条直线;对于Line方式,四个点可以连续绘制出3条直线;对于LineLoop方式,与line模式基本一样,最后会产生闭合, 四个点可以连续绘制出4条直线。
/**
* 创建线模型
*/
//立方体(长宽高均为100)
var box=new THREE.BoxGeometry(100,100,100);
var material=new THREE.LineBasicMaterial({color:0x0000ff});//材质对象
var mesh=new THREE.Line(box,material);//线模型对象(连续绘制)
var mesh=new THREE.LineLoop(box,material);//线模型对象(连续闭合绘制)
var mesh=new THREE.LineSegments(box,material);//线模型对象(断续绘制)
scene.add(mesh);//线模型添加到场景中
点
点:(不知道为什么渲染不出来点)
/**
* 创建点模型
*/
//立方体(长宽高均为100)
var box=new THREE.BoxGeometry(100,100,100);
var material=new THREE.PointsMaterial({
color:0x0000ff,
size:10
});//材质对象
var mesh=new THREE.Points(box,material);//点模型对象
scene.add(mesh);//点模型添加到场景中