Three.js是一个3D库,《three.js笔记》系列是在使用three.js中的一些过程和笔记。
本文介绍物体的几何形状和材质等,并记录往场景中添加物体的基本过程。
物体(Object)
概要
上一节我们创建了一个初始化的3D世界,这一节我们将会往该世界中添加物体。
最常用的一种物体就是网格(Mesh),网格是由顶点、边、面等组成的物体;其他物体包括线段(Line)、骨骼(Bone)、粒子系统(ParticleSystem,后命名为Points,其实就是一堆点的集合)等。
在创建物体时,需要传入两个参数,一个是几何形状(Geometry),另一个是材质(Material)。
其中,几何形状决定了物体的顶点位置等信息,材质决定了物体的颜色、纹理等信息。
几何形状(Geometry)
几何形状(Geometry)最主要的功能是储存了一个物体的顶点信息,通过存储模型用到的点集和点间关系(哪些点构成一个三角形)来达到描述物体形状的目的。
WebGL需要程序员指定每个顶点的位置,而在Three.js中,可以通过指定一些特征来创建几何形状。
Three提供了立方体(其实是长方体)、平面(其实是长方形)、球体、圆形、圆柱、圆台等许多基本形状。
也可以通过自己定义每个点的位置来构造形状。
对于比较复杂的形状,我们还可以通过外部的模型文件导入。
材质(Material)
材质(Material)是独立于物体顶点信息之外的与渲染效果相关的属性。通过设置材质可以改变物体的颜色、纹理贴图、光照模式等。
参考
向场景中添加物体
添加地板
1 2 3 4 5 6 7 8 9
| function initFloor() { var floorGeo = new THREE.PlaneBufferGeometry(12, 8, 1, 1); var floorMaterial = new THREE.MeshBasicMaterial({ color: '#aaaaaa' }); var floor = new THREE.Mesh(floorGeo, floorMaterial); floor.position.set(0, 0, -1); scene.add(floor); } initFloor();
|
如图:
添加正方体
这里我们简单设计一个生成正方体的函数,当传入路径时则设置为材质的纹理贴图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function initCube(imageUrl) { var geometry = new THREE.BoxGeometry(1, 1, 1); var material; if (imageUrl) { material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture(imageUrl) }); } else { material = new THREE.MeshLambertMaterial(); } var cube = new THREE.Mesh(geometry, material); scene.add(cube); return cube; }
|
然后,我们添加几个正方体到场景中:
1 2 3 4 5 6 7 8 9
| var cube1 = initCube('./img/1.jpg'); var cube2 = initCube('./img/2.png'); var cube3 = initCube(); var cube4 = initCube(); cube1.position.set(2, 0, 0); cube2.position.set(-2, 0, 0); cube3.position.set(0, -2, 1); cube4.position.set(1, 1, 3);
|
如图:
这里小伙伴们或许觉得奇怪,为什么正方体是黑色的呢,明明都已经添加材质纹理了呀。
这里我们使用的是Lambert材质,对光学有些了解的我们会知道,若没有光照射的时候,这些物体是没有反射的光,所以我们是看不到它们的颜色的。
而对于地板,由于我们使用的是基本材质。
前面也说过,使用基本材质的物体,渲染后物体的颜色始终为该材质的颜色,而不会由于光照产生明暗、阴影效果。故这里我们是可以看到地板的颜色的。
让物体动起来
上一节《three.js笔记1–初始化3D世界》我们也说过,我们在动画渲染的时候可以添加动画处理,这样我们就能看到动画似的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function render() { requestAnimationFrame(render);
cube1.rotation.x += 0.03; cube1.rotation.y += 0.03;
cube2.rotation.x += 0.02; cube3.rotation.y += 0.01; cube4.rotation.x -= 0.04;
renderer.render(scene, camera); }; render();
|
这时候我们虽然看不到正方体的颜色,但是我们能看到它们已经动起来了。
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, -5, 2); camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement);
function initFloor() { var floorGeo = new THREE.PlaneBufferGeometry(12, 8, 1, 1); var floorMaterial = new THREE.MeshBasicMaterial({ color: '#aaaaaa' }); var floor = new THREE.Mesh(floorGeo, floorMaterial); floor.position.set(0, 0, -1); scene.add(floor); } initFloor();
function initCube(imageUrl) { var geometry = new THREE.BoxGeometry(1, 1, 1); var material; if (imageUrl) { material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture(imageUrl) }); } else { material = new THREE.MeshLambertMaterial(); } var cube = new THREE.Mesh(geometry, material); scene.add(cube); return cube; }
var cube1 = initCube('./img/1.jpg'); var cube2 = initCube('./img/2.png'); var cube3 = initCube(); var cube4 = initCube(); cube1.position.set(2, 0, 0); cube2.position.set(-2, 0, 0); cube3.position.set(0, -2, 1); cube4.position.set(1, 1, 3);
function render() { requestAnimationFrame(render);
cube1.rotation.x += 0.03; cube1.rotation.y += 0.03;
cube2.rotation.x += 0.02; cube3.rotation.y += 0.01; cube4.rotation.x -= 0.04;
renderer.render(scene, camera); }; render();
|
结束语
这节主要讲了在初始化完毕后的3D世界中添加物体,由于Lambert材质的物体为漫反射物体,故我们需要在添加光源之后才能看到它们的效果。下一节将介绍光源的添加。
此处查看项目代码
此处查看页面效果
查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢
如果你想要关注日常生活中的我,欢迎关注“牧羊的猪”公众号噢