实现功能
1.加载天空图。
2.OrbitControls视角控制器。
3.正方体6个面加载不同纹理。
实现效果
完整代码请看最底下,接下来进行分段功能介绍
功能代码解释
1.加载天空图
第一步:创建天空图纹理。先将全景图的6个面文件路径加载到一个数组,然后调用loadTextureCube(不是loadTexture)方法加载纹理组合。
function createCubeMap() {
var path = "../assets/textures/cubemap/parliament/";
var format = '.jpg';
var urls = [
path + 'posx' + format, path + 'negx' + format,
path + 'posy' + format, path + 'negy' + format,
path + 'posz' + format, path + 'negz' + format
];//加载6张图
var textureCube = THREE.ImageUtils.loadTextureCube(urls);//加载纹理
return textureCube;//函数返回此纹理
}
第二步:创建天空背景图。
var textureCube = createCubeMap();//调用函数创建纹理
scene.background = textureCube ;//将场景的背景设置为天空图纹理
textureCube.format = THREE.RGBFormat;
var shader = THREE.ShaderLib["cube"];//自定义着色器
shader.uniforms["tCube"].value = textureCube;
var material = new THREE.ShaderMaterial({
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.DoubleSide //要能看到天空盒内部
});
//创建天空盒网格
var skybox = new THREE.Mesh(new THREE.BoxGeometry(10000, 10000, 10000), material);
2.OrbitControls视角控制器。
这个设置比较简单,只要几步就能完成。
首先加载js代码包;
<script src="../libs/OrbitControls.js"></script>
然后然后将相机添加到OrbitControls视角控制器;
orbit = new THREE.OrbitControls(camera);
最后再渲染循环时更新视角控制器的视角控制。
orbit.update();
3.正方体6个面加载不同纹理。
先解释以下下面展示代码的原理,一开始我也不理解,后来我打开开发者模式我 们查看网格的属性可以看到,其实每一个网格的gemotry属性中的faces属性中的12个面中,每一个面都有一个材质索引(materialIndex),该索引可以将我们所加载的6个纹理分别赋值给单个索引。我们分别查看每一个面的材质索引(materialIndex)可以发现一个索引对应两个面,所以6个纹理正好赋值给了正方体6个面的每一个面。
具体操作代码中有注释进行解释。
//调用setMech方法创建一个长宽高各为6的正方体
var cube = setMesh(new THREE.BoxGeometry(6, 6, 6));
//此方法可以加载6种不同纹理赋值给材质并且根据传入集合体创建网格。
function setMesh(cubeG) {
//加载6种纹理
var texture1 = THREE.ImageUtils.loadTexture("../assets/textures/general/bathroom.jpg");
var texture2 = THREE.ImageUtils.loadTexture("../assets/textures/general/weave.jpg");
var texture3 = THREE.ImageUtils.loadTexture("../assets/textures/general/plaster.jpg");
var texture4 = THREE.ImageUtils.loadTexture("../assets/textures/general/stone.jpg");
var texture5 = THREE.ImageUtils.loadTexture("../assets/textures/general/brick-wall.jpg");
var texture6 = THREE.ImageUtils.loadTexture("../assets/textures/general/metal-rust.jpg");
//创建纹理数组
var mats = [];
mats.push(new THREE.MeshBasicMaterial({map: texture1}));
mats.push(new THREE.MeshBasicMaterial({map: texture2}));
mats.push(new THREE.MeshBasicMaterial({map: texture3}));
mats.push(new THREE.MeshBasicMaterial({map: texture4}));
mats.push(new THREE.MeshBasicMaterial({map: texture5}));
mats.push(new THREE.MeshBasicMaterial({map: texture6}));
//MeshFaceMaterial这种材质能接收纹理组合
var cubeM = new THREE.MeshFaceMaterial(mats);
return cube = new THREE.Mesh(cubeG, cubeM);
}
**4.**另外还设置了gui进行控制,本文就不加以介绍,有新手不懂的可以跟我留言交流。
完整代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TextureTest</title>
<script src="../libs/three.js"></script>
<script src="../libs/dat.gui.js"></script>
<script src="../libs/OrbitControls.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="WebGL-output"></div>
<script>
function init() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
orbit = new THREE.OrbitControls(camera);
camera.position.x = 0;
camera.position.y = -10;
camera.position.z = -100;
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
var textureCube = createCubeMap();
scene.background = textureCube ;
textureCube.format = THREE.RGBFormat;
var shader = THREE.ShaderLib["cube"];
shader.uniforms["tCube"].value = textureCube;
var material = new THREE.ShaderMaterial({
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.DoubleSide
});
var skybox = new THREE.Mesh(new THREE.BoxGeometry(10000, 10000, 10000), material);
scene.add(skybox);
var cube = setMesh(new THREE.BoxGeometry(6, 6, 6));
scene.add(cube);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
var controls = new function () {
this.positionX = 0;
this.positionY = 0;
this.positionZ = 0;
this.rotationSpeed = 0.01;
this.rotation = true ;
this.visible = true;
};
var gui = new dat.GUI();
guiPosition = gui.addFolder('position');
guiPosition.add(controls, 'positionX', -10, 10).onChange(function (value) {
cube.position.x = controls.positionX;
});
guiPosition.add(controls, 'positionY', -10, 10).onChange(function (value) {
cube.position.y = controls.positionY;
});
guiPosition.add(controls, 'positionZ', -10, 10).onChange(function (value) {
cube.position.z = controls.positionZ;
});
gui.add(controls,'rotation');
gui.add(controls,'rotationSpeed',0.001,0.5);
gui.add(controls, 'visible');
document.getElementById("WebGL-output").appendChild(renderer.domElement);
render();
function render() {
orbit.update();
cube.visible = controls.visible;
if (controls.rotation){
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
}
requestAnimationFrame(render);
renderer.render(scene, camera);
}
}
function setMesh(cubeG) {
var texture1 = THREE.ImageUtils.loadTexture("../assets/textures/general/bathroom.jpg");
var texture2 = THREE.ImageUtils.loadTexture("../assets/textures/general/weave.jpg");
var texture3 = THREE.ImageUtils.loadTexture("../assets/textures/general/plaster.jpg");
var texture4 = THREE.ImageUtils.loadTexture("../assets/textures/general/stone.jpg");
var texture5 = THREE.ImageUtils.loadTexture("../assets/textures/general/brick-wall.jpg");
var texture6 = THREE.ImageUtils.loadTexture("../assets/textures/general/metal-rust.jpg");
var mats = [];
mats.push(new THREE.MeshBasicMaterial({map: texture1}));
mats.push(new THREE.MeshBasicMaterial({map: texture2}));
mats.push(new THREE.MeshBasicMaterial({map: texture3}));
mats.push(new THREE.MeshBasicMaterial({map: texture4}));
mats.push(new THREE.MeshBasicMaterial({map: texture5}));
mats.push(new THREE.MeshBasicMaterial({map: texture6}));
var cubeM = new THREE.MeshFaceMaterial(mats);
return cube = new THREE.Mesh(cubeG, cubeM);
}
function createCubeMap() {
var path = "../assets/textures/cubemap/parliament/";
var format = '.jpg';
var urls = [
path + 'posx' + format, path + 'negx' + format,
path + 'posy' + format, path + 'negy' + format,
path + 'posz' + format, path + 'negz' + format
];
var textureCube = THREE.ImageUtils.loadTextureCube(urls);
return textureCube;
}
window.onload = init;
</script>
</body>
</html>
欢迎大家留言一起交流互相学习呀!