版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37338983/article/details/82659082
在文章:three.js贴图之CubeTextureLoader全景贴图中已经讲过全景贴图的应用,本文将进一步扩展全景贴图的功能,结合THREE.CubeCamera功能,创建出一个具有反光效果的场景,首先来看看看看THREE.CubeCamera的用法:
let cubeCamera = new THREE.CubeCamera(0.1, 10000, 128);//实例化一个cubeCamera
scene.add(cubeCamera);//将其添加到场景中
let dynamicEnvMaterial = new THREE.MeshBasicMaterial({
envMap: cubeCamera.renderTarget, side: THREE.DoubleSide
}); //新建一个动态环境材料,envMap为环境贴图,设置为cubeCamera的渲染目标
cubeCamera.updateCubeMap(renderer, scene);//更新渲染立方体贴图
THREE.CubeCamera(near, far, cubeResolution)总共接收三个参数,前两个参数表示最近距离和最远距离,和THREE.PerspectiveCamera中的near和far一个道理,最后一个参数按字面理解为立方体分辨率,通俗的理解为物体对场景反光的清晰度,即越大越清晰,可以取128、256、512、1080等;本文实现一个球将周围场景反光,类似于镜子,你可以在球的表面上看到周围场景的镜像。demo实现效果如下图:
demo代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>场景反光</title>
<script type="text/javascript" src="build/three.js"></script>
<script type="text/javascript" src="js/controls/OrbitControls.js"></script>
<script type="text/javascript" src="js/libs/stats.js"></script>
<style>
body {
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script type="text/javascript" >
let container1 = document.createElement('div');
document.body.appendChild(container1);
let container2 = document.createElement('div');
document.body.appendChild(container2);
let scene = undefined;
let renderer = undefined;
let camera = undefined;
let cubeCamera = undefined;
let pointLight = ambientLight = undefined;
let sphere = undefined, cube = undefined;
let controls = undefined;
let stats = undefined;
main();
render();
function main() {
initScene();
initRenderer(container1);
initCamera();
initLight();
initControls();
createScene();
initStats(container2);
window.addEventListener('resize', onWindowResize, false);
}
function initScene() {
scene = new THREE.Scene();
}
function initCamera() {
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 5, 35);
camera.lookAt(scene.position);
}
function initRenderer(container1) {
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setClearColor(0xffffff, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
container1.appendChild(renderer.domElement);
}
function initLight() {
ambientLight = new THREE.AmbientLight(0xffffff, 0.35);
scene.add(ambientLight);
pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(10, 10, 10);
scene.add(pointLight);
}
function initControls() {
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = false;
controls.enableKeys = true;
}
function textureBox() {
let geometry = new THREE.BoxGeometry(3, 3, 3, 30, 30, 30);
let map = new THREE.TextureLoader().load('textures/brick_bump.jpg');
let material = new THREE.MeshPhongMaterial({map:map, side: THREE.DoubleSide});
let box = new THREE.Mesh(geometry, material);
scene.add(box);
}
function createScene() {
//创建一个立方体贴图
let textureCube = new THREE.CubeTextureLoader().setPath("textures/cube/Park3Med/")
.load([
'px.jpg',
'nx.jpg',
'py.jpg',
'ny.jpg',
'pz.jpg',
'nz.jpg'
]);
textureCube.format = THREE.RGBFormat;
textureCube.mapping = THREE.CubeReflectionMapping;
//创建用户shader
let shader = THREE.ShaderLib["cube"];
shader.uniforms["tCube"].value = textureCube;
let material = new THREE.ShaderMaterial({
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
side: THREE.DoubleSide
});
let skyBox = new THREE.Mesh(new THREE.BoxGeometry(800, 800, 800), material);
scene.add(skyBox);
cubeCamera = new THREE.CubeCamera(0.1, 10000, 1080);
scene.add(cubeCamera);
let sphereGeo = new THREE.SphereGeometry(10, 30, 30);
let cubeGeo = new THREE.BoxGeometry(10, 10, 10, 10, 10, 10);
let dynamicEnvMaterial = new THREE.MeshBasicMaterial({
envMap: cubeCamera.renderTarget, side: THREE.DoubleSide
});
let envMaterial = new THREE.MeshBasicMaterial({
envMap: textureCube, side:THREE.DoubleSide
});
sphere = new THREE.Mesh(sphereGeo, dynamicEnvMaterial);
scene.add(sphere);
cube = new THREE.Mesh(cubeGeo, envMaterial);
cube.position.set(30, 0, 0);
scene.add(cube);
}
function initStats(container2) {
stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
container2.appendChild(stats.domElement);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight);
}
function render() {
controls.update();
stats.update();
// sphere.visible = false;
cubeCamera.updateCubeMap(renderer, scene);
// sphere.visible = true;
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
requestAnimationFrame(render);
renderer.render(scene, camera);
}
</script>
</body>
</html>