Three.js - - Hello World(1)

这并不是算一个教程,更像是一个笔记,笔者水平有限;如果读起来感觉不对应该广泛查询资料。


关于Three.js

Three.js是一个WebGL的库,可以快速在网页上创建三维效果。

其所用的编程语言是java script,而我平时工作是用的C++,并不是太懂这门语言,特别是其中如何操作网页的部分;不过也是类C语言,可以边做边学嘛。

而WebGL顾名思意就是Web版的OpenGL,查了下资料是OpenGL ES 2.0的规范,新版的似乎是用ES 3.0,不过好像要很新的浏览器才支持。
OpenGL ES和其桌面版的我都用过,所以我并不是想单独学习WebGL。

如何学习

花了几天时间找了下相关教程,不过好像都不太理想,原因有二:
1. Three.js的版本更新很快
2. Three.js的应用好像的确有限。
3. 用来写写随机效果尚可,但是用来写3D应用程序很困难,虽然现在CPU性能过剩,但是js的效率还是差了太多,官方demo里有些例子都卡得不像话(那个化学分子式的三维渲染,demo有2个版本;其中一个用的是vbo,而一个好像没有用,我1080P的分辨率和650M的显卡,没有用vbo的只有10帧不到,用了的有10多帧)。
其次是js似乎语言缺陷方面的原因,代码多了维护不便。

找到的很多教程都普遍落后10+的版本(写文时版本为r88);国内更惨,好像12年~15年有人做,后面就没了。

还是用官方文档和demo来学习吧,three.js是挂在github上的,clone下来,里面的文件夹,build是库文件,docs是文档,examples里全是例子。

打开docs/index.html点击Useful links,再打开Examples分类下Professor Stemkoskis Examples,就有些简单的入门例子了;
不过这些例子版本都是60。

本文是其中Hello World改来的。


0. 本文做了什么

创建了一个渲染框架,并渲染了一个正方体,并且可以操纵相机。

1. 开始

构键html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>canvas { width:100%;height: 100%}</style>
</head>
<body>

</body>
</html>

将canvas画布设置为全页面。

加入js文件

<body>下放入

<script src="src/js/three.js"></script>
<script>
</script>

第一个js文件为three.js官方库,从你在github上clone下来的build中可以找到,
你也可以把它改成three.min.js,文件大小会小很多,内容和three.js一样;这个是消除了空行的,你没办法查看其中的api,所以推荐用three.js
three.module.js我不太懂,好像是另一种模组加载库文件的方式?

第二个js文件script里是空的,接下来我们要在里面添加自己的代码。

全局变量

在空的<script>下加入

var scene, camera, renderer;
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;

scene是场景,渲染的根节点。场景应该是一个树状结构,场景下可以放入很多物体,物体下又可以放入子物体这样。
总的来说就是一个容器。

camera是摄像机,如果你要看到画面的话这是必须的;
它就好比你的眼睛。

renderer是渲染器,负责在Web页面上渲染画面。

后面2个是画面的宽和高。

初始化

接着加入

function init()
{
}

创建场景

init()加入

// create scene
{
    scene = new THREE.Scene();
}

空的场景。

创建相机

接着在init()加入

// create camera
{
    var VIEW_ANGLE = 75;
    var ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT;
    var NEAR = 0.1;
    var FAR = 10000;

    camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
    camera.position.set(0, 150, 400);
    camera.lookAt(scene.position);
    scene.add(camera);
}

VIEW_ANGLE是重载可视角度,即FOV,越大就代表你的眼睛会看到越“高”的场景。
人眼的水平视角是188度,一般16比9设75度,4比3则可以设45度看起来比较舒服。
FOV过大会显得离场景变远,过小则像抵近了看一般。
你可以尝试设置不同的值,并改变浏览器窗口的长宽比看看效果。

ASPECT则是宽/长比;上面的FOV决定你看到的宽度,再用这个值就可以算出你看到的高度。

NEAR和FAR则是相机的近/远平面。过近/过远的物体不会被渲染。

THREE.PerspectiveCamera是指的透视相机。
渲染三维场景用透视,才会有远小近大的效果。
相对的有正交相机,可以用来渲染HUD、地图、二维游戏,远近并不影响大小。

然后设置了相机的位置。
OpenGL的坐标系是Y轴向上的左手坐标系,X向右,Y向上,Z朝屏幕外。
如果地面的高度即Y值是0的话,这里的相机高度就是150,离世界坐标原点400朝屏幕外。

lookAt设置视点,这里视点是scene的位置,我们并没有改变过scene的位置,即默认的xyz都是0。

最后将相机加入场景,请不要忘记这步。
一个场景是可以有多个相机的,多个相机不只可以分屏,还可以渲染地图、阴影贴图,做RTT。

创建渲染器

接着在init()加入

// create renderer
{
    renderer = new THREE.WebGLRenderer({antialias: true});
    renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
    document.body.appendChild(renderer.domElement);
}

渲染器负责渲染场景,这里用的是THREE.WebGLRenderer即WebGL。
注意这里并没有做检查,如果你的浏览器如果不支持WebGL,那就会出错。
正确的做法应该要检查,不支持的话应该用THREE.CanvasRenderer()的,这里为了简便并没有这么做。

然后设置渲染器输出画面大小为全屏。
你可以改变大小,如果它们的宽长比和前面的相机宽长比ASPECT不符合,画面就会被拉伸。
请注意这里不论怎么改,画面虽然被拉伸,但是内容是一致的。

最后把渲染器的dom元素加到web页面中,才能在web页面上看到画面。

创建三维物体

接着在init()加入

// cube
{
    var geom = new THREE.CubeGeometry(100, 100, 100, 1, 1, 2);
    var mat = new THREE.MeshBasicMaterial({color:0xff0000});

    var cube = new THREE.Mesh(geom, mat);
    scene.add(cube);
}

首先调用THREE.CubeGeometry()创建了一个方块几何体。
方块几何体是几何体的一个派生。几何体有三维物体的顶点、法线信息。

然后用THREE.MeshBasicMaterial()创建了基础的材质,并设置了颜色是红色。

然后用THREE.Mesh()创建了网格物体cube
网格代表这个物体有几何数据,是可以绘制的;相对应的肯定就有非网格物体,是绘制不出来的。
这里创建的时候用了几何体与材质。

最后把cube加入到场景下。

到这里init()函数就写完了。

渲染循环

在我们自己的<script>中接着加入

function allLoop() {
    requestAnimationFrame(allLoop);
    renderer.render(scene,camera);
}

这是一个会一直重复执行的回调函数。
requestAnimationFrame()是js的一个函数,参数是函数。
renderer.render()则是渲染器用一个场景节点和相机渲染一帧画面。

以上2句结合起来就可以不停重复调用渲染了。

启动

在我们自己的<script>中接着加入

init();
allLoop();

先初始化,再进入渲染循环。

2. 结果

渲染画面

如果你做的都没错,那么你就可以看到这个画面。如果不对,按F12再检查下吧!

3. 改进

是不是觉得这太LOW了……这算什么三维画面。那么我们加2、3行代码,就可以让画面动起来了!

创建操纵器

在three.js文件引用后加入一个新的引用

<script src="src/js/OrbitControls.js"></script>

这个文件的地址是three.js项目/examples/js/controls/OrbitControls.js

在上文中全局变量一节中,再加入一个control变量。

var control;

接着在init()中加入

// create controls
{
    controls = new THREE.OrbitControls(camera, renderer.domElement);
}

controls是操纵器,操纵器控制相机的姿态。
常见的有漫游操纵器,你可以在三维世界中行走;这里用的是轨道操纵器,这个操纵器可以控制相机像一个卫星一样围绕目标旋转。
第1个参数是要控制的相机,第2个则是渲染器的dom元素。

4. 改进结果

可操控的画面

你可以用鼠标拖动这个方块了,可以绕到方块的不同角度观看。
是不是很棒?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值