用three.js创建一个简易的天空盒
本文创建的天空盒是用六张图片来创建的。笔者会论述两种方法来创建,都是最简单基本的方法,不涉及着色器的使用。
一种是创建一个盒子,然后将图片作为盒子6个面的纹理贴上来创建。
另一种则是简单的将纹理作为场景的背景来创建。
两种方法视觉效果是几乎没区别的,会给人身临其境的效果,感觉身处在这个3维空间里,最明显的区别就在于当你在用鼠标滚轮缩进的时候,天空盒会“原形毕露”,暴露出其盒子的本性,视觉效果原理展现在你的眼前。如图所示:
而作为背景的方法创建的话,则无论你怎么缩进,都不会“原形毕露”。
当然,缩进的设置我们是可以自己调整的,规定缩进的范围,用第一种方法也是可以不暴露出盒子的原型的。
好,接下来我们来看代码部分。
<div id="WebGL-output"></div>
<script src="../build/three.js"></script>
<script src="../examples/js/controls/OrbitControls.js"></script>
第一步是引用文件,我们是用Three.js来创建天空盒,所以第一个引用的是three.js这个文件,第二引用的文件是OrbitControls.js,这里面的函数是我们用来操控相机的,你可以通过调用这个文件里的函数在天空盒中实现360°的转换视角来观看,前文所述的你如果要调整缩进的话,也是调用里面的函数。
至于第一行的div,是作为我们three.js的输出对象。
写完引用文件,接下来看下正文代码的结构。
<script>
var scene, camera, renderer;
var container, controls;
init();
animate();
// FUNCTIONS
function init()
{
······
}
function animate()
{
······
}
function update()
{
······
}
function render()
{
······
}
</script>
第一步创建会用到的全局变量
three.js不可缺少的三部分:scene(场景), camera(相机), renderer(渲染器);
至于另外两个变量我们在代码中去理解。笔者在此就不多述了。
核心部分是init()函数,先创立三维场景基本要素:
// 创建场景
scene = new THREE.Scene();
// 定义透视相机的四个参数变量
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
//创建相机
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
camera.position.set(0,150,400);//将相机的位置摆放在(0,150,400)的位置。这里位置你可以更改以下,放在(0,0,400)也是可以的
camera.lookAt(scene.position);//让相机对着场景中央
//将相机加入场景之中
scene.add(camera); //设置渲染器
renderer = new THREE.WebGLRenderer( {antialias:true} );//设置为抗锯齿
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);//设置渲染器渲染的场景大小 container = document.getElementById( 'WebGL-output' );
container.appendChild( renderer.domElement );
/*renderer的domElement元素,表示渲染器中的画布,所有的渲染都是画在domElement上的,所以这里的appendChild表示将这个domElement挂接在id=WebGL-output的div下面,这样渲染的结果就能够在页面中显示了。*/ //再设置相机控件,这行代码能让我们360°的旋转相机
controls = new THREE.OrbitControls( camera, renderer.domElement );
接着是创建天空盒的代码:
var path = "../examples/textures/cube/Park3Med/";//设置路径
var directions = ["px", "nx", "py", "ny", "pz", "nz"];//获取对象
var format = ".jpg";//格式
//创建盒子,并设置盒子的大小为( 5000, 5000, 5000 )
var skyGeometry = new THREE.BoxGeometry( 5000, 5000, 5000 );
//设置盒子材质
var materialArray = [];
for (var i = 0; i < 6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture( path + directions[i] + format ),//将图片纹理贴上
side: THREE.BackSide/*镜像翻转,如果设置镜像翻转,那么只会看到黑漆漆的一片,因为你身处在盒子的内部,所以一定要设置镜像翻转。*/
}));
var skyMaterial = new THREE.MeshFaceMaterial( materialArray );
var skyBox = new THREE.Mesh( skyGeometry, skyMaterial );//创建一个完整的天空盒,填入几何模型和材质的参数
scene.add( skyBox );//在场景中加入天空盒
注意directions[]数组中的图片顺序是有要求而不是随意的!否则加载的效果会错乱。这张图片会帮助你更好的理解:
剩下的尾巴部分:
function animate()
{
requestAnimationFrame( animate );//渲染循环
render();
update();
} function update()
{
controls.update();//实时更新相机操作
} function render()
{
renderer.render( scene, camera );//实时渲染
}
另一种作为背景的方法的代码如下:
var path = "textures/cube/Park3Med/"; //设置路径
var format = '.jpg'; //设定格式
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
var textureCube = new THREE.CubeTextureLoader().load( urls ); scene.background = textureCube; //作为背景贴图
还有另一种更简洁的写法是:
scene.background = new THREE.CubeTextureLoader()
.setPath( 'textures/cube/Park3Med/' )
.load( [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ] );
两种方法只需要更换这部分代码即可。
以下给出全部代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Skybox</title>
<style>
body {
background:#777;
padding:0;
margin:0;
font-weight: bold;
overflow:hidden;
}
</style>
</head>
<body> <div id="WebGL-output"></div>
<script src="../build/three.js"></script>
<script src="../examples/js/controls/OrbitControls.js"></script> <script> var scene, camera, renderer;
var container, controls; init();
animate(); // FUNCTIONS
function init()
{
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
camera.position.set(0,150,400);
camera.lookAt(scene.position); scene.add(camera); // RENDERER renderer = new THREE.WebGLRenderer( {antialias:true} );
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); container = document.getElementById( 'output' );
container.appendChild( renderer.domElement ); controls = new THREE.OrbitControls( camera, renderer.domElement ); // LIGHT
var light = new THREE.PointLight(0xffffff);
light.position.set(0,250,0);
scene.add(light);
// FLOOR var path = "../examples/textures/cube/Park3Med/";
var directions = ["px", "nx", "py", "ny", "pz", "nz"];
var format = ".jpg";
var skyGeometry = new THREE.BoxGeometry( 5000, 5000, 5000 ); var materialArray = [];
for (var i = 0; i < 6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture( path + directions[i] + format ),
side: THREE.BackSide
}));
var skyMaterial = new THREE.MeshFaceMaterial( materialArray );
var skyBox = new THREE.Mesh( skyGeometry, skyMaterial );
//skyBox.scale.x=-1;也是镜像翻转,与上面的side一个效果
scene.add( skyBox ); } function animate()
{
requestAnimationFrame( animate );
render();
update();
} function update()
{
controls.update();
} function render()
{
renderer.render( scene, camera );
} </script>
</body>
</html>
以上有一段代码是灯光的设置加入,这里可以注释掉,不影响天空盒的效果。但是如果你要在天空盒中加入物体,则需要设置灯光,否则加入场景的物体将会是黑色的。
以上就是笔者的一些见解,若有不对的对方,欢迎指正。
用three.js创建一个简易的天空盒的更多相关文章
- avalon.js实现一个简易日历
使用MVVM框架avalon.js实现一个简易日历 最近在做公司内部的运营管理系统,因为与日历密切相关,同时无需触发条件直接显示在页面上,所以针对这样的功能场景,我就用avalon快速实现了一个简 ...
- 依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在<依赖注入[4]: 创建一个简易版的DI框架[上篇]> ...
- 依赖注入[4]: 创建一个简易版的DI框架[上篇]
本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章(<控制反转>.<基于IoC的设计模式>和< 依赖注入模式>)从纯理论的角度 ...
- .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]
原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...
- 使用Python创建一个简易的Web Server
Python 2.x中自带了SimpleHTTPServer模块,到Python3.x中,该模块被合并到了http.server模块中.使用该模块,可以快速创建一个简易的Web服务器. 我们在C:\U ...
- 使用 js 实现一个简易版的模版引擎
使用 js 实现一个简易版的模版引擎 regex (function test() { this.str = str; })( window.Test = ...; format() { let ar ...
- 使用 js 实现一个简易版的 drag & drop 库
使用 js 实现一个简易版的 drag & drop 库 具有挑战性的前端面试题 H5 DnD js refs https://www.infoq.cn/article/0NUjpxGrqRX ...
- 使用 js 实现一个简易版的动画库
使用 js 实现一个简易版的动画库 具有挑战性的前端面试题 animation css refs https://www.infoq.cn/article/0NUjpxGrqRX6Ss01BLLE x ...
- 使用 js 实现一个简易版的 GIPHY 动图搜索 web 应用程序
使用 js 实现一个简易版的 GIPHY 动图搜索 web 应用程序 具有挑战性的前端面试题 API JAMstack refs https://www.infoq.cn/article/0NUjpx ...
随机推荐
- 面向对象的线程池Threadpool的封装
线程池是一种多线程处理形式,预先创建好一定数量的线程,将其保存于一个容器中(如vector), 处理过程中将任务添加到队列,然后从容器中取出线程后自动启动这些任务,具体实现如下. 以下是UML图,展示 ...
- numpy 实践记录
reshape是从低维度到高维度.max,sum等函数都是注意axis,不选择就是全体计算. swapaxes 转换轴,将两个选择的轴对调,在CNN中X乘W有的时候需要拉伸,如果轴不同结果不对. 看p ...
- 2016年android程序员需要知道的新技术
2016你需要了解Android有以下新兴的技术与框架,有些也许还不成熟,但是你应该去了解下,也许就是未来的方向. Kotlin 作为 Android 领域的 Swift,绝对让你如沐新风.抛弃沉重的 ...
- Windows PowerShell漫谈-win7下没有超级终端
Windows PowerShell是我在研究win7新特性的时候发现的新工具,起初没有对它产生太大的兴趣,只是简单看看了有关它的介绍.简单使用了一下,感觉上它和cmd.exe没有本质区别.对它产生兴 ...
- mxnet:结合R与GPU加速深度学习
转载于统计之都,http://cos.name/tag/dmlc/,作者陈天奇 ------------------------------------------------------------ ...
- MP4文件格式的解析
MP4文件格式的解析,以及MP4文件的分割算法 mp4应该算是一种比较复杂的媒体格式了,起源于QuickTime.以前研究的时候就花了一番的功夫,尤其是如何把它完美的融入到视频点播应用中,更是费尽了心 ...
- Linux显示各栏位的标题信息列
Linux显示各栏位的标题信息列 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ who -H 名称 线路 时间 备注 youhaidong :0 2015-0 ...
- javaWeb中request请求转发和response重定向
1.访问资源 运用forward方法只能重定向到同一个Web应用程序中的一个资源. 而sendRedirect方法可以让你重定向到任何URL. 2.request.get Forward代码中的&q ...
- ONCOCNV软件思路分析之control处理
进行数据初步处理(perl) 统计amplicon的RC(read counts),并且相互overlap大于75%的amplicon合并起来 统计每个amplicon的GC含量,均值, 性别识别并校 ...
- C# 找出泛型集合中的满足一定条件的元素 List.Wher()
在学习的过程中,发现泛型集合List<T>有一个Where函数可以筛选出满足一定条件的元素,结合Lambda表达式使用特别方便,写出来与大家分享. 1.关于Func<> Fun ...