WEB/WebGL

[WebGL] Three.js - Multiple Cameras

AlrepondTech 2017. 11. 1. 18:02
반응형

 



=======================

=======================

=======================

 

 

 

 

 

출처: http://cinema4dr12.tistory.com/773

[WebGL] Multiple Cameras

 

이번 예제에서는 화면을 2분할 하고 우측 화면에는 가상 카메라의 움직임을, 좌측 화면에는 가상 카메라를 통해 입력되는 영상을 표시한다.

 

[Download Project]

05-02-multiple-cameras.zip
다운로드

 

FULL SCREEN

 

 

[Operations]

W: Move forwardS: Move backwardQ: Move to the leftE: Move to the rightA: Rotate to the leftD: Rotate to the right


[main.js]

// MAIN // standard global variables var container, scene, camera, renderer, controls, stats; var keyboard = new THREEx.KeyboardState(); var clock = new THREE.Clock(); // custom global variables var video, videoImage, videoImageContext, videoTexture; // mirror mesh / mirror camera material var mirrorSphere, mirrorSphereCamera; var player = new THREE.Object3D(); var dae, skin; var loader = new THREE.ColladaLoader(); loader.options.convertUpAxis = true; loader.load( 'models/CamCoder.dae', function ( collada ) { dae = collada.scene; skin = collada.skins[ 0 ]; dae.position.set( 0, 0, 70 ); dae.scale.x = dae.scale.y = dae.scale.z = 10; dae.rotation.y = Math.PI; dae.castShadow = true; dae.updateMatrix(); init(); animate(); } ); // FUNCTIONS function init() { // SCENE scene = new THREE.Scene(); // CAMERA var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000; camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR); scene.add(camera); camera.position.set(0,0,400); camera.lookAt(scene.position); // RENDERER if ( Detector.webgl ) renderer = new THREE.WebGLRenderer( { antialias:true } ); else renderer = new THREE.CanvasRenderer(); renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); container = document.createElement( 'div' ); // CSS added so the hidden HTML elements do not reposition this one container.style.cssText = "position:absolute;top:0px;left:0px;"; document.body.appendChild( container ); container.appendChild( renderer.domElement ); // EVENTS THREEx.WindowResize(renderer, camera); THREEx.FullScreen.bindKey({ charCode : 'f'.charCodeAt(0) }); // STATS stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.bottom = '0px'; stats.domElement.style.zIndex = 100; container.appendChild( stats.domElement ); // Enables Shadow Map renderer.shadowMapEnabled = true; // Point Light var pointLight = new THREE.PointLight(0xffffff); pointLight.position.set(0,250,0); scene.add(pointLight); // Directional Light var dirLight = new THREE.DirectionalLight(0xffffff); dirLight.position.set(0,250,0); dirLight.shadowCameraVisible = false; dirLight.shadowDarkness = 0.5; dirLight.intensity = 2; dirLight.castShadow = true; var lightTarget = new THREE.Object3D(); var targetPosition = new Array(); targetPosition[0] = 0; targetPosition[1] = -10; targetPosition[2] = 200; lightTarget.position.set(targetPosition[0], targetPosition[1], targetPosition[2]); scene.add(lightTarget); dirLight.target = lightTarget; scene.add(dirLight); // FLOOR var floorTexture = new THREE.ImageUtils.loadTexture( 'img/Wood_floor.jpg' ); floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping; floorTexture.repeat.set( 1, 1 ); var floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture, side: THREE.DoubleSide } ); var floorGeometry = new THREE.CircleGeometry(500, 20); var floor = new THREE.Mesh(floorGeometry, floorMaterial); floor.position.y = -0.5; floor.rotation.x = Math.PI / 2; floor.receiveShadow = true; scene.add(floor); // SKYBOX/FOG var materialArray = []; materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/px.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/nx.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/py.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/ny.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/pz.jpg' ) })); materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'img/nz.jpg' ) })); for (var i = 0; i < 6; i++) materialArray[i].side = THREE.BackSide; var skyboxMaterial = new THREE.MeshFaceMaterial( materialArray ); var skyboxGeom = new THREE.CubeGeometry( 5000, 5000, 5000, 1, 1, 1 ); var skybox = new THREE.Mesh( skyboxGeom, skyboxMaterial ); scene.add( skybox ); scene.add( player ); /////////// // VIDEO // /////////// video = document.getElementById( 'monitor' ); videoImage = document.getElementById( 'videoImage' ); videoImageContext = videoImage.getContext( '2d' ); // background color if no video present videoImageContext.fillStyle = '#000000'; videoImageContext.fillRect( 0, 0, videoImage.width, videoImage.height ); videoTexture = new THREE.Texture( videoImage ); videoTexture.minFilter = THREE.LinearFilter; videoTexture.magFilter = THREE.LinearFilter; var movieMaterial = new THREE.MeshBasicMaterial( { map: videoTexture, overdraw: true, side:THREE.DoubleSide } ); // the geometry on which the movie will be displayed; var movieGeometry = new THREE.PlaneGeometry( 100, 100, 1, 1 ); // attach video to a mesh that will move with the camera this.movieScreen = new THREE.Mesh( movieGeometry, movieMaterial ); // add a frame to the image. var frameGeo = new THREE.CubeGeometry(120, 120, 20); var frameMat = new THREE.MeshLambertMaterial( {color:0x888888, emissive:0x000011} ); this.frameMesh = new THREE.Mesh( frameGeo, frameMat ); this.frameMesh.castShadow = true; // "attach" player to camera player.position = camera.position; player.rotation = camera.rotation; // Add a collada(DAE) mesh player.add( dae ); /////////////////// // Mirror Sphere // /////////////////// var sphereGeom = new THREE.SphereGeometry( 50, 64, 32 ); // radius, segmentsWidth, segmentsHeight mirrorSphereCamera = new THREE.CubeCamera( 0.1, 5000, 256 ); mirrorSphereCamera.renderTarget.minFilter = THREE.LinearMipMapLinearFilter; scene.add( mirrorSphereCamera ); var mirrorSphereMaterial = new THREE.MeshPhongMaterial( { emissive: 0x8888aa, envMap: mirrorSphereCamera.renderTarget } ); mirrorSphere = new THREE.Mesh( sphereGeom, mirrorSphereMaterial ); mirrorSphere.position.set(0, 50, 0); mirrorSphereCamera.position = mirrorSphere.position; mirrorSphere.castShadow = true; scene.add(mirrorSphere); camera.position.set(114,50,-61); camera.rotation.set(3.14, 0.875, 3.14); ////////////////////// // Secondary camera // ////////////////////// this.topCamera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR ); scene.add(topCamera); topCamera.position.set(0,200+50,550+200); topCamera.lookAt(scene.position); // other camera stuff renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setClearColor( 0x000000, 1 ); renderer.autoClear = false; } function animate() { requestAnimationFrame( animate ); render(); update(); } function update() { if ( keyboard.pressed("p") ) // pause webcam video.pause(); if ( keyboard.pressed("r") ) // resume webcam video.play(); var delta = clock.getDelta(); // seconds. var moveDistance = 100 * delta; // 100 pixels per second var rotateAngle = Math.PI / 2 * delta; // pi/2 radians (90 degrees) per second var previousPosition = camera.position.clone(); var previousRotation = camera.rotation.clone(); // move forwards/backwards/left/right (local coordinates) if ( keyboard.pressed("W") ) camera.translateZ( -moveDistance ); if ( keyboard.pressed("S") ) camera.translateZ( moveDistance ); if ( keyboard.pressed("Q") ) camera.translateX( -moveDistance ); if ( keyboard.pressed("E") ) camera.translateX( moveDistance ); // rotate left/right/up/down if ( keyboard.pressed("A") ) camera.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle); if ( keyboard.pressed("D") ) camera.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle); var d = camera.position.distanceTo( mirrorSphere.position ); if ( d > 500 || d < 60 ) { camera.position = previousPosition; camera.rotation = previousRotation; player.position = camera.position; player.rotation = camera.rotation; } stats.update(); } function render() { // update image from webcam if ( video.readyState === video.HAVE_ENOUGH_DATA ) { videoImageContext.drawImage( video, 0, 0, videoImage.width, videoImage.height ); if ( videoTexture ) videoTexture.needsUpdate = true; } // update cameras var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; camera.aspect = 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT; camera.updateProjectionMatrix(); topCamera.aspect = 0.5 * SCREEN_WIDTH / SCREEN_HEIGHT; topCamera.updateProjectionMatrix(); // setViewport parameters: // lower_left_x, lower_left_y, viewport_width, viewport_height renderer.setViewport( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); //renderer.clear(); // left side renderer.setViewport( 1, 1, 0.5 * SCREEN_WIDTH - 2, SCREEN_HEIGHT - 2 ); // move the CubeCamera to the position of the object // that has a reflective surface, "take a picture" in each direction // and apply it to the surface. // need to hide mirror surface before and after so that it does not // "get in the way" of the camera movieScreen.visible = true; mirrorSphere.visible = false; renderer.autoClear = true; mirrorSphereCamera.updateCubeMap( renderer, scene ); renderer.autoClear = false; mirrorSphere.visible = true; movieScreen.visible = false; renderer.render( scene, camera ); // right side movieScreen.visible = true; mirrorSphere.visible = true; renderer.setViewport( 0.5 * SCREEN_WIDTH + 1, 1, 0.5 * SCREEN_WIDTH - 2, SCREEN_HEIGHT - 2 ); renderer.render( scene, topCamera ); }

 



=======================

=======================

=======================

 

 

반응형