PeppersGhostEffect实现佩珀的幽灵效果
佩珀的幽灵是一种用于剧院,游乐园,博物馆,电视和音乐会的幻觉技巧。它以英国科学家约翰亨利佩珀(1821-1900)的名字命名,他在1862年的示威活动中推广了这种效果。
在threejs中,通过该效果变换,幽灵般的物体在场景中看起来淡入或淡出,或者场景中的物体神奇地变换成不同的物体。
①首先引用插件包,该js文件在threejs工程文件夹的example目录下的js/effects/可以找到
<script type="text/javascript" src="js/effects/PeppersGhostEffect.js" ></script>
②实例化PeppersGhostEffect对象,并传入参数,设置属性
effect=new THREE.PeppersGhostEffect(renderer);
effect.setSize(window.innerWidth,window.innerHeight);
effect.cameraDistance=5;//设置效果的距离远近
③最后在循环渲染
function render(){
effect.render(scene,camera);
}
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>佩珀的幽灵</title>
<script type="text/javascript" src="js/three.js" ></script>
<script type="text/javascript" src="js/controls/OrbitControls.js" ></script>
<script type="text/javascript" src="js/libs/stats.min.js" ></script>
<script type="text/javascript" src="js/libs/dat.gui.min.js" ></script>
<script type="text/javascript" src="js/WebGL.js" ></script>
<script type="text/javascript" src="js/effects/PeppersGhostEffect.js" ></script>
<style>
body{
padding: 0;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script>
if(WEBGL.isWebGLAvailable()===false){alert("该浏览器不支持WebGL!");document.body.appendChild(WEBGL.getWebGLErrorMessage());}
var scene,renderer,camera,controls,stats;
var effect;
function init(){
scene=new THREE.Scene();
renderer=new THREE.WebGLRenderer({
antialias:true,
});
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
camera=new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,100000);
controls=new THREE.OrbitControls(camera,renderer.domElement);
controls.enableDamping=true;
controls.minDistance=0.1;
controls.maxDistance=1000;
stats=new Stats();
document.body.appendChild(stats.domElement);
scene.add(new THREE.AmbientLight(0xffffff));
effect=new THREE.PeppersGhostEffect(renderer);
effect.setSize(window.innerWidth,window.innerHeight);
effect.cameraDistance=5;//设置效果物体的距离
};
var axes;
var group=new THREE.Group();
function initModel(){
axes=new THREE.AxesHelper(30);
axes.visible=false;
scene.add(axes);
var geometry=new THREE.BoxBufferGeometry(1,1,1);
geometry=geometry.toNonIndexed();//确保每个三角形具有唯一的顶点
var position=geometry.attributes.position;
console.log(position);
var colors=[];
var color=new THREE.Color();//为多维数据集的每一侧生成不同的颜色
for(var i=0;i<position.count;i+=6){
color.setHex(Math.random()*0xffffff);
//第一个面
colors.push(color.r,color.g,color.b);
colors.push(color.r,color.g,color.b);
colors.push(color.r,color.g,color.b);
//第二个面
colors.push(color.r,color.g,color.b);
colors.push(color.r,color.g,color.b);
colors.push(color.r,color.g,color.b);
}
geometry.addAttribute("color",new THREE.Float32BufferAttribute(colors,3));
var material=new THREE.MeshBasicMaterial({
vertexColors:THREE.VertexColors
});
for(var i=0;i<10;i++){
var cube=new THREE.Mesh(geometry,material);
cube.position.x=Math.random()*2-1;
cube.position.y=Math.random()*2-1;
cube.position.z=Math.random()*2-1;
var s=Math.random()+0.5;
cube.scale.set(s,s,s);
group.add(cube);
}
scene.add(group);
}
var setting;
function initGui(){
setting={
axesVisible:false,
isPeppersGhost:true,
cameraDistance:5
};
var gui=new dat.GUI();
gui.add(setting,"axesVisible").onChange(function(e){
axes.visible=e;
});
gui.add(setting,"isPeppersGhost");
gui.add(setting,"cameraDistance",1,100).step(1).onChange(function(e){
effect.cameraDistance=e;
});
}
function onWindowResize(){
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
function render(){
group.rotation.y+=0.01;
if(setting.isPeppersGhost){
effect.render(scene,camera);
}else{
renderer.render(scene,camera);
}
}
function animate(){
render();
stats.update();
controls.update();
window.onresize=onWindowResize();
requestAnimationFrame(animate);
}
function threeStart(){
init();
initModel();
initGui();
animate();
}
threeStart();
</script>
</body>
</html>