Prechádzať zdrojové kódy

Adding different environment mapping types including equirectangular mapping and sphere mapping

Michael Bond 11 rokov pred
rodič
commit
484f364eb8

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 15976
build/three.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 373
build/three.min.js


BIN
examples/textures/environment/grace-new.jpg


BIN
examples/textures/environment/grace_probe.jpg


+ 299 - 0
examples/webgl_environment_maps.html

@@ -0,0 +1,299 @@
+
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - materials - cube reflection [cars]</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:#000;
+				color:#fff;
+				padding:0;
+				margin:0;
+				overflow:hidden;
+				font-family:georgia;
+				text-align:center;
+			}
+			h1 { }
+			a { color:skyblue; text-decoration:none }
+			canvas { pointer-events:none; z-index:10; position:relative; }
+
+			#d { position:absolute; width: 100%; text-align:center; margin:1em 0 -4.5em 0; z-index:1000; }
+
+			.bwrap { margin:0.5em 0 0 0 }
+			button { font-family:georgia; border:0; background:#000; color:#fff; padding:0.2em 0.5em; cursor:pointer; border-radius:3px; }
+			button:hover { background:#333 }
+			#buttons_cars button { color:#fa0 }
+
+			#car_info { text-align:center; }
+			#car_name { font-size:1em }
+			#car_author { font-size:1em }
+
+			.dg { z-index: 100 }
+
+			#oldie { background:rgb(50,0,0) !important; color:#fff !important; margin-top:7em!important }
+		</style>
+	</head>
+
+	<body>
+		
+		<script src="../build/three.js"></script>
+
+		<script src="js/loaders/BinaryLoader.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+		<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
+
+		<div id="info">
+
+
+			<a href="http://threejs.org" target="_blank">three.js</a> - webgl environment mapping example<br/>
+			Equirectangular Map by <a href="http://gl.ict.usc.edu/Data/HighResProbes/">University of Southern California</a><br/>
+			Spherical Map by <a href="http://www.pauldebevec.com/Probes/">Paul Debevec</a>
+
+		</div>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var STATS_ENABLED = false;
+
+			var container, stats;
+
+			var camera, scene, renderer;
+			var cameraCube, sceneCube;
+			var textureEquirec, textureCube, textureSphere;
+			var cubeMesh, sphereMesh;
+			var sphereMaterial;
+			var refract;
+
+			var m, mi;
+
+			var directionalLight, pointLight;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			// var loader = new THREE.BinaryLoader( true );
+			// document.body.appendChild( loader.statusDomElement );
+
+			init();
+			animate();
+
+			function init() {
+
+				params = {
+					stuff: 0.4,
+					useCube: function() {
+						cubeMesh.material = cubeMaterial;
+						sphereMaterial.envMap = textureCube;
+						sphereMaterial.needsUpdate = true;
+					},
+					useEquirect: function() {
+						cubeMesh.material = equirectMaterial;
+						sphereMaterial.envMap = textureEquirec;
+						sphereMaterial.needsUpdate = true;
+					},
+					useSphere: function() {
+						cubeMesh.material = equirectMaterial;
+						sphereMaterial.envMap = textureSphere;
+						sphereMaterial.needsUpdate = true;
+					},
+					toggleRefraction: function() {
+						refract = !refract;
+						if ( refract ) {
+							textureEquirec.mapping = THREE.EquirectangularRefractionMapping;
+							textureCube.mapping = THREE.CubeRefractionMapping;
+							textureSphere.mapping = THREE.SphericalRefractionMapping;
+						}
+						else {
+							textureEquirec.mapping = THREE.EquirectangularReflectionMapping;
+							textureCube.mapping = THREE.CubeReflectionMapping;
+							textureSphere.mapping = THREE.SphericalReflectionMapping;
+						}
+						sphereMaterial.needsUpdate = true;
+					}
+				};
+
+				container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				// CAMERAS
+
+				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
+				cameraCube = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
+
+				// SCENE
+
+				scene = new THREE.Scene();
+				sceneCube = new THREE.Scene();
+
+				// LIGHTS
+
+				var ambient = new THREE.AmbientLight( 0xffffff );
+				scene.add( ambient );
+
+				// directionalLight = new THREE.DirectionalLight( 0xffffff, 2 );
+				// directionalLight.position.set( 2, 1.2, 10 ).normalize();
+				// scene.add( directionalLight );
+
+				// directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
+				// directionalLight.position.set( -2, 1.2, -10 ).normalize();
+				// scene.add( directionalLight );
+
+				// pointLight = new THREE.PointLight( 0xffaa00, 2 );
+				// pointLight.position.set( 2000, 1200, 10000 );
+				// scene.add( pointLight );
+
+				// Skybox
+
+				var equirectShader = THREE.ShaderLib[ "equirect" ];
+				// shader.uniforms[ "tCube" ].value = textureCube;
+
+				var equirectMaterial = new THREE.ShaderMaterial( {
+					fragmentShader: equirectShader.fragmentShader,
+					vertexShader: equirectShader.vertexShader,
+					uniforms: equirectShader.uniforms,
+					depthWrite: false,
+					side: THREE.BackSide
+				} );
+
+				var cubeShader = THREE.ShaderLib[ "cube" ];
+				var cubeMaterial = new THREE.ShaderMaterial( {
+					fragmentShader: cubeShader.fragmentShader,
+					vertexShader: cubeShader.vertexShader,
+					uniforms: cubeShader.uniforms,
+					depthWrite: false,
+					side: THREE.BackSide
+				} );
+
+				cubeMesh = new THREE.Mesh( new THREE.BoxGeometry( 100, 100, 100 ), cubeMaterial );
+				sceneCube.add( cubeMesh );
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setFaceCulling( THREE.CullFaceNone );
+				renderer.autoClear = false;
+
+				container.appendChild( renderer.domElement );
+
+				if ( STATS_ENABLED ) {
+
+					stats = new Stats();
+					stats.domElement.style.position = 'absolute';
+					stats.domElement.style.top = '0px';
+					stats.domElement.style.zIndex = 100;
+					container.appendChild( stats.domElement );
+
+				}
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+				var r = "textures/cube/Bridge2/";
+				var urls = [ r + "posx.jpg", r + "negx.jpg",
+							 r + "posy.jpg", r + "negy.jpg",
+							 r + "posz.jpg", r + "negz.jpg" ];
+
+				textureCube = THREE.ImageUtils.loadTextureCube( urls );
+				textureCube.format = THREE.RGBFormat;
+				textureCube.mapping = THREE.CubeReflectionMapping;
+				cubeMaterial.uniforms[ "tCube" ].value = textureCube;
+
+				textureEquirec = THREE.ImageUtils.loadTexture( "textures/environment/grace-new.jpg" );
+				textureEquirec.format = THREE.RGBAFormat;
+				textureEquirec.mapping = THREE.EquirectangularReflectionMapping;
+				textureEquirec.magFilter = THREE.LinearFilter;
+				textureEquirec.minFilter = THREE.LinearFilter;
+				equirectMaterial.uniforms[ "tEquirect" ].value = textureEquirec;
+
+				textureSphere = THREE.ImageUtils.loadTexture( "textures/environment/grace_probe.jpg" );
+				textureSphere.mapping = THREE.SphericalReflectionMapping;
+
+				var gui = new dat.GUI();
+				// gui.domElement.style['z-index'] = 100;
+				gui.add( params, 'toggleRefraction' );
+				gui.add( params, 'useCube' );
+				gui.add( params, 'useEquirect' );
+				gui.add( params, 'useSphere' );
+				gui.open();
+
+				createScene();
+				
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				windowHalfX = window.innerWidth / 2;
+				windowHalfY = window.innerHeight / 2;
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				cameraCube.aspect = window.innerWidth / window.innerHeight;
+				cameraCube.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+
+
+			function createScene(  ) {
+				var geometry = new THREE.SphereGeometry( 400.0, 24, 24 );
+				sphereMaterial = new THREE.MeshLambertMaterial( { envMap: textureCube } );
+				sphereMesh = new THREE.Mesh( geometry, sphereMaterial );
+
+				// sphereMesh.scale.x = mesh.scale.y = mesh.scale.z = s;
+
+				scene.add( sphereMesh );
+
+				$('.dg.ac').css('z-index', 100);
+				
+			}
+
+			function onDocumentMouseMove(event) {
+
+				mouseY = ( event.clientY - window.innerHeight );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+
+			}
+
+			function render() {
+
+				var timer = -0.0002 * Date.now();
+
+				camera.position.x = 1000 * Math.cos( timer );
+				camera.position.y += ( - mouseY - camera.position.y ) * .05;
+				camera.position.z = 1000 * Math.sin( timer );
+
+				camera.lookAt( scene.position );
+				cameraCube.rotation.copy( camera.rotation );
+
+				renderer.render( sceneCube, cameraCube );
+				renderer.render( scene, camera );
+
+				if ( STATS_ENABLED ) stats.update();
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 8 - 5
src/Three.js

@@ -115,13 +115,16 @@ THREE.AddOperation = 2;
 
 // Mapping modes
 
-THREE.UVMapping = function () {};
+THREE.UVMapping = 300;
 
-THREE.CubeReflectionMapping = function () {};
-THREE.CubeRefractionMapping = function () {};
+THREE.CubeReflectionMapping = 301;
+THREE.CubeRefractionMapping = 302;
 
-THREE.SphericalReflectionMapping = function () {};
-THREE.SphericalRefractionMapping = function () {};
+THREE.SphericalReflectionMapping = 303;
+THREE.SphericalRefractionMapping = 304;
+
+THREE.EquirectangularReflectionMapping = 305;
+THREE.EquirectangularRefractionMapping = 306;
 
 // Wrapping modes
 

+ 4 - 1
src/renderers/WebGLRenderer.js

@@ -4716,7 +4716,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		uniforms.refractionRatio.value = material.refractionRatio;
 		uniforms.combine.value = material.combine;
-		uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
+		uniforms.useRefract.value = material.envMap && (
+			material.envMap.mapping === THREE.CubeRefractionMapping ||
+			material.envMap.mapping === THREE.SphericalRefractionMapping ||
+			material.envMap.mapping === THREE.EquirectangularRefractionMapping );
 
 	}
 

+ 20 - 8
src/renderers/shaders/ShaderChunk/envmap_fragment.glsl

@@ -28,33 +28,45 @@
 	#endif
 
 	#ifdef DOUBLE_SIDED
-
 		float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );
-		vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
-
 	#else
+		float flipNormal = 1.0;
+	#endif
+
+	#ifdef ENVMAP_TYPE_CUBE
+		vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
+
+	#elif defined( ENVMAP_TYPE_EQUIREC )
+		// #ifdef DOUBLE_SIDED
 
-		vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
+		// 	float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );
+		vec2 sampleUV;
+    sampleUV.y = clamp( flipNormal * reflectVec.y * 0.5 + 0.5, 0.0, 1.0);
+   	sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * 0.15915494309189533576888376337251 + 0.5; // reciprocal( 2 PI ) + 0.5
+   	vec4 envColor = texture2D( envMap, sampleUV );
+  #elif defined( ENVMAP_TYPE_SPHERE )
 
+  	vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));
+   	vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
 	#endif
 
 	#ifdef GAMMA_INPUT
 
-		cubeColor.xyz *= cubeColor.xyz;
+		envColor.xyz *= envColor.xyz;
 
 	#endif
 
 	if ( combine == 1 ) {
 
-		gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );
+		gl_FragColor.xyz = mix( gl_FragColor.xyz, envColor.xyz, specularStrength * reflectivity );
 
 	} else if ( combine == 2 ) {
 
-		gl_FragColor.xyz += cubeColor.xyz * specularStrength * reflectivity;
+		gl_FragColor.xyz += envColor.xyz * specularStrength * reflectivity;
 
 	} else {
 
-		gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );
+		gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * envColor.xyz, specularStrength * reflectivity );
 
 	}
 

+ 5 - 1
src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl

@@ -1,7 +1,11 @@
 #ifdef USE_ENVMAP
 
 	uniform float reflectivity;
-	uniform samplerCube envMap;
+	#ifdef ENVMAP_TYPE_CUBE
+		uniform samplerCube envMap;
+	#else
+		uniform sampler2D envMap;
+	#endif
 	uniform float flipEnvMap;
 	uniform int combine;
 

+ 54 - 0
src/renderers/shaders/ShaderLib.js

@@ -1254,6 +1254,60 @@ THREE.ShaderLib = {
 
 	},
 
+	/* -------------------------------------------------------------------------
+	//	Cube map shader
+	 ------------------------------------------------------------------------- */
+
+	'equirect': {
+
+		uniforms: { "tEquirect": { type: "t", value: null },
+					"tFlip": { type: "f", value: - 1 } },
+
+		vertexShader: [
+
+			"varying vec3 vWorldPosition;",
+
+			THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
+
+			"void main() {",
+
+			"	vec4 worldPosition = modelMatrix * vec4( position, 1.0 );",
+			"	vWorldPosition = worldPosition.xyz;",
+
+			"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
+				THREE.ShaderChunk[ "logdepthbuf_vertex" ],
+
+			"}"
+
+		].join("\n"),
+
+		fragmentShader: [
+
+			"uniform sampler2D tEquirect;",
+			"uniform float tFlip;",
+
+			"varying vec3 vWorldPosition;",
+
+			THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
+
+			"void main() {",
+
+				// "	gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",
+				"vec3 direction = normalize( vWorldPosition );",
+				"vec2 sampleUV;",
+		    "sampleUV.y = clamp( tFlip * direction.y * -0.5 + 0.5, 0.0, 1.0);",
+		   	"sampleUV.x = atan( direction.z, direction.x ) * 0.15915494309189533576888376337251 + 0.5;", // reciprocal( 2 PI ) + 0.5
+		   	"gl_FragColor = texture2D( tEquirect, sampleUV );",
+
+				THREE.ShaderChunk[ "logdepthbuf_fragment" ],
+
+			"}"
+
+		].join("\n")
+
+	},
+
 	/* Depth encoding into RGBA texture
 	 *
 	 * based on SpiderGL shadow map example

+ 19 - 0
src/renderers/webgl/WebGLProgram.js

@@ -84,6 +84,24 @@ THREE.WebGLProgram = ( function () {
 
 		}
 
+		var envMapTypeDefine = null;
+		if ( parameters.envMap ) {
+			switch ( material.envMap.mapping ) {
+				case THREE.CubeReflectionMapping:
+				case THREE.CubeRefractionMapping:
+					envMapTypeDefine = "ENVMAP_TYPE_CUBE";
+					break;
+				case THREE.SphericalReflectionMapping:
+				case THREE.SphericalRefractionMapping:
+					envMapTypeDefine = "ENVMAP_TYPE_SPHERE";
+					break;
+				case THREE.EquirectangularReflectionMapping:
+				case THREE.EquirectangularRefractionMapping:
+					envMapTypeDefine = "ENVMAP_TYPE_EQUIREC";
+					break;
+			}
+		}
+
 		// console.log( "building new program " );
 
 		//
@@ -233,6 +251,7 @@ THREE.WebGLProgram = ( function () {
 
 				parameters.map ? "#define USE_MAP" : "",
 				parameters.envMap ? "#define USE_ENVMAP" : "",
+				envMapTypeDefine ? "#define " + envMapTypeDefine : "",
 				parameters.lightMap ? "#define USE_LIGHTMAP" : "",
 				parameters.bumpMap ? "#define USE_BUMPMAP" : "",
 				parameters.normalMap ? "#define USE_NORMALMAP" : "",

+ 1 - 0
src/textures/CubeTexture.js

@@ -4,6 +4,7 @@
 
 THREE.CubeTexture = function ( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
 
+  mapping = mapping !== undefined ? mapping : THREE.CubeReflectionMapping;
 	THREE.Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
 
 	this.images = images;

+ 1 - 1
src/textures/Texture.js

@@ -42,7 +42,7 @@ THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, f
 };
 
 THREE.Texture.DEFAULT_IMAGE = undefined;
-THREE.Texture.DEFAULT_MAPPING = new THREE.UVMapping();
+THREE.Texture.DEFAULT_MAPPING = THREE.UVMapping;
 
 THREE.Texture.prototype = {
 

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov