three.js(3):点、线、面(颜色插值,几何体三种渲染方式)

参考: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);//点模型添加到场景中

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值