原理
架构
概念
一 场景
三维场景,画好的、需要去渲染的东西,类似于现实生活中用相机要去拍的东西(场景)。包括模型和光照,画了模型不添加光照的话,模型都是黑色的。
var scene = new THREE.Scene();
(一)模型
包括点模型、线模型、网格模型。都是由几何体Geometry和材质Material构成的,区别在于对几何体顶点数据的渲染方式不同。
1 点模型
画几何体的顶点,使用点材质PointsMaterial。
// 创建一个立方体几何对象Geometryvar geometry = new THREE.BoxGeometry(100, 100, 100);// 点材质对象var material = new THREE.PointsMaterial({color: 0xff0000,size: 5.0, //点对象像素尺寸});// 点模型对象var points = new THREE.Points(geometry, material);scene.add(points);
2 线模型
画几何体的线条:直接使用预置的几何体,然后画它的线条。
// 创建一个立方体几何对象Geometryvar geometry = new THREE.BoxGeometry(100, 100, 100);// 线材质对象 实线或虚线var material=new THREE.LineBasicMaterial({color:0xff0000, // 线条颜色});// 线模型对象 构造函数:Line、LineLoop、LineSegmentsvar line=new THREE.Line(geometry,material);scene.add(line);
画直线:
通过Vector3定义几个顶点,然后通过geometry.vertices.push(p1, p2)将顶点坐标添加到geometry对象,然后生成一个线条对象。
// 声明一个几何体对象Geometryvar geometry = new THREE.Geometry();// 声明两个顶点var p1 = new THREE.Vector3(50, 0, 0);var p2 = new THREE.Vector3(0, 70, 0);// 顶点坐标添加到geometry对象geometry.vertices.push(p1, p2);// 线材质var material = new THREE.LineBasicMaterial({color: 0xffff00,});// 线条模型对象var line = new THREE.Line(geometry, material);// 线条对象添加到场景中scene.add(line);
通过Vector3定义几个顶点,然后用LineCurve或LineCurve3生成一个直线,然后通过LineCurve.getPoints(10)获取这个直线的顶点,通过geometry.setFromPoints(pointArr);将顶点添加到geometry对象,然后生成一条直线。
// 声明一个几何体对象Geometryvar geometry = new THREE.Geometry();// 声明两个顶点var p1 = new THREE.Vector3(50, 0, 0);var p2 = new THREE.Vector3(0, 70, 0);// 三维直线LineCurve3var LineCurve3 = new THREE.LineCurve3(p1, p2);// 二维直线LineCurvevar LineCurve2 = new THREE.LineCurve(new THREE.Vector2(50, 0), new THREE.Vector2(0, 70));// 获取直线的点数组var pointArr = LineCurve2.getPoints(10);// 点数组赋给几何体对象geometry.setFromPoints(pointArr);// 线材质var material = new THREE.LineBasicMaterial({color: 0xffff00,});// 线条模型对象var line = new THREE.Line(geometry, material);// 线条对象添加到场景中scene.add(line);
画圆弧:通过ArcCurve方法绘制一个圆弧,然后获取圆弧的顶点坐标,赋值给几何体对象
// 声明一个几何体对象Geometryvar geometry = new THREE.Geometry();// 参数:0, 0圆弧坐标原点x,y 100:圆弧半径 0, 2 * Math.PI:圆弧起始角度var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);// getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组// 分段数50,返回51个顶点var points = arc.getPoints(50);// setFromPoints方法从points中提取数据改变几何体的顶点属性verticesgeometry.setFromPoints(points);// 线材质var material = new THREE.LineBasicMaterial({color: 0xffff00,});// 线条模型对象var line = new THREE.Line(geometry, material);// 线条对象添加到场景中scene.add(line);
画样条曲线:设置几个顶点,用CatmullRomCurve3画出曲线,获取到更多顶点,然后构建一个几何体
// 声明一个几何体对象Geometryvar geometry = new THREE.Geometry();// 三维样条曲线 Catmull-Rom算法var curve = new THREE.CatmullRomCurve3([new THREE.Vector3(-50, 20, 90),new THREE.Vector3(-10, 40, 40),new THREE.Vector3(0, 0, 0),new THREE.Vector3(60, -60, 0),new THREE.Vector3(70, 0, 80)]);//getPoints是基类Curve的方法,返回一个vector3对象作为元素组成的数组// 分段数100,返回101个顶点var points = curve.getPoints(100);// setFromPoints方法从points中提取数据改变几何体的顶点属性verticesgeometry.setFromPoints(points);// 线材质var material = new THREE.LineBasicMaterial({color: 0xffff00,});// 线条模型对象var line = new THREE.Line(geometry, material);// 线条对象添加到场景中scene.add(line);
画贝塞尔曲线
// 声明一个几何体对象Geometryvar geometry = new THREE.Geometry();// 三次贝赛尔曲线的参数p1、p4是起始点,p2、p3是控制点,控制点不在贝塞尔曲线上var p1 = new THREE.Vector3(-80, 0, 0);var p2 = new THREE.Vector3(-40, 100, 0);var p3 = new THREE.Vector3(40, 100, 0);var p4 = new THREE.Vector3(80, 0, 0);// 三维三次贝赛尔曲线var curve = new THREE.CubicBezierCurve3(p1, p2, p3, p4);//getPoints是基类Curve的方法,返回一个vector3对象作为元素组成的数组// 分段数100,返回101个顶点var points = curve.getPoints(100);// setFromPoints方法从points中提取数据改变几何体的顶点属性verticesgeometry.setFromPoints(points);// 线材质var material = new THREE.LineBasicMaterial({color: 0xffff00,});// 线条模型对象var line = new THREE.Line(geometry, material);// 线条对象添加到场景中scene.add(line);
多个线条组合
// 声明一个几何体对象Geometryvar geometry = new THREE.Geometry();// 绘制一个U型轮廓var R = 80;// 画一段圆弧var arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, true);// 半圆弧的一个端点作为直线的一个端点var line1 = new THREE.LineCurve(new THREE.Vector2(R, 200, 0), new THREE.Vector2(R, 0, 0));var line2 = new THREE.LineCurve(new THREE.Vector2(-R, 0, 0), new THREE.Vector2(-R, 200, 0));// 创建组合曲线对象CurvePathvar CurvePath = new THREE.CurvePath();// 把多个线条插入到CurvePath中CurvePath.curves.push(line1, arc, line2);// 分段数200var points = CurvePath.getPoints(200);// setFromPoints方法从points中提取数据改变几何体的顶点属性verticesgeometry.setFromPoints(points);// 材质对象var material = new THREE.LineBasicMaterial({color: 0x000000});// 线条模型对象var line = new THREE.Line(geometry, material);// 线条对象添加到场景中scene.add(line);
3 网格模型
(1)几何体
长方体、球体、圆柱、正八面体、正十二面体、正二十面体
// 创建一个立方体var geometry = new THREE.BoxGeometry(100, 100, 100);// 材质对象var material = new THREE.MeshLambertMaterial({color: 0x0000ff,opacity: 0.7,transparent: true,});// 网格模型对象Meshvar mesh = new THREE.Mesh(geometry, material);// 网络模型添加到场景中scene.add(mesh);
曲线路径管道:由一条曲线生成一个管道
// 创建多段线条的顶点数据var p1 = new THREE.Vector3(-85.35, -35.36)var p2 = new THREE.Vector3(-50, 0, 0);var p3 = new THREE.Vector3(0, 50, 0);var p4 = new THREE.Vector3(50, 0, 0);var p5 = new THREE.Vector3(85.35, -35.36);// 创建线条一:直线let line1 = new THREE.LineCurve3(p1,p2);// 创建线条2:三维样条曲线var curve = new THREE.CatmullRomCurve3([p2, p3, p4]);// 创建线条3:直线let line2 = new THREE.LineCurve3(p4,p5);// 创建CurvePath对象var CurvePath = new THREE.CurvePath();// 插入三段线条CurvePath.curves.push(line1, curve, line2);//通过多段曲线路径创建生成管道var geometry = new THREE.TubeGeometry(CurvePath, 100, 5, 25, false);// 材质对象var materialg = new THREE.LineBasicMaterial({color: 0xffff00});// 创建网格模型对象var mesh = new THREE.Mesh(geometryg, material);// 设置网络模型位置mesh.position.set(100, 100, 100);// 网络模型添加到场景中scene.add(mesh);
旋转成形:由几个顶点旋转360度生成一个几何体
// 定义几个顶点var points = [new THREE.Vector2(50,60),new THREE.Vector2(25,0),new THREE.Vector2(50,-60)];// 旋转生成一个几何体var geometry = new THREE.LatheGeometry(points,30);// 材质var material=new THREE.MeshPhongMaterial({color: 0x0000ff, // 三角面颜色side: THREE.DoubleSide, // 两面可见});// 线条模式渲染:true-看到细分的三角形 false-看到设置的颜色material.wireframe = true;// 创建网格模型对象var mesh = new THREE.Mesh(geometryg, material);// 设置网络模型位置mesh.position.set(100, 100, 100);// 网络模型添加到场景中scene.add(mesh);
轮廓填充:填充一个由多条曲线组成的2D图形
// 圆弧与直线连接// Shape对象var shape = new THREE.Shape();var R = 50;// 绘制一个半径为R、圆心坐标(0, 0)的半圆弧shape.absarc(0, 0, R, 0, Math.PI);// 从圆弧的一个端点(-R, 0)到(-R, -200)绘制一条直线shape.lineTo(-R, -200);// 绘制一个半径为R、圆心坐标(0, -200)的半圆弧shape.absarc(0, -200, R, Math.PI, 2 * Math.PI);// 从圆弧的一个端点(R, -200)到(-R, -200)绘制一条直线shape.lineTo(R, 0);var geometry = new THREE.ShapeGeometry(shape, 30);// 材质var material=new THREE.MeshPhongMaterial({color: 0x0000ff,side: THREE.DoubleSide, // 两面可见});// 创建网格模型对象var mesh = new THREE.Mesh(geometryg, material);// 网络模型添加到场景中scene.add(mesh);
拉伸扫描成型:将一个2D图形按照一条3D曲线进行拉伸扫描,生成一个几何体
var shape = new THREE.Shape();// 四条直线绘制一个矩形轮廓shape.moveTo(0,0);shape.lineTo(0,10);shape.lineTo(10,10);shape.lineTo(10,0);shape.lineTo(0,0);// 创建轮廓的扫描轨迹(3D样条曲线)var curve = new THREE.SplineCurve3([new THREE.Vector3( -10, -50, -50 ),new THREE.Vector3( 10, 0, 0 ),new THREE.Vector3( 8, 50, 50 ),new THREE.Vector3( -5, 0, 100)]);// 将矩形轮廓按照扫描轨迹进行拉伸var geometry = new THREE.ExtrudeGeometry(shape,{bevelEnabled: false, // 无倒角extrudePath: curve, // 选择扫描轨迹steps: 50, // 扫描方向细分数});// 材质var material=new THREE.MeshPhongMaterial({color: 0x0000ff,side: THREE.DoubleSide, // 两面可见});// 创建网格模型对象var mesh = new THREE.Mesh(geometryg, material);// 网络模型添加到场景中scene.add(mesh);
(2)材质
基础网格材质
- 与光照产生漫反射的材质
- 高光材质
-
(二)光照
对自然界光照的模拟,就像摄影师拍照时设置各种辅助灯光一样。不同的光源、不同的光照强度实现的渲染效果不同。

环境光
- 点光源
- 平行光
- 聚光源
// 点光源var point = new THREE.PointLight(0xffffff);// 点光源位置point.position.set(400, 200, 300);// 点光源添加到场景中scene.add(point);// 环境光var ambient = new THREE.AmbientLight(0x444444);// 环境光添加到场景中scene.add(ambient);
二 相机
一个虚拟的相机,需要设置位置、角度、投影方式。// 窗口宽度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);// body元素中插入canvas对象document.body.appendChild(renderer.domElement);// 执行渲染操作function render() {// 指定场景、相机作为参数renderer.render(scene,camera);requestAnimationFrame(render);}render();// 创建控件对象 监听鼠标操作// 需引入OrbitControls.js文件var controls = new THREE.OrbitControls(camera,renderer.domElement);
示例

