Three.js 官方文档比较精简,重点介绍 api,没有一个合适的零基础的教程,但官网的 demo 十分丰富,遂产生从 demo 来逐渐学习 Three.js 的想法。
以下是目前收集到的较好的学习资源:
Three.js 入门指南:http://www.ituring.com.cn/boo…
Three.js 官网中文文档:https://threejs.org/docs/inde…
大牛博客,有很多 demo:http://www.wjceo.com/blog/thr…
图解 WebGL&Three.js 工作原理:https://www.cnblogs.com/wanbo…
Three.js 源码注释:https://blog.csdn.net/omni360…
好,下面回归正题,这是今天要分析的: demo,官网的例子,可以直接跳到 github 上查看源码,我建议直接把 three.js 整个项目下载下来,可以直接查看 demo 的效果,直接打开 html 文件可能效果有不一样,可以看官网的说法,也就是需要启动一个本地的服务器,如果你用的 webstorm 的话,直接右键 html 文件,就会有个 run 文件的选项,点击就可以启动一个本地服务器来启动本地的文件。
下面是 demo 的代码:
var camera, scene, renderer;
var mesh;
init();
animate();
function init() {
// 初始化透视相机,参数 (fov : Number, aspect : Number, near : Number, far : Number)
// fov — 摄像机视锥体垂直视野角度
// aspect — 摄像机视锥体长宽比
// near — 摄像机视锥体近端面
// far — 摄像机视锥体远端面
camera = new THREE.PerspectiveCamera(70, ( window.innerWidth – 600) / window.innerHeight, 1, 1000 );
// position 是 camera 继承自 Object3D 的属性,表示相机对象在三维空间中的位置
camera.position.z = 400;
// 初始化场景
scene = new THREE.Scene();
// 加载纹理,TextureLoader 是一个加载器,load 方法加载文件,返回一个新的纹理对象
var texture = new THREE.TextureLoader().load( ‘textures/crate.gif’);
// BoxBufferGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)
var geometry = new THREE.BoxBufferGeometry(200, 200, 200);
// 材质,map 属性表示贴图,这里将之前的 texture 纹理对象添加进来
var material = new THREE.MeshBasicMaterial({ map: texture} );
// Mesh 方法表示以三角形组成基本网格来形成物体
mesh = new THREE.Mesh(geometry, material);
// 将物体添加到场景中
scene.add(mesh);
// 初始化渲染器,antialias 表示抗锯齿, canvas 属性将 three.js 加载到已有的 canvas 元素上。
renderer = new THREE.WebGLRenderer({ antialias: true, canvas: document.getElementById(‘my-canvas’) } );
// 设置设备像素比。通常用于避免 HiDPI 设备上绘图模糊
renderer.setPixelRatio(window.devicePixelRatio);
// .setSiZe(width : Integer, height : Integer, updateStyle : Boolean)
// 设置输出 canvas 的大小,将 updateStyle 设置为 false 以阻止对 canvas 的样式做改变
renderer.setSize(window.innerWidth – 600, window.innerHeight);
// domElement 为自动创建或已有的 canvas 元素
document.body.appendChild(renderer.domElement);
// 监听浏览器尺寸的修改
window.addEventListener(‘resize’, onWindowResize, false);
}
// 浏览器尺寸改变时的回调,重新设置相机和渲染器参数
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
// 在大多数属性发生改变之后,你将需要调用.updateProjectionMatrix 来使得这些改变生效。
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// 动画
function animate() {
// 每一帧调用一次
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
对于初始化透视相机中 fov — 摄像机视锥体垂直视野角度和视锥体的理解,可以看看入门指南中的透视相机一章,但视锥体的长宽比都说要和 canvas 的长宽比一样,我试了一下,如果不一样的话物体就会变形。有点难以理解,其实道理跟图片要在固定长宽的 div 填满且没有裁剪和空白的情形一样,如果图片跟 div 长宽比不同的话就会变形。这里的视锥体垂直视野角度在照相机距离物体角度固定的情况下,相当于固定了宽,再根据长宽比算出长,视锥体的面积就固定了,此时视锥体的就相当于一张图片,而 canvas 就相当于固定宽高的 div,所以此时视锥体拉伸铺满。
widthSegments 属性可以看入门指南中的基本形状了解。
设备像素比可以看链接
一般情况下 new THREE.WebGLRenderer() 会自动创建一个 canvas 元素,如果想用自己定义的 canvas 元素的话,可以传入 canvas 属性,值为获取的元素。