three 天空球_用three.js创建一个简易的天空盒

本文创建的天空盒是用六张图片来创建的。笔者会论述两种方法来创建,都是最简单基本的方法,不涉及着色器的使用。

一种是创建一个盒子,然后将图片作为盒子6个面的纹理贴上来创建。

另一种则是简单的将纹理作为场景的背景来创建。

两种方法视觉效果是几乎没区别的,会给人身临其境的效果,感觉身处在这个3维空间里,最明显的区别就在于当你在用鼠标滚轮缩进的时候,天空盒会“原形毕露”,暴露出其盒子的本性,视觉效果原理展现在你的眼前。如图所示:

而作为背景的方法创建的话,则无论你怎么缩进,都不会“原形毕露”。

当然,缩进的设置我们是可以自己调整的,规定缩进的范围,用第一种方法也是可以不暴露出盒子的原型的。

好,接下来我们来看代码部分。

第一步是引用文件,我们是用Three.js来创建天空盒,所以第一个引用的是three.js这个文件,第二引用的文件是OrbitControls.js,这里面的函数是我们用来操控相机的,你可以通过调用这个文件里的函数在天空盒中实现360°的转换视角来观看,前文所述的你如果要调整缩进的话,也是调用里面的函数。

至于第一行的div,是作为我们three.js的输出对象。

写完引用文件,接下来看下正文代码的结构。

1

2

3 varscene, camera, renderer;4 varcontainer, controls;5

6 init();7 animate();8

9 //FUNCTIONS

10 functioninit()11 {12 ······13

14 }15

16 functionanimate()17 {18 ······19 }20

21 functionupdate()22 {23 ······24 }25

26 functionrender()27 {28 ······29 }30

31

第一步创建会用到的全局变量

three.js不可缺少的三部分:scene(场景), camera(相机), renderer(渲染器);

至于另外两个变量我们在代码中去理解。笔者在此就不多述了。

核心部分是init()函数,先创立三维场景基本要素:

1 //创建场景

2 scene = newTHREE.Scene();3 //定义透视相机的四个参数变量

4 var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT =window.innerHeight;5 var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;6 //创建相机

7 camera = newTHREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);8 camera.position.set(0,150,400);//将相机的位置摆放在(0,150,400)的位置。这里位置你可以更改以下,放在(0,0,400)也是可以的

9 camera.lookAt(scene.position);//让相机对着场景中央

10 //将相机加入场景之中

11 scene.add(camera);12

13 //设置渲染器

14 renderer = new THREE.WebGLRenderer( {antialias:true} );//设置为抗锯齿

15 renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);//设置渲染器渲染的场景大小

16

17 container = document.getElementById( 'WebGL-output');18 container.appendChild( renderer.domElement );19 /*renderer的domElement元素,表示渲染器中的画布,所有的渲染都是画在domElement上的,所以这里的appendChild表示将这个domElement挂接在id=WebGL-output的div下面,这样渲染的结果就能够在页面中显示了。*/

20

21 //再设置相机控件,这行代码能让我们360°的旋转相机

22 controls = new THREE.OrbitControls( camera, renderer.domElement );

接着是创建天空盒的代码:

1 var path = "../examples/textures/cube/Park3Med/";//设置路径

2 var directions = ["px", "nx", "py", "ny", "pz", "nz"];//获取对象

3 var format = ".jpg";//格式

4 //创建盒子,并设置盒子的大小为( 5000, 5000, 5000 )

5 var skyGeometry = new THREE.BoxGeometry( 5000, 5000, 5000);6 //设置盒子材质

7 var materialArray =[];8 for (var i = 0; i < 6; i++)9 materialArray.push( newTHREE.MeshBasicMaterial({10 map: THREE.ImageUtils.loadTexture( path + directions[i] + format ),//将图片纹理贴上

11 side: THREE.BackSide/*镜像翻转,如果设置镜像翻转,那么只会看到黑漆漆的一片,因为你身处在盒子的内部,所以一定要设置镜像翻转。*/

12 }));13 var skyMaterial = newTHREE.MeshFaceMaterial( materialArray );14 var skyBox = new THREE.Mesh( skyGeometry, skyMaterial );//创建一个完整的天空盒,填入几何模型和材质的参数

15 scene.add( skyBox );//在场景中加入天空盒

注意directions[]数组中的图片顺序是有要求而不是随意的!否则加载的效果会错乱。这张图片会帮助你更好的理解:

剩下的尾巴部分:

1 functionanimate()2 {3 requestAnimationFrame( animate );//渲染循环

4 render();5 update();6 }7

8 functionupdate()9 {10 controls.update();//实时更新相机操作

11 }12

13 functionrender()14 {15 renderer.render( scene, camera );//实时渲染

16 }

另一种作为背景的方法的代码如下:

1 var path = "textures/cube/Park3Med/"; //设置路径

2 var format = '.jpg'; //设定格式

3 var urls =[4 path + 'px' + format, path + 'nx' +format,5 path + 'py' + format, path + 'ny' +format,6 path + 'pz' + format, path + 'nz' +format7 ];8 var textureCube = newTHREE.CubeTextureLoader().load( urls );9

10 scene.background = textureCube; //作为背景贴图

还有另一种更简洁的写法是:

1 scene.background = newTHREE.CubeTextureLoader()2 .setPath( 'textures/cube/Park3Med/')3 .load( [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ] );

两种方法只需要更换这部分代码即可。

以下给出全部代码:

1

2

3

4

5

Skybox

6

7 body {8 background:#777;9 padding:0;10 margin:0;11 font-weight: bold;12 overflow:hidden;13 }14

15

16

17

18

19

20

21

22

23

24 varscene, camera, renderer;25 varcontainer, controls;26

27

28 init();29 animate();30

31 //FUNCTIONS

32 functioninit()33 {34 //SCENE

35 scene = newTHREE.Scene();36 //CAMERA

37 var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT =window.innerHeight;38 var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;39 camera = newTHREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);40 camera.position.set(0,150,400);41 camera.lookAt(scene.position);42

43 scene.add(camera);44

45 //RENDERER

46

47 renderer = new THREE.WebGLRenderer( {antialias:true} );48 renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);49

50 container = document.getElementById( 'output');51 container.appendChild( renderer.domElement );52

53 controls = newTHREE.OrbitControls( camera, renderer.domElement );54

55 //LIGHT

56 var light = new THREE.PointLight(0xffffff);57 light.position.set(0,250,0);58 scene.add(light);59 //FLOOR

60

61 var path = "../examples/textures/cube/Park3Med/";62 var directions = ["px", "nx", "py", "ny", "pz", "nz"];63 var format = ".jpg";64 var skyGeometry = new THREE.BoxGeometry( 5000, 5000, 5000);65

66 var materialArray =[];67 for (var i = 0; i < 6; i++)68 materialArray.push( newTHREE.MeshBasicMaterial({69 map: THREE.ImageUtils.loadTexture( path + directions[i] +format ),70 side: THREE.BackSide71 }));72 var skyMaterial = newTHREE.MeshFaceMaterial( materialArray );73 var skyBox = newTHREE.Mesh( skyGeometry, skyMaterial );74 //skyBox.scale.x=-1;也是镜像翻转,与上面的side一个效果

75 scene.add( skyBox );76

77 }78

79 functionanimate()80 {81 requestAnimationFrame( animate );82 render();83 update();84 }85

86 functionupdate()87 {88 controls.update();89 }90

91 functionrender()92 {93 renderer.render( scene, camera );94 }95

96

97

98

以上有一段代码是灯光的设置加入,这里可以注释掉,不影响天空盒的效果。但是如果你要在天空盒中加入物体,则需要设置灯光,否则加入场景的物体将会是黑色的。

以上就是笔者的一些见解,若有不对的对方,欢迎指正。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值