图形化开发(二)02——Three.js之分析-创建渲染器、相机、场景 & 创建生成一个模型 & 实现动画效果

图形化开发(二)02——Three.js之分析-创建渲染器、相机、场景 & 创建生成一个模型 & 实现动画效果

分析
<body onload="init()">

ready和onload的区别: ready加载完js和css就执行,onload必须加载完图片之后。

//初始化函数,页面加载完成是调用
function init() {
  initRenderer();
  initScene();
  initCamera();
  initMesh();
  animate();
}

使用Three.js显示创建的内容,我们必须需要的三大件是:渲染器,相机和场景。相机获取到场景内显示的内容,然后再通过渲染器渲染到画布上面。

在这里插入图片描述

创建渲染器
function initRenderer() {
    renderer = new THREE.WebGLRenderer(); //实例化渲染器
    renderer.setSize(window.innerWidth, window.innerHeight); //设置宽和高
    document.body.appendChild(renderer.domElement); //添加到dom
}

第一行,我们实例化了一个THREE.WebGLRenderer,这是一个基于WebGL渲染的渲染器,当然,Three.js向下兼容,还有CanvasRenderer,CSS2DRenderer,CSS3DRenderer和SVGRenderer,这四个渲染器分别基于canvas2D,CSS2D,CSS3D和SVG渲染的渲染器。由于,作为3D渲染,WebGL渲染的效果最好,并且支持的功能更多,我们以后的课程也只会用到THREE.WebGLRenderer,需要使用其他渲染器时,会重点提示。

第二行,调用了一个设置函数setSize方法,这个是设置我们需要显示的窗口大小。案例我们是基于浏览器全屏显示,所以设置了浏览器窗口的宽和高。

第三行,renderer.domElement是在实例化渲染器时生成的一个canvas画布,渲染器渲染界面生成的内容,都将在这个画布上显示。所以,我们将这个画布添加到了dom当中,来显示渲染的内容。

创建相机
//初始化相机
function initCamera() {
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200); //实例化相机
    camera.position.set(0, 0, 15);
}

Three.js里面有几个不同的相机,我们这里使用到的是THREE.PerspectiveCamera,这个相机的效果是模拟人眼看到的效果,就是具有透视的效果,近大远小。

第一行,我们实例化了一个透视相机,需要四个值分别是视野,宽高比,近裁面和远裁面。我们分别介绍一下这四个值:

  • 视野:当前相机视野的宽度,值越大,渲染出来的内容也会更多。
  • 宽高比:默认是按照画布的显示的宽高比例来设置,如果比例设置的不对,会发现渲染出来的画面有拉伸或者压缩的感觉。
  • 近裁面和远裁面:这个是设置相机可以看到的场景内容的范围,如果场景内的内容位置不在这两个值内的话,将不会被显示到渲染的画面中。

第二行,我们设置了相机的位置。

在这里插入图片描述

WebGL坐标系统作为3D坐标,在原来的2D坐标xy轴上面又多了一个z轴,大家注意z轴的方向,是坐标轴朝向我们的方向是正轴,我们眼看去的方向是是z轴的负方向。
camera.position.set函数是设置当前相机的位置,函数传的三个值分别是x轴坐标,y轴坐标和z轴坐标。我们只是将相机的放到了z正轴坐标轴距离坐标原点的15的位置。相机默认的朝向是朝向0点坐标的,我们也可以设置相机的朝向,这将在后面相机介绍是,专门介绍相机的相关。

在这里插入图片描述

创建场景
//初始化场景
function initScene() {
	scene = new THREE.Scene(); //实例化场景
}

场景只是作为一个容器,我们将需要显示的内容都放到场景对象当中。如果我们需要将一个模型放入到场景当中,则可以使用scene.add方法,如:

scene.add(mesh); //添加一个网格(模型)到场景
创建第一个模型

渲染器,场景和相机都全了,是不是就能显示东西了?不能!因为场景内没有内容,即使渲染出来也是一片漆黑,所以我们需要往场景里面添加内容。接下来,我们将查看initMesh方法,看看如何创建一个最简单的模型:

//创建模型
function initMesh() {
    geometry = new THREE.BoxGeometry( 2, 2, 2 ); //创建几何体
    material = new THREE.MeshNormalMaterial(); //创建材质

    mesh = new THREE.Mesh( geometry, material ); //创建网格
    scene.add( mesh ); //将网格添加到场景
}

第一行代码里,我们实例化了一个THREE.BoxGeometry立方体的几何体对象,实例化的三个传值分别代表着立方体的长度,宽度和高度。我们全部设置的相同的值,将渲染出一个标准的正立方体。

第二行里面,我们实例化了一个THREE.MeshNormalMaterial材质,这种材质的特点是,它会根据面的朝向不同,显示不同的颜色。

第三行,通过THREE.Mesh方法实例化创建了一个网格对象,THREE.Mesh实例化需要传两个值,分别是几何体对象和材质对象,才可以实例化成功。

第四行,添加

动画
function animate() {
    requestAnimationFrame(animate); //循环调用函数
	...
}

在循环调用的函数中,每一帧我们都让页面重新渲染相机拍摄下来的内容:

renderer.render( scene, camera ); //渲染界面

渲染的render方法需要两个值,第一个值是场景对象,第二个值是相机对象。这意味着,你可以有多个相机和多个场景,可以通过渲染不同的场景和相机让画布上显示不同的画面。

但是,如果现在一直渲染的话,我们发现就一个立方体在那,也没有动,我们需要做的是让立方体动起来:

mesh.rotation.x += 0.01; //每帧网格模型的沿x轴旋转0.01弧度
mesh.rotation.y += 0.02; //每帧网格模型的沿y轴旋转0.02弧度

每一个实例化的网格对象都有一个rotation的值,通过设置这个值可以让立方体旋转起来。在每一帧里,我们让立方体沿x轴方向旋转0.01弧度,沿y轴旋转0.02弧度(1π弧度等于180度角度)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值