Three.js 入门基础

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容