Three.js入门(一)

摘自Three.js入门指南 张雯莉 (作者)

本书针对Three.js的几个重要话题分章节介绍,包括:Three.js和WebGL的背景资料、照相机的设定、在场景中添加物体、实现动画效果、导入外部模型、添加光源和阴影效果、着色器等。

1、WebGL

WebGL是基于OpenGL ES 2.0的Web标准,可以通过HTML5 Canvas元素作为DOM接口访问。WebGL可以看做是将OpenGL ES(OpenGL for Embedded Systems,OpenGL嵌入式版本,针对手机、游戏机等设备相对较轻量级的版本)移植到了网页平台,像Chrome、Firefox这些现代浏览器都实现了WebGL标准,使用JavaScript就可以用你熟悉的、类似OpenGL的代码编写了。

2、什么是Three.js

Three.js封装了底层的图形接口,能大大简化WebGL的开发,使得程序员能够在无需掌握繁冗的图形学知识的情况下,也能用简单的代码实现三维场景的渲染。几乎不会有WebGL支持而Three.js实现不了的情况,而且就算真的遇到这种情况,你还是能同时使用WebGL去实现,而不会有冲突。当然,除了WebGL之外,Three.js还提供了基于Canvas、SVG标签的渲染器,但由于通常WebGL能够实现更灵活的渲染效果,所以本书主要针对基于WebGL渲染器进行说明。

3、Hello world!

一个典型的Three.js程序至少要包括渲染器(Renderer)场景(Scene)照相机(Camera),以及你在场景中创建的物体

渲染器(Renderer)

WebGL的渲染是需要HTML5 Canvas元素的,你可以手动在HTML的部分中定义Canvas元素,或者让Three.js帮你生成。这两种选择一般没有多大差别。
渲染器将和Canvas元素进行绑定,如果之前在HTML中手动定义了id为mainCanvas的Canvas元素,那么Renderer可以这样写:

 var renderer = new THREE.WebGLRenderer({
    canvas: document.getElementById('mainCanvas')
});

而如果想要Three.js生成Canvas元素,在HTML中就不需要定义Canvas元素,在JavaScript代码中可以这样写

var renderer = new THREE.WebGLRenderer();
renderer.setSize(400, 300);
document.getElementsByTagName('body')[0].appendChild(renderer.domElement);

上面代码的第二行表示设置Canvas的宽400像素,高300像素。第三行将渲染器对应的Canvas元素添加到<body>中。

我们可以使用下面的代码将背景色(用于清除画面的颜色)设置为黑色:

renderer.setClearColor(0x000000);

场景(Scene)

在Three.js中添加的物体都是添加到场景中的,因此它相当于一个大容器。一般说,场景里没有很复杂的操作,在程序最开始的时候进行实例化,然后将物体添加到场景中即可。

var scene = new THREE.Scene();

照相机(Camera)

我们使用Three.js创建的场景是三维的,而通常情况下显示屏是二维的,那么三维的场景如何显示到二维的显示屏上呢?照相机就是这样一个抽象,它定义了三维空间到二维屏幕的投影方式,用“照相机”这样一个类比,可以使我们直观地理解这一投影方式。

WebGL和Three.js使用的坐标系是右手坐标系,看起来就是这样的:
坐标系

针对投影方式的不同,照相机又分为正交投影照相机与透视投影照相机。照相机的概念和OpenGL中的类似,此处就不多说了。需要的同学可以看看书里关于照相机的介绍。

  • 正交投影照相机
THREE.OrthographicCamera(left, right, top, bottom, near, far)
  • 透视投影照相机
THREE.PerspectiveCamera(fov, aspect, near, far)

这里,我们定义了一个透视投影的照相机

var camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 1000);
camera.position.set(0, 0, 5);
//照相机也需要被添加到场景中
scene.add(camera);

物体

我们创建一个长度为1的立方体,并将其设置为绿色。

var cube = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1),
        new THREE.MeshBasicMaterial({
            color: 0x00ff00
        })
);
scene.add(cube);

此处涉及了Mesh(网格)、Geometry(几何形状)和Material(材质)的概念,后面会介绍。

渲染

在定义了场景中的物体,设置好的照相机之后,渲染器就知道如何渲染出二维的结果了。这时候,我们只需要调用渲染器的渲染函数,就能使其渲染一次了。

renderer.render(scene, camera);

如果想要使这个长方体动起来,需要渲染循环,并且设置立方体旋转,需要用到requestAnimationFrame()函数。我们可以这样创建一个动画:

function render() {
    requestAnimationFrame( render );
    cube.rotation.x += 0.05;
    cube.rotation.y += 0.05;
    renderer.render( scene, camera );
}
render();

整合一下代码看起来是这样的:
html

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>My first Three.js app</title>
        <script type="text/javascript" src="three.js"></script>
    </head>
    <body onload="init()">
         <canvas id="mainCanvas" width="400px" height="300px" ></canvas>
    </body>
</html>
<!DOCTYPE html>

javascript

var renderer, scene, camera, cube;
//绑定canvas和渲染器
function initRender() {
    renderer = new THREE.WebGLRenderer({
        canvas: document.getElementById('mainCanvas')
    });
    //清除画面颜色
    renderer.setClearColor(0x000000);
}

//创建照相机
function initScene() {
    scene = new THREE.Scene();
}

//创建照相机
function initCamera() {
    camera = new THREE.PerspectiveCamera(45, 4 / 3, 1, 1000);
    camera.position.set(0, 0, 5);
    scene.add(camera);
}

//创建物体
function initObject() {
    cube = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1),
        new THREE.MeshBasicMaterial({
            color: 0x00ff00
        })
    );
    scene.add(cube);
}

//渲染循环
function render() {
    requestAnimationFrame( render );
    cube.rotation.x += 0.05;
    cube.rotation.y += 0.05;
    renderer.render( scene, camera );
}

function init() {
    initRender();
    initScene();
    initCamera();
    initObject();
    render();
}

可以在这个网站上复制代码并运行查看效果。

猜你喜欢

转载自blog.csdn.net/unirrrrr/article/details/80548637