Pārlūkot izejas kodu

New webgl example: postprocessing crossfade between cameras

fernandojsg 11 gadi atpakaļ
vecāks
revīzija
9c4399aec0

+ 1 - 0
examples/index.html

@@ -235,6 +235,7 @@
 				"webgl_postprocessing_dof",
 				"webgl_postprocessing_dof2",
 				"webgl_postprocessing_godrays",
+				"webgl_postprocessing_crossfade",
 				"webgl_rtt",
 				"webgl_sandbox",
 				"webgl_shader",

+ 39 - 0
examples/js/crossfade/gui.js

@@ -0,0 +1,39 @@
+var transitionParams = {
+	"useTexture": true,
+	"transition": 0.5,
+	"transitionSpeed": 2.5,
+	"texture": 5,
+	"loopTexture": true,
+	"animateTransition": true,
+	"textureThreshold": 0.3
+};
+
+function initGUI() {
+	
+	var gui = new dat.GUI();
+
+	gui.add(transitionParams, "useTexture").onChange(function(value) {
+		
+		transition.useTexture(value);
+		
+	});
+	
+	gui.add(transitionParams, 'loopTexture');
+	
+	gui.add(transitionParams, 'texture', { Perlin: 0, Squares: 1, Cells: 2, Distort: 3, Gradient: 4, Radial: 5 } ).onChange(function(value) {
+		
+		transition.setTexture(value);
+		
+	}).listen();
+		
+	gui.add(transitionParams, "textureThreshold", 0, 1, 0.01 ).onChange(function(value) {
+		
+		transition.setTextureThreshold(value);
+		
+	});
+
+	gui.add(transitionParams, "animateTransition");
+	gui.add(transitionParams, "transition", 0, 1, 0.01 ).listen();
+	gui.add(transitionParams, "transitionSpeed", 0.5, 5, 0.01 );
+
+}

+ 107 - 0
examples/js/crossfade/scenes.js

@@ -0,0 +1,107 @@
+function generateGeometry(objectType, numObjects) {
+
+	var geometry = new THREE.Geometry();
+	
+	function applyVertexColors( g, c ) {
+
+		g.faces.forEach( function( f ) {
+
+			var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
+
+			for( var j = 0; j < n; j ++ ) {
+
+				f.vertexColors[ j ] = c;
+
+			}
+
+		} );
+
+	}
+
+	for ( var i = 0; i < numObjects; i ++ ) {
+	
+		var position = new THREE.Vector3();
+
+		position.x = Math.random() * 10000 - 5000;
+		position.y = Math.random() * 6000 - 3000;
+		position.z = Math.random() * 8000 - 4000;
+
+		var rotation = new THREE.Euler();
+
+		rotation.x = Math.random() * 2 * Math.PI;
+		rotation.y = Math.random() * 2 * Math.PI;
+		rotation.z = Math.random() * 2 * Math.PI;
+
+		var scale = new THREE.Vector3();
+
+		var geom;
+
+		scale.x = Math.random() * 200 + 100;
+
+		if ( objectType == "cube" )
+		{
+			geom = new THREE.CubeGeometry( 1, 1, 1 );
+			scale.y = Math.random() * 200 + 100;
+			scale.z = Math.random() * 200 + 100;
+		}
+		else if ( objectType == "sphere" )
+		{
+			geom = new THREE.IcosahedronGeometry( 1, 1 )
+			scale.y = scale.z = scale.x;
+		}
+
+		// give the geom's vertices a random color, to be displayed
+		var color = new THREE.Color( Math.random() * 0xffffff );
+		applyVertexColors( geom, color );
+
+		var cube = new THREE.Mesh( geom );
+		cube.position.copy( position );
+		cube.rotation.copy( rotation );
+		cube.scale.copy( scale );
+
+		THREE.GeometryUtils.merge( geometry, cube );
+
+	}
+
+	return geometry;
+
+}
+
+function Scene ( type, numObjects, cameraZ, fov, rotationSpeed, clearColor ) {
+	
+	this.clearColor = clearColor;
+	
+	this.camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 10000 );
+	this.camera.position.z = cameraZ;
+	
+	// Setup scene
+	this.scene = new THREE.Scene();
+	this.scene.add( new THREE.AmbientLight( 0x555555 ) );
+
+	var light = new THREE.SpotLight( 0xffffff, 1.5 );
+	light.position.set( 0, 500, 2000 );
+	this.scene.add( light );
+
+	this.rotationSpeed = rotationSpeed;
+	defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors	} );
+	this.mesh = new THREE.Mesh( generateGeometry( type, numObjects ), defaultMaterial );
+	this.scene.add( this.mesh );
+
+	renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
+	this.fbo = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, renderTargetParameters );
+	
+	this.render = function( delta, rtt ) {
+		
+		this.mesh.rotation.x += delta*this.rotationSpeed.x;
+		this.mesh.rotation.y += delta*this.rotationSpeed.y;
+		this.mesh.rotation.z += delta*this.rotationSpeed.z;
+		
+		renderer.setClearColor( this.clearColor, 1 );
+		
+		if (rtt)
+			renderer.render( this.scene, this.camera, this.fbo, true );
+		else
+			renderer.render( this.scene, this.camera );
+		
+	};
+}

+ 165 - 0
examples/js/crossfade/transition.js

@@ -0,0 +1,165 @@
+function Transition ( sceneA, sceneB ) {
+
+	this.scene = new THREE.Scene();
+	
+	this.cameraOrtho = new THREE.OrthographicCamera(window.innerWidth / -2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / -2, -10, 10);
+
+	this.textures = [];
+	for (var i=0;i<6;i++)
+		this.textures[i]=new THREE.ImageUtils.loadTexture('textures/transition/transition'+(i+1)+'.png');
+				
+	this.quadmaterial = new THREE.ShaderMaterial({
+
+		uniforms: {
+
+			tDiffuse1: {
+				type: "t",
+				value: null
+			},
+			tDiffuse2: {
+				type: "t",
+				value: null
+			},
+			mixRatio: {
+				type: "f",
+				value: 0.0
+			},
+			threshold: {
+				type: "f",
+				value: 0.1
+			},
+			useTexture: {
+				type: "i",
+				value: 1,
+			},
+			tMixTexture: {
+				type: "t",
+				value: this.textures[0]
+			}
+		},
+		vertexShader: [
+
+			"varying vec2 vUv;",
+
+			"void main() {",
+
+			"vUv = vec2( uv.x, uv.y );",
+			"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
+			"}"
+
+		].join("\n"),
+		fragmentShader: [
+
+			"uniform float mixRatio;",
+
+			"uniform sampler2D tDiffuse1;",
+			"uniform sampler2D tDiffuse2;",
+			"uniform sampler2D tMixTexture;",
+			
+			"uniform int useTexture;",
+			"uniform float threshold;",
+
+			"varying vec2 vUv;",
+
+			"void main() {",
+
+			"vec4 texel1 = texture2D( tDiffuse1, vUv );",
+			"vec4 texel2 = texture2D( tDiffuse2, vUv );",
+			
+			"if (useTexture==1) {",
+				
+				"vec4 transitionTexel = texture2D( tMixTexture, vUv );",
+				"float r = mixRatio * (1.0 + threshold * 2.0) - threshold;",
+				"float mixf=clamp((transitionTexel.r - r)*(1.0/threshold), 0.0, 1.0);",
+				
+				"gl_FragColor = mix( texel1, texel2, mixf );",
+			"} else {",
+				
+				"gl_FragColor = mix( texel2, texel1, mixRatio );",
+				
+			"}",
+		"}"
+
+		].join("\n")
+
+	});		
+
+	quadgeometry = new THREE.PlaneGeometry(window.innerWidth, window.innerHeight);
+	
+	this.quad = new THREE.Mesh(quadgeometry, this.quadmaterial);
+	this.scene.add(this.quad);
+
+	// Link both scenes and their FBOs
+	this.sceneA = sceneA;
+	this.sceneB = sceneB;
+
+	this.quadmaterial.uniforms.tDiffuse1.value = sceneA.fbo;
+	this.quadmaterial.uniforms.tDiffuse2.value = sceneB.fbo;
+
+	this.needChange = false;
+	
+	this.setTextureThreshold = function ( value ) {
+	
+		this.quadmaterial.uniforms.threshold.value=value;
+
+	}
+	
+	this.useTexture = function ( value ) {
+	
+		this.quadmaterial.uniforms.useTexture.value = value?1:0;
+
+	}
+	
+	this.setTexture = function ( i ) {
+		
+		this.quadmaterial.uniforms.tMixTexture.value = this.textures[i];
+		
+	}
+	
+	this.render = function( delta ) {
+		
+		// Transition animation
+		if (transitionParams.animateTransition)
+		{
+			var t=(1+Math.sin(transitionParams.transitionSpeed*clock.getElapsedTime()/Math.PI))/2;
+			transitionParams.transition=THREE.Math.smoothstep(t,0.3,0.7);
+			
+			// Change the current alpha texture after each transition
+			if (transitionParams.loopTexture && (transitionParams.transition==0 || transitionParams.transition==1))
+			{
+				if (this.needChange)
+				{
+					transitionParams.texture=(transitionParams.texture+1)%this.textures.length;
+					this.quadmaterial.uniforms.tMixTexture.value = this.textures[transitionParams.texture];
+					this.needChange=false;
+				}
+			}	
+			else
+				this.needChange=true;
+				
+		}
+		
+		this.quadmaterial.uniforms.mixRatio.value = transitionParams.transition;
+
+		// Prevent render both scenes when it's not necessary
+		if (transitionParams.transition==0) {
+			
+			this.sceneB.render( delta, false );
+		
+		} else if (transitionParams.transition==1) {
+		
+			this.sceneA.render( delta, false );
+			
+		} else {
+			
+			// When 0<transition<1 render transition between two scenes
+			
+			this.sceneA.render( delta, true );
+			this.sceneB.render( delta, true );
+			renderer.render( this.scene, this.cameraOrtho, null, true );
+
+		}
+
+	}
+}

BIN
examples/textures/transition/transition1.png


BIN
examples/textures/transition/transition2.png


BIN
examples/textures/transition/transition3.png


BIN
examples/textures/transition/transition4.png


BIN
examples/textures/transition/transition5.png


BIN
examples/textures/transition/transition6.png


+ 109 - 0
examples/webgl_postprocessing_crossfade.html

@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - interactive cubes</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 {
+				font-family: Monospace;
+				background-color: #f0f0f0;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			.info {
+				position: absolute;
+				background-color: black;
+				opacity: 0.8;
+				color: white;
+				text-align: center;
+				top: 0px;
+				width: 100%;
+			}
+
+			.info a {
+				color: #00ffff;
+			}
+		</style>
+	</head>
+	<body>
+
+		<div class="info">
+			<a href="http://threejs.org" target="_blank">three.js</a> webgl scene transitions - by <a href="https://twitter.com/fernandojsg">fernandojsg</a> - <a href="https://github.com/kile/three.js-demos">github</a>
+		</div>
+
+		<div id="container"></div>
+
+		<script src="../build/three.min.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+		<script src="js/crossfade/scenes.js"></script>
+		<script src="js/crossfade/gui.js"></script>
+		<script src="js/crossfade/transition.js"></script>
+		
+		<script>
+
+			var container, stats;
+			var renderer;
+			var transition;
+			
+			var clock = new THREE.Clock();
+
+			init();
+			animate();
+			
+			function init() {
+
+				initGUI();
+				
+				container = document.getElementById( "container" );
+
+				renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false } );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.sortObjects = false;
+
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+
+				sceneA = new Scene( "cube", 5000, 1200, 120, new THREE.Vector3(0,-0.4,0), 0xffffff );
+				sceneB = new Scene( "sphere", 500, 2000, 50, new THREE.Vector3(0,0.2,0.1), 0x000000 );
+				
+				transition = new Transition(sceneA,sceneB);
+				
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+			
+			function render() {
+				
+				transition.render( clock.getDelta() );
+				
+			}
+
+		</script>
+
+	</body>
+	
+	<script type="text/javascript">
+	var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+	document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+	</script>
+	<script type="text/javascript">
+	var pageTracker = _gat._getTracker("UA-1752824-2");
+	pageTracker._trackPageview();
+	</script>
+	
+</html>
+