正在努力加载中...
Three.js自学碎碎叨(上)
  1. 1. 搜刮来的学习资料
  2. 2. WebGL初印象
  3. 3. Three.js初印象
    1. 3.1. 三个要素
    2. 3.2. 我的第一个例子
      1. 3.2.1. 场景篇
      2. 3.2.2. 盒子篇
        1. 3.2.2.1. BoxGeometry是什么呢
        2. 3.2.2.2. 为什么还有一个Material呢
      3. 3.2.3. 光源篇
      4. 3.2.4. 照相机篇
      5. 3.2.5. 渲染器篇
  4. 4. 小结

一直就很想学习WebGL相关的知识,现在也找到了工作,生活也差不多趋向稳定了,加上学校也没那么多课程了,所以我肯定要利用起来这个时间啊!因为腿摔伤了,国庆估计是在家躺7天,所以更加要抓住这么好的学习时机了。
如你所见,这系列文章都是我自己的碎碎叨,当然啦,目的是为了能更好的梳理自己学习的知识,加强印象,顺便再来做个总结,这样能更加扎实的学习。
我的情况是,有前端基础,有PS基础,无计算机图形学基础,没有学过OpenGL,而我觉得,立体的图像比起2D的来说,可能更难以理解,因为首先,没有图形学的基础,游戏建模的经验,所以要通过联想来达成对概念的理解是比较困难的,但是我觉得只要多看多试验,实在不行就问问身边的同学,不一定要是图形学的“专家”,美术生也是不错的选择哦!这样总会明白的,所以让我们开始今天的学习吧!

搜刮来的学习资料

我的学习资料主要是来源于下面的清单(可是找了好久,才找到了这么多,当然还有加上百度各种文章):

WebGL初印象

WebGL也是在Canvas上绘制成的。
但是它还是有一点不一样,因为它除了要HTML、JS来写之外,还需要一个叫做着色器语言的东西,而WebGL使用的是GLSL ES,这就是说作为前端的我们,还得去学习另一门语言才行。
至于这其中的道理就是,Javascript通过浏览器的JS解释器控制CPU,通过CPU来控制GPU,GPU就是图形处理器,着色器语言构成的代码被编译后再交给GPU去执行。所以在写WebGL的时候,你会看到一大段类似于C语言的代码字符串被赋予给一个变量。
而对于我们新手来说,肯定是一脸懵逼的,所以我们对WebGL有一个简单的印象后,从Three.js开始入手学习,Three.js对这些都进行了一个很好的封装,我们就可以先不去考虑这些稍微原生态的东西。

Three.js初印象

Github地址:https://github.com/mrdoob/three.js
我们肯定要先从简单的入手啦!虽然官方git仓库东西丰富,看的眼花缭乱!我们可以直接引入一个three.min.js的cdn链接就开始写我们的程序。

一般情况下,我们可以在HTML文档里先写一个canvas标签,最后把我们的内容挂载上去,但是大家似乎更倾向于一切都在JS代码中完成,也就是最后appendChild到body上面去。

三个要素

我们可以想像自己是在拍摄一张照片!比如,要拍摄淘宝的商品图片。
这时候我们就需要布置一个场景,我们可以放(add)一个苹果,然后加一个光照,最后再拿相机摆好位置拍下来!然后再把成像洗出来。
而Three.js成像的过程也很类似于这样,我们每次要作一幅新画的时候,就需要一个场景(Scene)对象、照相机(Camera)对象,还有渲染器(Renderer)!

我的第一个例子

var scene = new THREE.Scene();

var box = new THREE.BoxGeometry(100, 100, 100);
var material = new THREE.MeshLambertMaterial({color: 0x0000ff});
var mesh = new THREE.Mesh(box, material);
scene.add(mesh);

var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300);
scene.add(point);

var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);

var width = window.innerWidth;
var height = window.innerHeight;
var k = width / height;
var s = 100;

var camera = new THREE.OrthographicCamera(-s*k, s*k, s, -s, 1, 1000);
camera.position.set(200, 300, 200);
camera.lookAt(scene.position);

var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.setClearColor(0xb9d3ff, 1);
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera);

以下是下面这段代码的预览图:
图片描述

以上的大段代码来自于我学习资料中的第一个网站!看不懂没关系,这时候其实我也还没细细看呢,我们一个个来看哦!

场景篇

第一段代码,是关于我们创建了一个场景对象的!
这个比较简单,就是new了一个对象:

var scene = new THREE.Scene();

不过后面我们可以看到相关的代码还有scene.add(point);之类的,其实就是类似于我们说过的,向场景里去添加东西啦!我们可以看看场景对象的内部结构:
图片描述
眼花缭乱,东西好多啊!但是我们可以看到它有一个children属性,下面放的就是一个数组,就是我们add进去的东西哦!这样就更好理解了!

盒子篇

可以看到,这个场景,我们就是放了一个正方体进去!

var box = new THREE.BoxGeometry(100, 100, 100);
var material = new THREE.MeshLambertMaterial({color: 0x0000ff});
var mesh = new THREE.Mesh(box, material);
scene.add(mesh);

BoxGeometry是什么呢

当然就是创建一个“盒子”对象咯,也就是一个块,长方体呀正方体啊都可以,给它设置参数就行了。三个参数分别表示width, height和depth。这里都是100,所以就是一个正方体啦!(可以自己修改下参数试试)

为什么还有一个Material呢

我们可以看到,我们最后用Mesh这个方法,把Box和Material结合起来了,字如其名!Material就是材料啦!如果我们不给Box添加任何材料的话,那就是一个”骨架”了,所以这里可能和我一开始的想象不一样,我们需要给Box制定它的材质,这个东西才能出来!

光源篇

我们可以想象,假如我们东西都摆好了,但是没有灯的话,就是一片漆黑,所以这里还有很多光源的对象。这里我们就先了解这里用的两种光:点光源(point)和环境光(ambient)。

假如没有任何的光,它就是乌漆麻黑的看不见!!
图片描述

那么首先我们来研究一下点光源!

var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300);
scene.add(point);

我们给它添加了白色的光,重要的是在于这个位置的理解。我们根据经验也可以推断是这是x,y和z三个坐标值。经过我不断的改变这个位置值,看下图分别是(100, 100, 0)和(100, 100, 100)的情况,我们可以根据光线的变化来推断出光源的位置,从而知道坐标轴的设置:
图片描述
图片描述
随后查过资料后,发现Three.js使用的确实是右手坐标系,这里是与OpenGL同步默认的情况:
图片描述
下面我模拟了一下从(0, 0, 100)到(0, 200, 100)的变化情况,也就是灯光从下一直上升到了上面。
图片描述

我们再来看看环境光~
我尝试着只给Cube添加一个#FFF最亮的白光,可以看到它全部都亮了,颜色就是我们最初给Cube的颜色。我们可以发现这个环境光是均匀的,不会像点光源一样有一个强弱的减少。也就是说我们可以利用它来给我们提供一个布景的基础。
图片描述

照相机篇

照相机我觉得对于我们这种没有图形学基础和建模经验的人来说,应该是比较难理解的,首先是我们要知道有两种成像相机:

其中透视投影是符合我们眼睛成像的原理的,就是说东西并不是远近一样的大小,比如下面这张桌子,我们可以感觉到离我们近的这边要更“大”一些:
图片描述

而正交投影就不一样了,比如我们可以看下面这张建模图,就是方方正正的,参考线都是平行的:
图片描述

好,下面我们来认识一下照相机里面的几个参数:左、右、上、下、近、远。
这就类似于你相机成像的位置,也就是说可能画布是无限大的,但是相机只能拍出部分景象。
图片描述
这里比较难理解的就是近和远,似乎又和我们想像的一样,根据我自己的测试,我感觉它更像一个盒子,就是说超出这个范围的东西都会被割掉。
比如,当我把near值调大一点的时候,可以看到出现了一个缺口,也就是说相机距离的很近,所以出现了一个三角形的缺口。
图片描述
另外我们可以知道,这个左-右/上-下的比例应该与画布的比例一样,要不然图像的宽高比肯定会变化,会被压缩。

当然啦,我们有了一个相机,必定要设置好它的位置,以及它朝着的方向。

渲染器篇

最后,一切就绪,我们就可以用渲染器把这个图像渲染出来。
然后用document.body.appendChild(renderer.domElement);把渲染器渲染出来的元素添加到body中,再调用render函数进行渲染,就完毕了。
如果想要做动画效果,就再函数里动态改变一些数值,重新调用渲染方法,就可以达到了。

小结

今天是我学习Three.js的第一天,我通过一个基本的例子,对Three.js里面的一些基础的概念有了一点了解。
不过有的细节还是不太懂,也有一些自己的疑问,这还需要后面更多的学习。
另外,因为我也是新手,可能会有一些自己理解的不对的地方,欢迎指出来!^—^

上一篇 下一篇
ABOUT
欢迎来到小年糕的后花园,年糕的小站开设于2017年,博主年糕君是一个爱好十分广泛的人,也是一个比较佛系的人,不定时爆发脑洞更新(因为是社畜,也可能失踪很久,工作太累了)。 查看更多