Three.js
1.Three.js 介绍
OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。这个接口由近350个不同的函数调用组成,用来从简单的图形比特绘制复杂的三维景象。而另一种程序接口系统是仅用于Microsoft Windows上的Direct3D。OpenGL常用于CAD、虚拟实境、科学可视化程序和电子游戏开发。
WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。
Three.js(Javascript 3D library),使用JavaScript语言对WebGL进行了封装,让前端开发人员在不需要掌握很多数学知识和绘图知识的情况下,也能够轻松进行web 3D开发,降低了门槛,同时大大提升了效率。总结来一句话:就是你不懂计算机图形学,只要理解了three.js的一些基本概念就可以开始入门网页端的3D开发。
2.Three.js 从入门到放弃
简单的一个threejs示例,可以理解为一个空间或者环境,就像一个房间一样,建造一个房间之后,可以在房间里放置任何可以放置的东西,也就是threejs中的物体。房间里如果光线很暗需要有灯,就是threejs中的光源,需要有一个观察对象可以看到这些东西,也就是threejs中的相机,也可以简单理解为我们的眼镜,来捕捉映射这个房间内的物体和光线等。渲染器可以理解为我们大脑中对各种颜色和物体的认识,比如红色的方块,如果单纯来说方块只是一个物体,但是经过渲染器,有了颜色和形状。
基本要素1:场景
场景能够让你在什么地方、摆放什么东西来交给three.js来渲染,这是你放置物体、灯光和摄像机的地方。
const scene = new THREE.Scene(); //创建一个场景
基本要素2:相机
相机就类似我们的人眼,可以观察到环境中的物体,以及光线效果等。
Threejs中相机主要分为两种:正交相机(OrthographicCamera)和透视相机(PerspectiveCamera),正交相机是正交投影所反映的效果,透视相机是透视投影所反映的效果。从效果而言,就是正交相机看到的东西不会因为距离而改变,只会因为相机的角度改变物体显示效果。而透视相机类似人眼,近大远小,距离和角度都会影响物体的显示效果
正交相机OrthographicCamera
在这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。这对于渲染2D场景或者UI元素是非常有用的。
//OrthographicCamera( left : Number, right : Number, top : Number, bottom : Number, near : Number, far : Number )
//left — 摄像机视锥体左侧面。
//right — 摄像机视锥体右侧面。
//top — 摄像机视锥体上侧面。
//bottom — 摄像机视锥体下侧面。
//near — 摄像机视锥体近端面。
//far — 摄像机视锥体远端面。
const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
scene.add( camera );
透视相机(PerspectiveCamera)
这一投影模式被用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。
透视投影:从某个投射中心将物体投射到单一投影面上所得到的图形
//PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
//fov — 摄像机视锥体垂直视野角度
//aspect — 摄像机视锥体长宽比
//near — 摄像机视锥体近端面
//far — 摄像机视锥体远端面
const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
scene.add( camera );
基本要素3:灯光
threejs的场景中默认都是没有光的,就像一个没有窗户的空间,需要增加光源才能看到物体。
种类介绍备注
AmbientLight环境光:环境光会均匀的照亮场景中的所有物体。环境光不能用来投射阴影,因为它没有方向。
AmbientLightProbe环境光探针:光照探针是一种在3D场景中添加光源的另一种方法。 AmbientLightProbe 是场景中单个环境光的光照估算数据
DirectionalLight平行光:平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光 的效果; 太阳足够远,因此我们可以认为太阳的位置是无限远,所以我们认为从太阳发出的光线也都是平行的平行光可以投射阴影
HemisphereLight半球光:光源直接放置于场景之上,光照颜色从天空光线颜色渐变到地面光线颜色。贝塔模型中使用
HemisphereLightProbe半球光探针:光照探针是一种在3D场景中添加光源的另一种方法。 HemisphereLightProbe 是场景中单个半球光的光照估算数据。
LightProbe光照探针:光照探针是一种在3D场景中添加光源的另一种方法。与经典光源(平行光、点光、聚光)不同, 光照探针不发光。相反,光照探针存储着有关穿过3D空间的光线的信息。 渲染过程中,通过使用来自光照探针的数据,来逼近打到3D物体上的光线光照探测是一种快速计算实时渲染应用中的光照技术,通常会用于处理游戏世界的人物角色或是动态物体的光照,为在场景中的移动物体上提供高质量的照明(包括间接反射光(indirect bounced light)(GI)(实例场景中白色方块上的黄色和蓝色光)),它的优点在于运行时有不错的处理性能而且预计算也相当快速。
PointLight点光源:从一个点向各个方向发射的光源。一个常见的例子是模拟一个灯泡发出的光。
RectAreaLight平面光光源:平面光光源从一个矩形平面上均匀地发射光线。这种光源可以用来模拟像明亮的窗户或者条状灯光光源。
SpotLight聚光灯:光线从一个点沿一个方向射出,随着光线照射的变远,光线圆锥体的尺寸也逐渐增大。该光源可以投射阴影
//以贝塔模型中用到的光源为类
//创建环境光
//环境中默认都是添加的,就像自然界的太阳光,月光,如果只给场景添加特定光源,那么特定光照不到的模型位置有可能就是黑色的,不会渲染的。
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
this.scene.add(ambientLight);
//创建半球光
const light = new THREE.HemisphereLightProbe(0xffffff, 0x080820, 0.5); //添加半球光
this.scene.add(light);
基本要素4:网格
这里所说的网格也就是threejs场景中的物体,可以是2D效果的面板,也可以是3D效果的立方体,或者外部导入的符合规范的模型,这里所有的物体显示效果都是通过网格也就是一个个三角形来拼接,最后平滑过渡为面。mesh可以设置material材质,来实现不同的效果。
在计算机的世界里,一条弧线是由有限个点构成的有限条线段连接得到的。当线段数量越多,长度就越短,当达到你无法察觉这是线段时,一条平滑的弧线就出现了。计算机的三维模型也是类似的。只不过线段变成了平面,普遍用三角形组成的网格来描述。我们把这种模型称之为 Mesh 模型。
var geometry = new THREE.PlaneGeometry(700, 700, 1);
this.texture = this.textureLoader.load(item.printUrl);
var material = new THREE.MeshBasicMaterial({
map: this.texture,
side: THREE.FrontSide,
});
let frontPlane = new THREE.Mesh(geometry, material);
this.scene.add(frontPlane);
PlaneGeometry
webgl_lines_fat_wireframe
基本要素5:渲染器
WebGL Render 用WebGL渲染出你精心制作的场景。
let renderer = new THREE.WebGLRenderer({
antialias: true,// true/false表示是否开启反锯齿
alpha: true,// true/false 表示是否可以设置背景色透明
precision: 'highp',// highp/mediump/lowp 表示着色精度选择
preserveDrawingBuffer: true, //true/false 是否保留缓直到手动清除或被覆盖。 默认false. 决定画布是否能导出快照
premultipliedAlpha: false,// true/false 表示是否可以设置像素深度(用来度量图像的分率)preserveDrawingBuffer: true,// true/false 表示是否保存绘图缓冲
)}
3.外部模型的导入:加载器loader
TextureLoader 纹理加载器(加载texture的一个类。 内部使用ImageLoader来加载文件)
const texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' );
// 立即使用纹理进行材质创建
const material = new THREE.MeshBasicMaterial( { map: texture } );
OBJLoader (贝塔模型)
用于加载.obj资源的加载器。
OBJ 文件格式是一种简单的数据格式, 这种格式以人类可读的形式来表示3D几何体,即每个顶点的位置、每个纹理坐标顶点的UV位置、顶点法线、 将使每个多边形定义为顶点列表的面以及纹理顶点。
// model 创建obj模型加载器
const loader = new OBJLoader(manager);
//加载obj模型文件
loader.load( 'a.obj', function (obj) {
object = obj;
that.currObj = object;
object.scale.set(0.8, 0.8, 0.8);
});
//使用纹理加载器加载法向贴图 实现模型细腻纹理(如凹凸效果 褶皱效果等) 普通纹理即map只是大范围贴图,实现材质铺满。
that.normalMapTexture = that.textureLoader.load(
that.fullPrintingVo.sil3dMappingNormal
);
//创建材质加载器
var material = new THREE.MeshPhongMaterial({
map: that.texture,
normalMap: that.normalMapTexture,
});
//设置材质的映射面 可分为 前THREE.Frontside、后THREE.Frontside、前+后THREE.Doubleside 在此处则为样衣模型的内外
material.side = THREE.DoubleSide;
//渲染纹理
object.children.forEach((mesh) => {
mesh.material = material;
});
},
that.onProgress,
that.onError
);
webgl_materials_lightmap
GLTFLoader (指纹模型)
用于载入glTF 2.0资源的加载器
glTF(gl传输格式)是一种开放格式的规范 (open format specification), 用于更高效地传输、加载3D内容。该类文件以JSON(.glft)格式或二进制(.glb)格式提供, 外部文件存储贴图(.jpg、.png)和额外的二进制数据(.bin)。一个glTF组件可传输一个或多个场景, 包括网格、材质、贴图、蒙皮、骨架、变形目标、动画、灯光以及摄像机。
const loader = new GLTFLoader();
loader.load('a.gltf',
function (gltf) {
object = gltf;
that.map = that.textureLoader.load("/3D1.jpeg");
gltf.scene.traverse(function (child) {
if (child.isMesh) {
child.material.map = that.map;
}
});
that.scene.add(object.scene);
}
);
webgl_loader_gltf
Tip: 参考网站
threejs官方网站:https://threejs.org/
threejs非官方中文网:http://www.yanhuangxueyuan.com/Three.js/
obj模型文件免费下载网站:https://www.aigei.com/s?type=3d&term=obj