Three.js
01-three.js
1.three.js资源
GitHub:https://github.com/mrdoob/three.js
官网:https://threejs.org/
相关库:
库 | 功能 |
---|---|
Physijs | Physijs是一款物理引擎,可以协助基于原生WebGL或使用three.js创建模拟物理现象,比如重力下落、物体碰撞等物理现 |
stats.js | JavaScript性能监控器,同样也可以测试webgl的渲染性能 |
dat.gui | 轻量级的icon形用户界面框架,可以用来控制Javascript的变量,比如WebGL中一个物体的尺寸、颜色 |
tween.js | 借助tween.js快速创建补间动画,可以非常方便的控制机械、游戏角色运动 |
ThreeBSP | 可以作为three.js的插件,完成几何模型的布尔,各类三维建模软件基本都有布尔的概念 |
2.学习three.js与webGl
Threejs是基于原生WebGl API和着色器封装得到的3D引擎,也就是一个js库。通过原生WebGL直接编写程序,会比较麻烦,一般开发项目直接使用Thre.js引擎。简单的项目一般也用不到底层WebGL知识,不过学习WebGl有助于深入理解Threejs,如果使用Thre.js开发项目需要自定义着色器的时候,肯定也是要学习底层WebGL和着色器GLSL知识。
02-three.js基础运用
1.程序结构
2.创建场景
类别 | 内容 |
---|---|
二维几何 | PlaneGeometry 平面、 CircleGeometry 圆形、 ShapeGeometry 塑形 |
三维几何体 | BoxGeometry 立方体(或叫三维方块)、 SphereGeometry 球体、 CylinderGeometry 柱体、 TorusGeometry 圆环 、TorusKnotGeometry 环面扭结、 PolyhedronGeometry 多面体、 IcosahedronGeometry 十二面体、 OctahedronGeometry 八面体、 TetrahedronGeometry 四面体 |
复杂几何体 | ConvexGeometry 凸面体、 LatheGeometry 扫描面、 ExtrudeGeometry 拉伸几何体、 TubeGeometry 管状体、 ParametricGeometry 参数几何体、 TextGeometry 文本几何体 |
名称 | 内容 | 参数 |
---|---|---|
MeshBasicMaterial | MeshBasicMaterial是一种非常简单的材质,这种材质不考虑场景中光照的影响。使用这种材质的网格会被渲染成简单的平面多边形,而且也可以显示几何体的线框,对场景中的雾化会有反应。 | color(颜色),wireframe(线框),wireframeLinewidth(线框宽度),wireframeLinecap(线框线段端点),wireframeLinejoin(线框线段连接点),shading(着色)、 vertexColors(顶点颜色),fog(雾化) |
MeshPhongMaterial | 该材料使用非基于物理的Blinn-Phong模型来计算反射系数。通过THREE.MeshPhongMaterial,可以创建一种光亮的材质,与在MeshLambertMaterial中使用的Lambertian模型不同,它可以模拟带有高光的闪亮表面(如漆木)。 | color(颜色)、shininess(光滑度),specular(高光),ambient(环境色),emissive(发射颜色),metal(像素颜色计算),wrapAround(光照效果),wrapRGB(控制光) |
MeshLambertMaterial | 这种材质可以用来创建暗淡的并不光亮的表面。 无光泽表面的材质,无镜面高光。 这可以很好地模拟一些表面(如未经处理的木材或石头),但不能用镜面高光(如上漆木材)模拟光泽表面。 该材质非常易用,而且会对场景中的光源产生反应。 | color、opacity、shading、blending、depthTest、depthWrite、wireframe、wireframeLinewidth、wireframeLinecap、wireframeLineJoin、vertexColors和fog |
//创建场景
var scene = new THREE.Scene();
//显示三维坐标轴
var axes = new THREE.AxesHelper(20)
//添加坐标系到场景中
scene.add(axes)
//创建平面几何
var planeGeometry = new THREE.PlaneGeometry(60, 20)
//几何体材质
var planeMaterial=new THREE.MeshBasicMaterial({color:0xCCCCCC})
//创建平面
var plane=new THREE.Mesh(planeGeometry,planeMaterial)
//物体位置旋转xyz 位置:xyz
plane.rotation.x=-0.5*Math.PI
plane.position.x=15
plane.position.y=0
plane.position.z=0
//物体添加到场景中
scene.add(plane)
3.创建相机
//创建相机(透视)角度,长宽比,最近视野,最远视野
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000)
//设定摄像机位置,指向场景中心
camera.position.x=-30
camera.position.y=40
camera.position.z=30
camera.lookAt(scene.position)
4.渲染
//创建渲染
var renderer = new THREE.WebGLRenderer()
//设置渲染器初始颜色
renderer.setClearColor(new THREE.Color(0xEEEEEE))
//设置输出canvas画面大小宽,高
renderer.setSize(window.innerWidth, window.innerHeight)
//渲染
document.getElementById('webgl-output').appendChild(renderer.domElement)
renderer.render(scene,camera)
5.光源与阴影
阴影与光源有关,涉及函数包括castShadow,receiveShadow。投影物体与光源需要设置castShadow为true,
同时接受阴影的平面需要receiveShadow为true,注意投影平面不使用MeshBasicMaterial,否则可能存在投影不生效情况
function init() {
//创建场景
var scene = new THREE.Scene();
//创建阴影投射平面
var planeGeometry = new THREE.PlaneGeometry(40, 40)
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xCCCCCC})
var plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.rotation.x = -0.5 * Math.PI
plane.receiveShadow = true
scene.add(plane) //物体添加到场景中
//添加球体
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xFFA500})
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.position.set(0, 4, 2)
sphere.castShadow = true//阴影
scene.add(sphere) //物体添加到场景中
//添加聚光灯
var spotLight = new THREE.SpotLight(0xFFFFFF)
spotLight.position.set(30, 30, -30)
spotLight.castShadow = true
spotLight.shadow.mapSize.width = 2048; //阴影贴图宽度设置为2048像素
spotLight.shadow.mapSize.height = 2048; //阴影贴图高度设置为2048像素
scene.add(spotLight)
//创建相机(透视)角度,长宽比,最近视野,最远视野
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000)
camera.position.set(30,40,30)//设定摄像机位置,指向场景中心
camera.lookAt(scene.position)
//创建渲染
//设置渲染器初始颜色
//渲染webGLRenderer
//设置输出canvas画面大小宽,高
var renderer = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true,
})
renderer.shadowMap.enabled = true
renderer.setClearColor(new THREE.Color(0xEEEEEE))
renderer.setSize(window.innerWidth, window.innerHeight)
document.getElementById('webgl-output').appendChild(renderer.domElement)
renderer.render(scene, camera)
}
6.动画效果
旋转
1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流
function rotate() {
renderer.render(scene, camera)
sphere.rotateY(0.01)
requestAnimationFrame(rotate)
}
鼠标控制相关库为:OrbitControls
监听
//创建控制器对象
var control = new OrbitControls(camera, renderer.domElement)
// 监听鼠标
control.addEventListener('change', () => {
renderer.render(scene, camera)
})
requestAnimationFrame
animate();
var control = new OrbitControls(camera, renderer.domElement)
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}