本文创建的天空盒是用六张图片来创建的。论述三种方法来创建,前两种比较简单,第三中牵扯到着色器的使用,但是只要会使用即可,无需深入的理解。
一种是创建一个盒子,然后将图片作为盒子6个面的纹理贴上来创建。
另一种则是简单的将纹理作为场景的背景来创建。
第三种是通过着色器的形式
三种方法视觉效果是几乎没区别的,会给人身临其境的效果,感觉身处在这个3维空间里,最明显的区别
就在于当你在用鼠标滚轮缩进的时候,天空盒会“原形毕露”,暴露出其盒子的本性,视觉效果原理展现在你的眼前。如图所示:
而作为背景的方法创建的话,则无论你怎么缩进,都不会“原形毕露”。
当然,缩进的设置我们是可以自己调整的,规定缩进的范围,用第一种方法也是可以不暴露出盒子的原型的。
方法一:创建一个盒子
接着是创建天空盒的代码:
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[]数组中的图片顺序是有要求而不是随意的!否则加载的效果会错乱。这张图片会帮助你更好的理解:
方法二:利用CUBETEXTURELOADER设置scene的背景
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' ]
);
方法三:利用着色器
let urls = [
'./res/skybox/px.jpg', // right
'./res/skybox/nx.jpg', // left
'./res/skybox/py.jpg', // top
'./res/skybox/ny.jpg', // bottom
'./res/skybox/pz.jpg', // back
'./res/skybox/nz.jpg' // front
];
let skyboxCubemap = new THREE.CubeTextureLoader().load(urls);
skyboxCubemap.format = THREE.RGBFormat;
let skyboxShader = THREE.ShaderLib['cube'];
skyboxShader.uniforms['tCube'].value = skyboxCubemap;
skyBox = new THREE.Mesh(
new THREE.BoxGeometry(10000, 10000, 10000),
new THREE.ShaderMaterial({
fragmentShader: skyboxShader.fragmentShader,//片段着色器
vertexShader: skyboxShader.vertexShader,//顶点着色器
uniforms: skyboxShader.uniforms,//是所有顶点都具有相同的值的变量。 比如灯光,
雾,和阴影贴图就是被储存在uniforms中的数据。 uniforms可以通过顶点着色器和片元着色器来访问。
depthWrite: false,//深度测试
side: THREE.BackSide//正反面
})
);
skyBox.name = 'StarSky';