Stereo example 1 (for reference; optional)

stereo1.html  [download]

<!DOCTYPE html>

<html>
<head>

<title>Comp 86 example: Stereo 1</title>

<script src="libs/build/three.min.js"></script>
<script src="libs/examples/js/Detector.js"></script>
<script src="libs/examples/js/controls/OrbitControls.js"></script>

<script type="text/javascript">

/*
 * Example: Stereo, using threejs library features
 */

/*
 ***************************************************
 * This code replaces boiler.js to do stereo
 ***************************************************
 */

// Global variables
var scene, renderer, camera, controls, effect;

window.onload = function () {
	// Most browsers now support WebGLRenderer
	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setClearColor( new THREE.Color ("lightgrey"))
	renderer.setSize( window.innerWidth, window.innerHeight );
	document.getElementById('theContainer').appendChild(renderer.domElement);

	// Create the scene
	scene = new THREE.Scene();

	// Put a camera into the scene
	camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
	camera.position.set(0, 0, 16);
	scene.add(camera);

	// Create a camera contol
	controls = new THREE.OrbitControls( camera, renderer.domElement );
	controls.addEventListener( 'change', render );

	// Now add the stereo effect, which will affect rendering
	effect = new StereoEffect( renderer ); //*1 Add stereo effect, affects rendering

	// Add our stuff to the scene, kept in a separate function
	makeSceneGraph()

	render()
	animate()
}

// Animation loop
function animate() {
	requestAnimationFrame( animate );
	controls.update()
}

// Render the scene, by calling the stereo effect
function render() { //*2 Render the scene, by calling the stereo effect
	effect.render( scene, camera ); //*2
}

// In case window is resized
window.onresize = function () {
	renderer.setSize( window.innerWidth, window.innerHeight );

	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();

	render();
}

/*
 * StereoEffect: based on downloaded one from threejs lib,
 * which in turn calls their StereoCamera
 * (uses old style class definition)
 */
var StereoEffect = function ( renderer ) { //*3 Based on threejs library
	var _stereo = new THREE.StereoCamera(); //*3
	_stereo.aspect = 0.5;

	this.render = function ( scene, camera ) { //*4 Renders on 2 cameras
		scene.updateMatrixWorld();
		if ( camera.parent === null ) camera.updateMatrixWorld();
		_stereo.update( camera );

		var size = renderer.getSize();
		if ( renderer.autoClear ) renderer.clear();

		renderer.setScissorTest( true );

		renderer.setScissor( 0, 0, size.width / 2, size.height );
		renderer.setViewport( 0, 0, size.width / 2, size.height ); //*4
		renderer.render( scene, _stereo.cameraL ); //*4

		renderer.setScissor( size.width / 2, 0, size.width / 2, size.height );
		renderer.setViewport( size.width / 2, 0, size.width / 2, size.height ); //*4
		renderer.render( scene, _stereo.cameraR ); //*4

		renderer.setScissorTest( false );
	};
};

/*
 ***************************************************
 * The rest of this code is identical to lights.html
 ***************************************************
 */

// Global used by callbacks from HTML
var lights

function makeSceneGraph () {
	scene.add (new Scene())
	lights = new Lights()
}

/*
 * Same as previous example, except
 * this time we provide materials.
 */
class Scene extends THREE.Object3D {
    constructor () {
	super ()

	// First item = a box, rotated and translated
	var box = new THREE.Mesh (
		new THREE.BoxGeometry (1, 3, 1),
		new THREE.MeshPhongMaterial ({ color: "yellow" }))

	// Move it back from origin and to the right
	box.position.set (5, 0, -4)

	// Rotate it in X and Y
	box.rotation.set (45 * Math.PI/180, 30 * Math.PI/180, 0)

	// Plug it in to our scene
	this.add (box)

	// A sphere, in a different location
	var sphere = new THREE.Mesh (
		new THREE.SphereGeometry(1, 32, 32),
		new THREE.MeshPhongMaterial ({
			color: "red", shininess: 60 }))
	sphere.position.set (-5, 0, -3)
	this.add (sphere)

	// A pyramid, using our subroutine below
	var pyramid = new Pyramid (new THREE.MeshPhongMaterial ({
		color: "green", shininess: 60 }))
	pyramid.position.set (0, 0, -6)
	pyramid.rotation.set (0, 45 * Math.PI/180, 0)
	this.add (pyramid)
    }
}

/*
 * Same as previous example, except
 * this time, you pass us the material you want.
 */
class Pyramid extends THREE.Object3D {
    constructor (material) {
	super ()

	// Bottom Box, located slightly down
	// (relative to origin of the pyramid)
	var bot = new THREE.Mesh (
		new THREE.BoxGeometry (3, 3, 3),
		material)
	bot.position.set (0, -3/2, 0)
	this.add (bot)

	// Middle Box, slightly up
	var mid = new THREE.Mesh (
		new THREE.BoxGeometry (2, 2, 2),
		material)
	mid.position.set (0, 2/2, 0)
	this.add (mid)

	// Top box, further up
	var top = new THREE.Mesh (
		new THREE.BoxGeometry (1, 1, 1),
		material)
	top.position.set (0, 2 + 1/2, 0)
	this.add (top)
    }
}

/*
 * An object to hold the lights,
 * constructor just adds them to global var scene
 */
class Lights {
    constructor () {
	// Uses typical lighting setup, like portrait or TV studio...

	// Main (key) light, directional, 
	// from 45 deg. user's right, above, bright white
	this.mainLight = new THREE.DirectionalLight ("white", 1)
	this.mainLight.position.set (1, 0.5, 1)
	scene.add (this.mainLight)

	// Fill light, directional, from 45deg. user's left,
	// white, half as bright
	this.fillLight = new THREE.DirectionalLight ("white", 0.5)
	this.fillLight.position.set (-1, 0, 1 )
	scene.add (this.fillLight)

	// Ambient light, white, still less bright
	this.ambientLight = new THREE.AmbientLight (0x404040)
	scene.add (this.ambientLight);
    }

    // Callback from checkboxes
    pressed (state, light) {
	light.visible = state
	render ()
    }
}

</script>
</head>

<body>
Main light: <input type=checkbox checked="checked"
	onclick="lights.pressed(this.checked, lights.mainLight)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

Fill light: <input type=checkbox checked="checked"
	onclick="lights.pressed(this.checked, lights.fillLight)">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

Ambient light: <input type=checkbox checked="checked"
	onclick="lights.pressed(this.checked, lights.ambientLight)">

<br/>

<!-- Container for three.js -->
<div id="theContainer">&nbsp;</div>
</body>
</html>