2
0
Эх сурвалжийг харах

Merge remote-tracking branch 'origin/dev' into dev

Mr.doob 10 жил өмнө
parent
commit
630b294d92

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


BIN
examples/textures/environment/grace_probe.jpg


+ 307 - 0
examples/webgl_environment_maps.html

@@ -0,0 +1,307 @@
+
+<!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/controls/OrbitControls.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>
+		
+		<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 controls, 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 );
+				camera.position.set( 550, 0, 550 );
+				cameraCube = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
+
+				controls = new THREE.OrbitControls( camera );
+				controls.minDistance = 500;
+				controls.maxDistance = 2500;
+
+
+				// 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.LinearMipMapLinearFilter;
+				// textureEquirec.anisotropy = 8.0;
+				// textureEquirec.generateMipmaps = true;
+				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 );
+				
+			}
+
+			function onDocumentMouseMove(event) {
+
+				mouseY = ( event.clientY - window.innerHeight );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+
+				controls.update();
+
+			}
+
+			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

@@ -4784,7 +4784,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 );
 
 	}
 

+ 18 - 9
src/renderers/shaders/ShaderChunk/envmap_fragment.glsl

@@ -28,33 +28,42 @@
 	#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
 
-		vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
-
+	#ifdef ENVMAP_TYPE_CUBE
+		vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
+
+	#elif defined( ENVMAP_TYPE_EQUIREC )
+		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 = {