1.在body下引入THREE.js
// 根据自己的路径写src,js文件在build 文件夹下
<script src="../three.js-r102/build/three.js"></script>
<script>
// 在这创建场景
</script>
2.设置style
body {margin :0;}
canvas {width: 100%;height: 100%;}
一个渲染场景需要的三大件:场景、相机、渲染器,这样我们就能透过摄像机渲染出场景。
<script>
// 创建 场景 相机 渲染器
var scene, renderer, camera;
// 创建场景
function createScene() {
scene = new THREE.Scene();
}
// 创建相机
function createCamera() {
// PerspectiveCamera(视野角度, 长宽比, 近切面, 远切面)
camera = new THREE.PerspectiveCamera(75, window.innerWidth/innerHeight, 0.1, 1000);
// 设置相机的位置方法 camera.position.set(x, y, z)
camera.position.set(0, 0, 15);
// 设置相机的焦点
camera.lookAt(0,0,0);
}
// 创建渲染器
function createRenderer() {
renderer = new THREE.WebGLRender();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
</script>
THREE.js内置了两种几何体类型,Geometry(普通几何体) 和 BufferGeometry(缓冲类型几何体),它们两个的区别是:BufferGeometry存储的都是一些原始的数据,性能比Geometry的性能高,很适合存储一些放入场景内不需要再额外操作的模型。而Geometry的优势刚好相反,Geometry比BufferGeometry更友好,使用了Three.js提供的THREE.Vector3或者THREE.Color这样的对象来存储数据(顶点位置,面,颜色等),这些对象易于阅读和编辑,但效率低于BufferGeometry使用的类型化数组。
所以,我们可以根据项目的大小来使用不同的几何体,小项目,可以使用Geometry实现,中大型的项目,还是推荐BufferGeometry。
//实例化一个Geometry对象
var geo = new THREE.Geometry();
//调用对象的fromBufferGeometry方法,并将需要转换的bufferGeometry传入
geo.fromBufferGeometry(bufferGeometry);
//geo为转换转换成的Geometry
//实例化一个BufferGeometry对象
var bufferGeo = new THREE.BufferGeometry();
//调用对象的fromGeometry方法,并将需要转换的Geometry传入
bufferGeo.fromGeometry(geometry);
//bufferGeo为geometry转换转换成的BufferGeometry
// 创建立方体
var geometry, material, cube;
function createGeometry() {
// new THREE.BoxGeometry(宽, 高, 深, [沿宽度的分隔面的数量], [沿高度的分隔面的数量], [沿深度的分隔面的数量])
// 创建一个几何体
geometry = new THREE.BoxGeometry(5, 10, 15);
// 创建一个材质
material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 模型 = 几何体 + 材质
cube = new THREE.Mesh(geometry, material);
// 物体默认坐标 (0,0,0)
scene.add(cube);
}
// 创建动画
function animate() {
// requestAnimatinFrame(); 请求动画帧 API
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.02;
// 渲染场景
renderer.render(scene, camera);
}
// 1.圆形平面
var circle = new THREE.CircleGeometry(5, 32);
// 构造函数
CircleGeometry(半径, 段数, [第一段起始角度], [圆形扇形的中心角])
// 2.圆锥
var cone= new THREE.ConeGeometry(5,10,32);
// 构造函数
ConeGeometry(半径, 圆锥高度, [圆锥表面的段数,越高越圆滑], [高度方向的段数],[底部显示或隐藏,默认是false-显示], [第一段的起始角度], [中心角,默认是2*PI]]);
// 3.圆柱
var cylinder = new THREE.CylinderGeometry();
// 构造函数
CylinderGeometry(顶部圆柱体半径, 底部圆柱体半径, 高度, [圆柱表面分段数], [高度分段数], [圆柱体两端是否显示], [第一段的起始角度], [中心角,默认是2*PI] );
// 4.球
var sphere = new THREE.SphereGeometry(5,32,32);
// 构造函数
SphereGeometry(半径, 水平线段数量, 垂直段的数量, [水平起始角度],[水平角度大小], [垂直起始角度], [垂直角度大小]);
// 5.平面
var plane = new THREE.PlaneGeometry(5,10,32);
// 构造函数
PlaneGeometry(宽度, 长度, [宽的分段数], [长度的分段数])
// 6.圆环
var torus = new THREE.TorusGeometry(10,5);
// 构造函数
ToursGeometry(圆环半径, 管道半径, [横向分段,,默认8], [纵向分段,默认6], [绘制弧度,默认2*PI])
// 创建线条
var geometry, material, line;
function createGeometry() {
geometry = new THREE.Geometry();
// 创建顶点
// 线是画在每一对连续的顶点之间的,而不是在第一个顶点和最后一个顶点之间绘制线条(线条并未闭合)
geometry.vertices.push(new THREE.Vector3(-10, 0, 0));
geometry.vertices.push(new THREE.Vector3(0, 10, 0));
geometry.vertices.push(new THREE.Vector3(10, 0, 0));
geometry.vertices.push(new THREE.Vector3(20, 30, 10));
material1 = new THREE.LineDashedMaterial({
color: 0x0000ff
});
line = new THREE.Line(geometry1, material1);
scene.add(line);
}
var texture = new THREE.TextureLoader().load( "文件路径" );
material.map = texture; //将纹理赋值给材质
texture.wrapS = THREE.RepeatWrapping; //设置水平方向无限循环
texture.wrapT = THREE.RepeatWrapping; //设置垂直方向无限循环
// 设置纹理的重复
texture.repeat.set( 4, 4 ); //水平方向和垂直方向都重复四次
var material = new THREE.MeshBasicMaterial({color:0x00ffff});
// 可以修改材质的颜色,方法一
material.color.set(0xff00ff)
// 方法二:修改材质的颜色,支持十六进制数,字符串,RGB字符串,颜色字符串,HSL字符串,
material.color = new THREE.Color("#ff0000")
var geometry = new THREE.BoxGeometry(1, 1, 1);
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
material = new THREE.MeshNormalMaterial();
lineMaterial = new THREE.LineBasicMaterial({color:0x00ff00}); // 线条材质
var pointsArr = [
new THREE.Vector3( -10, 0, -5 ),
new THREE.Vector3( -5, 15, 5 ),
new THREE.Vector3( 20, 15, -5 ),
new THREE.Vector3( 10, 0, 5 )
];
//指定一些用于生成曲线线的三维顶点
var curve = new THREE.CatmullRomCurve3(pointsArr);
var points = curve.getPoints( 50 ); //使用getPoints获取当前曲线分成50段后的所有顶点
var curveGeometry = new THREE.BufferGeometry().setFromPoints( points ); //使用顶点生成几何体
var curveMaterial = new THREE.LineDashedMaterial( { color : 0xff0000 } ); //创建一条红色的线材质
// 使用THREE.Line创建线
curveLine = new THREE.Line( curveGeometry, curveMaterial );
curveLine.computeLineDistances(); //需要重新计算位置才能显示出虚线
scene.add(curveLine);
material = new THREE.MeshLambertMaterial({color:0x00ffff});
material = new THREE.MeshPhongMaterial({color:0x00ffff}); //创建材质
// 属性: 高光颜色:material.specular 高光贴图: material.specularMap
material = new THREE.MeshStandardMaterial({color:0x00ffff}); //创建材质
/*
属性:
金属度:material.metalness 金属贴图:material.metalnessMap
粗糙度: material.roughness 粗糙度贴图: material.roughnessMap
*/
倘若需要从外部文件里载入几何体或是纹理贴图,由于浏览器same origin policy(同源策略)的安全限制,从本地文件系统载入外部文件将会失败,同时抛出安全性异常。
解决方法:
在本地的服务器运行文件
http://localhost/文件地址
1.灯光种类
var light = new THREE.AmbientLight(0x00ffff);
scene.add(light);
var light = new THREE.DirectionalLight(0x00ffff, 1.5);
// 设置灯光的 颜色 强度 位置 朝向
light.color.set(0xff00ff); // 设置颜色
light.intensity = 1.2; // 设置强度
light.position.set(10, 10, 10); // 设置位置
light.target.set(10, 0, 0) // 设置目标点
scene.add(light);
var pointLight = new THREE.PointLight(0xff0000, 1, 100, 2); // 创建一个白色的点光源
pointLight.position.set( 50, 50, 50 );
// 设置灯光衰减
pointLight.decay = 1.0 // 设置衰减
scene.add( pointLight );
var spotLight = new THREE.SpotLight(0xffffff, 2.0, 100, Math.PI/4, 0.5, 2);
spotLight.color.set(0x000000); // 修改光照颜色
spotLight.intensity = 0.5; // 修改光的强度
spotLight.distance = 50; // 修改光的照射范围
spotLight.angle = Math.PI/3; // 修改光的照射弧度
spotLight.penumbra = 1.0; // 修改交界过渡
spotLight.decay = 1.0; // 修改衰减度
spotLight.target.set(0, 1, 1); // 修改照射方向
var hemisphereLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
hemisphereLight.color.set(0xffffff); //将天空颜色修改为白色
hemisphereLight.groundColor.set(0x000000); //将地面颜色修改为黑色
scene.add(hemisphereLight);
2.添加阴影效果
renderer.shadowMap.enabled = true;
var light = new THREE.DirectionalLight("#ffffff");
light.castShadow = true; // 设置平行光投射投影
scene.add(directionalLight);
sphere.castShadow = true; // 圆球产生阴影
scene.add(sphere);
cube.castShadow = true; // 立方体产生阴影
scene.add(cube);
plane.receiveShadow = true; // 平面接收阴影
scene.add(plane);
directionalLight.shadow.camera.near = 20; // 产生阴影的最近距离
directionalLight.shadow.camera.far = 100; // 产生阴影的最远距离
directionalLight.shadow.camera.left = -50; // 产生阴影距离位置的最左边位置
directionalLight.shadow.camera.right = 50; // 最右边
directionalLight.shadow.camera.top = 50; // 最上边
directionalLight.shadow.camera.bottom = -50; // 最下面
//这两个值决定生成阴影密度 默认512
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.mapSize.width = 1024;
// 相机朝向原点
camera.target = new THREE.Vector3(0, 0, 0);
// 或者
camera.lookAt(new THREE.Victor3(0, 0, 0));
var mesh = new THREE.Mesh(geometry, material);
camera.target = mesh.position;
//或者
camera.lookAt(mesh.position);
var orthographicCamera = new THREE.OrthograthicCamera(-5, 5, -4,4,8,-8)
// 相机显示的内容需要和窗口显示的内容同样的比例才能不被拉伸
var frustumSize = 1000; // 设置显示相机前方1000高的内容
var aspect = window.innerWidth / window.innerHeight; //计算场景的宽高比
var orthographicCamera = new THREE.OrthographicCamera( frustumSize * aspect / 5, frustumSize * aspect / -5, frustumSize / -4, frustumSize / 4, 1, 2000 ); // 根据比例计算出left,top,right,bottom的值
var frustumSize = 1000; //设置显示相机前方1000高的内容
var aspect = window.innerWidth / window.innerHeight; //计算场景的宽高比
var orthographicCamera = new THREE.OrthographicCamera(); //实例化一个空的正交相机
orthographicCamera.left = frustumSize * aspect / - 2; //设置left的值
orthographicCamera.right = frustumSize * aspect / 2; //设置right的值
orthographicCamera.top = frustumSize / 2; //设置top的值
orthographicCamera.bottom = frustumSize / - 2; //设置bottom的值
orthographicCamera.near = 1; //设置near的值
orthographicCamera.far = 2000; //设置far的值
//注意,最后一定要调用updateProjectionMatrix()方法更新