Bläddra i källkod

Merge pull request #7527 from tpowellmeto/peppersghosteffect

Added example for peppers ghost effect
Mr.doob 9 år sedan
förälder
incheckning
4a84d1b69c
2 ändrade filer med 275 tillägg och 0 borttagningar
  1. 139 0
      examples/js/effects/PeppersGhostEffect.js
  2. 136 0
      examples/webgl_effects_peppersghost.html

+ 139 - 0
examples/js/effects/PeppersGhostEffect.js

@@ -0,0 +1,139 @@
+/**
+ * Created by tpowellmeto on 29/10/2015.
+ *
+ * peppers ghost effect based on http://www.instructables.com/id/Reflective-Prism/?ALLSTEPS
+ */
+
+THREE.PeppersGhostEffect = function ( renderer ) {
+
+    var scope = this;
+
+    scope.cameraDistance = 15;
+    scope.reflectFromAbove = false;
+
+    // Internals
+    var _halfWidth, _width, _height;
+
+    var _cameraF = new THREE.PerspectiveCamera(); //front
+    var _cameraB = new THREE.PerspectiveCamera(); //back
+    var _cameraL = new THREE.PerspectiveCamera(); //left
+    var _cameraR = new THREE.PerspectiveCamera(); //right
+
+    var _position = new THREE.Vector3();
+    var _quaternion = new THREE.Quaternion();
+    var _scale = new THREE.Vector3();
+
+    // Initialization
+    renderer.autoClear = false;
+
+    this.setSize = function ( width, height ) {
+
+        _halfWidth = width / 2;
+        if ( width < height ) {
+
+            _width = width / 3;
+            _height = width / 3;
+
+        } else {
+
+            _width = height / 3;
+            _height = height / 3;
+
+        }
+        renderer.setSize( width, height );
+
+    };
+
+    this.render = function ( scene, camera ) {
+
+        scene.updateMatrixWorld();
+
+        if ( camera.parent === null ) camera.updateMatrixWorld();
+
+        camera.matrixWorld.decompose( _position, _quaternion, _scale );
+
+        // front
+        _cameraF.position.copy( _position );
+        _cameraF.quaternion.copy( _quaternion );
+        _cameraF.translateZ( scope.cameraDistance );
+        _cameraF.lookAt( scene.position );
+
+        // back
+        _cameraB.position.copy( _position );
+        _cameraB.quaternion.copy( _quaternion );
+        _cameraB.translateZ( - ( scope.cameraDistance ) );
+        _cameraB.lookAt( scene.position );
+        _cameraB.rotation.z += 180 * ( Math.PI / 180 );
+
+        // left
+        _cameraL.position.copy( _position );
+        _cameraL.quaternion.copy( _quaternion );
+        _cameraL.translateX( - ( scope.cameraDistance ) );
+        _cameraL.lookAt( scene.position );
+        _cameraL.rotation.x += 90 * ( Math.PI / 180 );
+
+        // right
+        _cameraR.position.copy( _position );
+        _cameraR.quaternion.copy( _quaternion );
+        _cameraR.translateX( scope.cameraDistance );
+        _cameraR.lookAt( scene.position );
+        _cameraR.rotation.x += 90 * ( Math.PI / 180 );
+
+
+        renderer.clear();
+        renderer.enableScissorTest( true );
+
+        renderer.setScissor( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
+        renderer.setViewport( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
+        if ( scope.reflectFromAbove ) {
+
+            renderer.render( scene, _cameraB );
+
+        } else {
+
+            renderer.render( scene, _cameraF );
+
+        }
+
+        renderer.setScissor( _halfWidth - ( _width / 2 ), 0, _width, _height );
+        renderer.setViewport( _halfWidth - ( _width / 2 ), 0, _width, _height );
+        if ( scope.reflectFromAbove ) {
+
+            renderer.render( scene, _cameraF );
+
+        } else {
+
+            renderer.render( scene, _cameraB );
+
+        }
+
+        renderer.setScissor( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );
+        renderer.setViewport( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );
+        if ( scope.reflectFromAbove ) {
+
+            renderer.render( scene, _cameraR );
+
+        } else {
+
+            renderer.render( scene, _cameraL );
+
+        }
+
+        renderer.setScissor( _halfWidth + ( _width / 2 ), _height, _width, _height );
+        renderer.setViewport( _halfWidth + ( _width / 2 ), _height, _width, _height );
+        if ( scope.reflectFromAbove ) {
+
+            renderer.render( scene, _cameraL );
+
+        } else {
+
+            renderer.render( scene, _cameraR );
+
+        }
+
+        renderer.enableScissorTest( false );
+
+    };
+
+
+};

+ 136 - 0
examples/webgl_effects_peppersghost.html

@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <title>three.js webgl - effects - peppers ghost</title>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+    <style>
+        body {
+            background: #777;
+            padding: 0;
+            margin: 0;
+            font-weight: bold;
+            overflow: hidden;
+        }
+
+        #info {
+            position: absolute;
+            top: 0px;
+            width: 100%;
+            color: #ffffff;
+            padding: 5px;
+            font-family: Monospace;
+            font-size: 13px;
+            text-align: center;
+            z-index: 1000;
+        }
+
+        a {
+            color: #ffffff;
+        }
+
+        #oldie a {
+            color: #da0
+        }
+    </style>
+</head>
+
+<body>
+<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - <a href="https://en.wikipedia.org/wiki/Pepper%27s_ghost">peppers ghost effect</a> demo <br />
+    <a href="http://www.instructables.com/id/Reflective-Prism/?ALLSTEPS">basic instructions for building the reflective prism</a></div>
+
+<script src="../build/three.min.js"></script>
+
+<script src="js/effects/PeppersGhostEffect.js"></script>
+
+<script src="js/Detector.js"></script>
+
+<script>
+
+    if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+    var container;
+
+    var camera, scene, renderer, effect;
+    var cube;
+
+    var windowHalfX = window.innerWidth / 2;
+    var windowHalfY = window.innerHeight / 2;
+
+    init();
+    animate();
+
+    function init() {
+
+        container = document.createElement( 'div' );
+        document.body.appendChild( container );
+
+        camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 100000 );
+
+        scene = new THREE.Scene();
+
+        // Cube
+
+        var geometry = new THREE.BoxGeometry( 1, 1, 1 );
+
+        for ( var i = 0; i < geometry.faces.length; i += 2 ) {
+
+            var hex = Math.random() * 0xffffff;
+            geometry.faces[ i ].color.setHex( hex );
+            geometry.faces[ i + 1 ].color.setHex( hex );
+
+        }
+
+        var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
+
+        cube = new THREE.Mesh( geometry, material );
+        cube.position.y = 1;
+        scene.add( cube );
+
+        renderer = new THREE.WebGLRenderer();
+        renderer.setPixelRatio( window.devicePixelRatio );
+
+        container.appendChild( renderer.domElement );
+
+        effect = new THREE.PeppersGhostEffect( renderer );
+        effect.setSize( window.innerWidth, window.innerHeight );
+        effect.cameraDistance = 5;
+
+        window.addEventListener( 'resize', onWindowResize, false );
+
+    }
+
+    function onWindowResize() {
+
+        windowHalfX = window.innerWidth / 2,
+                windowHalfY = window.innerHeight / 2,
+                camera.aspect = window.innerWidth / window.innerHeight;
+        camera.updateProjectionMatrix();
+
+        effect.setSize( window.innerWidth, window.innerHeight );
+
+    }
+
+    function animate() {
+
+        requestAnimationFrame( animate );
+
+        render();
+
+    }
+
+    function render() {
+
+        camera.lookAt( scene.position );
+
+        cube.rotation.y += 0.01;
+
+        effect.render( scene, camera );
+
+    }
+
+
+</script>
+
+</body>
+</html>