原理
架构
概念
一 场景
三维场景,画好的、需要去渲染的东西,类似于现实生活中用相机要去拍的东西(场景)。包括模型和光照,画了模型不添加光照的话,模型都是黑色的。
var scene = new THREE.Scene();
(一)模型
包括点模型、线模型、网格模型。都是由几何体Geometry和材质Material构成的,区别在于对几何体顶点数据的渲染方式不同。
1 点模型
画几何体的顶点,使用点材质PointsMaterial。
// 创建一个立方体几何对象Geometry
var 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 线模型
画几何体的线条:直接使用预置的几何体,然后画它的线条。
// 创建一个立方体几何对象Geometry
var geometry = new THREE.BoxGeometry(100, 100, 100);
// 线材质对象 实线或虚线
var material=new THREE.LineBasicMaterial({
color:0xff0000, // 线条颜色
});
// 线模型对象 构造函数:Line、LineLoop、LineSegments
var line=new THREE.Line(geometry,material);
scene.add(line);
画直线:
通过Vector3定义几个顶点,然后通过geometry.vertices.push(p1, p2)将顶点坐标添加到geometry对象,然后生成一个线条对象。
// 声明一个几何体对象Geometry
var 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对象,然后生成一条直线。
// 声明一个几何体对象Geometry
var geometry = new THREE.Geometry();
// 声明两个顶点
var p1 = new THREE.Vector3(50, 0, 0);
var p2 = new THREE.Vector3(0, 70, 0);
// 三维直线LineCurve3
var LineCurve3 = new THREE.LineCurve3(p1, p2);
// 二维直线LineCurve
var 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方法绘制一个圆弧,然后获取圆弧的顶点坐标,赋值给几何体对象
// 声明一个几何体对象Geometry
var 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中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
// 线材质
var material = new THREE.LineBasicMaterial({
color: 0xffff00,
});
// 线条模型对象
var line = new THREE.Line(geometry, material);
// 线条对象添加到场景中
scene.add(line);
画样条曲线:设置几个顶点,用CatmullRomCurve3画出曲线,获取到更多顶点,然后构建一个几何体
// 声明一个几何体对象Geometry
var 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中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
// 线材质
var material = new THREE.LineBasicMaterial({
color: 0xffff00,
});
// 线条模型对象
var line = new THREE.Line(geometry, material);
// 线条对象添加到场景中
scene.add(line);
画贝塞尔曲线
// 声明一个几何体对象Geometry
var 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中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
// 线材质
var material = new THREE.LineBasicMaterial({
color: 0xffff00,
});
// 线条模型对象
var line = new THREE.Line(geometry, material);
// 线条对象添加到场景中
scene.add(line);
多个线条组合
// 声明一个几何体对象Geometry
var 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));
// 创建组合曲线对象CurvePath
var CurvePath = new THREE.CurvePath();
// 把多个线条插入到CurvePath中
CurvePath.curves.push(line1, arc, line2);
// 分段数200
var points = CurvePath.getPoints(200);
// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.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,
});
// 网格模型对象Mesh
var 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);
示例