Three.js快速入门教程(3)

讲完了Mesh,我们来看看另一种Object——Points。
Points其实就是一堆点的集合,它在之前很长时间都被称为ParticleSystem(粒子系统),r68版本时更名为PointCloud,r72版本时才更名为Points。更名主要是因为,Mr.doob认为,粒子系统应当是包括粒子和相关的物理特性的处理的一套完整体系,而Three中的Points简单得多。因此最终这个类被命名为Points。
Points能够用来实现的典型效果是这样的:官方example

Light

神说:要有光!
光影效果是让画面丰富的重要因素。
Three提供了包括环境光AmbientLight、点光源PointLight、 聚光灯SpotLight、方向光DirectionalLight、半球光HemisphereLight等多种光源。
只要在场景中添加需要的光源就好了。

Renderer

在场景中建立了各种物体,也有了光,还有观察物体的相机,是时候把看到的东西渲染到屏幕上了。这就是Render做的事情了。
Renderer绑定一个canvas对象,并可以设置大小,默认背景颜色等属性。
调用Renderer的render函数,传入scene和camera,就可以把图像渲染到canvas中了。

让画面动起来

现在,一个静态的画面已经可以得到了,怎么才能让它动起来?
很简单的想法,改变场景中object的位置啊角度啊各种属性,然后重新调用render函数渲染就好了。
那么重新渲染的时机怎么确定?
HTML5为我们提供了requestAnimFrame,它会自动在每次页面重绘前调用传入的函数。
如果我们一开始这样渲染:

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

只需要改成这样:

function render() { requestAnimationFrame(render); object.position.x += 1; renderer.render(scene, camera); }

object就可以动起来了!

举个栗子

下面我们用一个简单的例子来梳理一下这个过程。
首先写一个有Canvas元素的页面吧。

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>立方体</title> <script src="https://sqimg.qq.com/qq_product_operations/mma/javanli_test/lib/three.min.js"></script> <style type="text/css"> html, body { margin: 0; padding: 0; } #three_canvas { position: absolute; width: 100%; height: 100%; } </style> </head> <body> <canvas></canvas> </body> </html>

下面来做Javascript的部分
首先初始化Renderer

function initRenderer() { width = document.getElementById('three_canvas').clientWidth; height = document.getElementById('three_canvas').clientHeight; renderer = new THREE.WebGLRenderer({ //将Canvas绑定到renderer canvas: document.getElementById('three_canvas') }); renderer.setSize(width, height);//将渲染的大小设为与Canvas相同 renderer.setClearColor(0xFFFFFF, 1.0);//设置默认颜色与透明度 }

初始化场景:

function initScene() { scene = new THREE.Scene(); }

初始化相机:

function initCamera() { //简单的正交投影相机,正对着视口的中心,视口大小与Canvas大小相同。 camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000); //设置相机的位置 camera.position.x = 0; camera.position.y = 0; camera.position.z = 200; //设置相机的上方向 camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; //设置相机聚焦的位置(其实就是确定一个方向) camera.lookAt({ x: 0, y: 0, z: 0 }); }

要唯一确定一个相机的位置与方向,position、up、lookAt三个属性是缺一不可的。
这里我们创建了一个正交投影相机,这里我将视景体大小与屏幕分辨率保持一致只是为了方便,这样坐标系中的一个单位长度就对应屏幕的一个像素了。
我们将相机放在Z轴上,面向坐标原点,相机的上方向为Y轴方向,注意up的方向和lookAt的方向必然是垂直的(类比自己的头就知道了)。

下面添加一个立方体到场景中:

function initObject() { //创建一个边长为100的立方体 var geometry = new THREE.CubeGeometry(100, 100, 100); object = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial()); scene.add(object); }

注意我们使用了法向材质MeshNormalMaterial,这样立方体每个面的颜色与这个面对着的方向是相关的,更便于观察/调试。

在这个简单的demo里我不打算添加光影效果,而法向材质对光也是没有反应的。
最后来创建一个动画循环吧

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

每次重绘都让这个立方体转动一点点。
当页面加载好时,调用前面这些函数就好了

function threeStart() { initRenderer(); initCamera(); initScene(); initObject(); render(); } window.onload = threeStart();

完整的demo是这个样子的:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzjpxz.html