Browse Source

Added CardboardEffect example. See #7732.

Mr.doob 9 năm trước cách đây
mục cha
commit
ed4f5f1379

+ 1 - 0
examples/files.js

@@ -8,6 +8,7 @@ var files = {
 		"webgl_camera_logarithmicdepthbuffer",
 		"webgl_camera_logarithmicdepthbuffer",
 		"webgl_decals",
 		"webgl_decals",
 		"webgl_effects_anaglyph",
 		"webgl_effects_anaglyph",
+		"webgl_effects_cardboard",
 		"webgl_effects_parallaxbarrier",
 		"webgl_effects_parallaxbarrier",
 		"webgl_effects_peppersghost",
 		"webgl_effects_peppersghost",
 		"webgl_effects_stereo",
 		"webgl_effects_stereo",

+ 109 - 0
examples/js/effects/CardboardEffect.js

@@ -0,0 +1,109 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.CardboardEffect = function ( renderer ) {
+
+	var _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
+
+	var _scene = new THREE.Scene();
+
+	var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
+
+	var _renderTarget = new THREE.WebGLRenderTarget( 512, 512, _params );
+	_renderTarget.scissorTest = true;
+
+	// https://github.com/borismus/webvr-boilerplate/blob/master/src/distortion/barrel-distortion-fragment.js
+
+	var _material = new THREE.ShaderMaterial( {
+
+		uniforms: {
+			'texture': { type: 't', value: _renderTarget },
+			'distortion': { type: 'v2', value: new THREE.Vector2( 0.441, 0.156 ) },
+			'leftCenter': { type: 'v2', value: new THREE.Vector2( 0.5, 0.5 ) },
+			'rightCenter': { type: 'v2', value: new THREE.Vector2( 0.5, 0.5 ) },
+			'background': { type: 'v4', value: new THREE.Vector4( 0.0, 0.0, 0.0, 1.0 ) },
+		},
+
+		vertexShader: [
+			'varying vec2 vUV;',
+
+			'void main() {',
+				'vUV = uv;',
+				'gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
+			'}'
+
+		].join( '\n' ),
+
+		fragmentShader: [
+			'uniform sampler2D texture;',
+
+			'uniform vec2 distortion;',
+			'uniform vec2 leftCenter;',
+			'uniform vec2 rightCenter;',
+			'uniform vec4 background;',
+
+			'varying vec2 vUV;',
+
+			'float poly(float val) {',
+				'return 1.0 + (distortion.x + distortion.y * val) * val;',
+			'}',
+
+			'vec2 barrel(vec2 v, vec2 center) {',
+				'vec2 w = v - center;',
+				'return poly(dot(w, w)) * w + center;',
+			'}',
+			'void main() {',
+				'bool isLeft = (vUV.x < 0.5);',
+				'float offset = isLeft ? 0.0 : 0.5;',
+				'vec2 a = barrel(vec2((vUV.x - offset) / 0.5, vUV.y), isLeft ? leftCenter : rightCenter);',
+				'if (a.x < 0.0 || a.x > 1.0 || a.y < 0.0 || a.y > 1.0) {',
+					'gl_FragColor = background;',
+				'} else {',
+					'gl_FragColor = texture2D(texture, vec2(a.x * 0.5 + offset, a.y));',
+				'}',
+			'}'
+		].join( '\n' )
+
+	} );
+
+	var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), _material );
+	_scene.add( mesh );
+
+	this.setSize = function ( width, height ) {
+
+		_renderTarget.setSize( width, height );
+
+		renderer.setSize( width, height );
+
+	};
+
+	this.render = function ( scene, camera ) {
+
+		if ( camera instanceof THREE.StereoCamera === false ) {
+
+			console.error( 'THREE.StereoCamera.render(): camera should now be an insteance of THREE.StereoCamera.' );
+			return;
+
+		}
+
+		scene.updateMatrixWorld();
+
+		if ( camera.parent === null ) camera.updateMatrixWorld();
+
+		var width = _renderTarget.width / 2;
+		var height = _renderTarget.height;
+
+		_renderTarget.scissor.set( 0, 0, width, height );
+		_renderTarget.viewport.set( 0, 0, width, height );
+		renderer.render( scene, camera.cameraL, _renderTarget );
+
+		_renderTarget.scissor.set( width, 0, width, height );
+		_renderTarget.viewport.set( width, 0, width, height );
+		renderer.render( scene, camera.cameraR, _renderTarget );
+
+		renderer.render( _scene, _camera );
+
+	};
+
+};

+ 110 - 0
examples/webgl_effects_cardboard.html

@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - effects - cardboard</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 {
+				margin: 0px;
+				overflow: hidden;
+			}
+		</style>
+	</head>
+	<body>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/effects/CardboardEffect.js"></script>
+		<script>
+
+			var camera, scene, renderer;
+			var effect;
+
+			init();
+			animate();
+
+			function init() {
+
+				camera = new THREE.StereoCamera( 50, window.innerWidth / window.innerHeight / 2, 1, 100 );
+				camera.position.set( 3, 2, 3 );
+				camera.lookAt( new THREE.Vector3() );
+				camera.focalLength = camera.position.distanceTo( new THREE.Vector3() );
+
+				scene = new THREE.Scene();
+
+				var geometry = new THREE.CubeGeometry( 1, 1, 1 );
+				var material = new THREE.MeshStandardMaterial();
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.position.y = 0.5;
+				mesh.castShadow = true;
+				mesh.receiveShadow = true;
+				scene.add( mesh );
+
+				var geometry = new THREE.PlaneGeometry( 4, 4 );
+				geometry.rotateX( - Math.PI / 2 );
+				var material = new THREE.MeshStandardMaterial();
+				var mesh = new THREE.Mesh( geometry, material );
+				mesh.castShadow = true;
+				mesh.receiveShadow = true;
+				scene.add( mesh );
+
+				var light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( -1, 1.5, 0.5 );
+				light.castShadow = true;
+				scene.add( light );
+
+				var light = new THREE.DirectionalLight( 0xff0000, 1.5 );
+				light.position.set( 1, 1.5, -0.5 );
+				light.castShadow = true;
+				scene.add( light );
+
+				//
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setClearColor( 0x101010 );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.shadowMap.enabled = true;
+				document.body.appendChild( renderer.domElement );
+
+				//
+
+				effect = new THREE.CardboardEffect( renderer );
+				effect.setSize( window.innerWidth, window.innerHeight );
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight / 2;
+				camera.updateProjectionMatrix();
+
+				effect.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+				render();
+
+			}
+
+			function render() {
+
+				var time = performance.now() * 0.0005;
+				camera.position.x = Math.cos( time ) * 4;
+				camera.position.z = Math.sin( time ) * 4;
+				camera.lookAt( new THREE.Vector3() );
+
+				effect.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>