Quellcode durchsuchen

Merge pull request #15331 from WestLangley/dev-cubemap_gen

Add THREE.CubemapGenerator
Mr.doob vor 6 Jahren
Ursprung
Commit
36e2f63a3d

+ 108 - 0
examples/js/loaders/EquirectangularToCubeGenerator.js

@@ -1,7 +1,115 @@
 /**
 * @author Richard M. / https://github.com/richardmonette
+* @author WestLangley / http://github.com/WestLangley
 */
 
+THREE.CubemapGenerator = function ( renderer ) {
+
+	this.renderer = renderer;
+
+};
+
+THREE.CubemapGenerator.prototype.fromEquirectangular = function ( texture, options ) {
+
+	var scene = new THREE.Scene();
+
+	var shader = {
+
+		uniforms: {
+			tEquirect: { value: null },
+		},
+
+		vertexShader:
+
+			`
+			varying vec3 vWorldDirection;
+
+			//include <common>
+			vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
+
+				return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
+
+			}
+
+			void main() {
+
+				vWorldDirection = transformDirection( position, modelMatrix );
+
+				#include <begin_vertex>
+				#include <project_vertex>
+
+			}
+			`,
+
+		fragmentShader:
+
+			`
+			uniform sampler2D tEquirect;
+
+			varying vec3 vWorldDirection;
+
+			//include <common>
+			#define RECIPROCAL_PI 0.31830988618
+			#define RECIPROCAL_PI2 0.15915494
+
+			void main() {
+
+				vec3 direction = normalize( vWorldDirection );
+
+				vec2 sampleUV;
+
+				sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
+
+				sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;
+
+				gl_FragColor = texture2D( tEquirect, sampleUV );
+
+			}
+			`
+	};
+
+	var material = new THREE.ShaderMaterial( {
+
+		type: 'CubemapFromEquirect',
+
+		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
+		vertexShader: shader.vertexShader,
+		fragmentShader: shader.fragmentShader,
+		side: THREE.BackSide,
+		blending: THREE.NoBlending
+
+	} );
+
+	material.uniforms.tEquirect.value = texture;
+
+	var mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 5, 5, 5 ), material );
+
+	scene.add( mesh );
+
+	var resolution = options.resolution || 512;
+
+	var params = {
+		type: texture.type,
+		format: texture.format,
+		encoding: texture.encoding,
+		generateMipmaps: ( options.generateMipmaps !== undefined ) ?  options.generateMipmaps : texture.generateMipmaps,
+		minFilter: ( options.minFilter !== undefined ) ?  options.minFilter : texture.minFilter,
+		magFilter: ( options.magFilter !== undefined ) ?  options.magFilter : texture.magFilter
+	};
+
+	var camera = new THREE.CubeCamera( 1, 10, resolution, params );
+
+	camera.update( this.renderer, scene );
+
+	mesh.geometry.dispose();
+	mesh.material.dispose();
+
+	return camera.renderTarget;
+
+};
+
+//
+
 THREE.EquirectangularToCubeGenerator = ( function () {
 
 	var camera = new THREE.PerspectiveCamera( 90, 1, 0.1, 10 );

+ 18 - 10
examples/webgl_materials_cubemap_dynamic.html

@@ -32,6 +32,7 @@
 		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js webgl</a> - materials - dynamic cube reflection<br/>Photo by <a href="http://www.flickr.com/photos/jonragnarsson/2294472375/" target="_blank" rel="noopener">J&oacute;n Ragnarsson</a>.</div>
 
 		<script src="../build/three.js"></script>
+		<script src="js/loaders/EquirectangularToCubeGenerator.js"></script>
 
 		<script>
 
@@ -58,17 +59,27 @@
 
 			function init( texture ) {
 
-				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 				scene = new THREE.Scene();
 
-				backgroundMesh = new THREE.Mesh( new THREE.SphereBufferGeometry( 500, 32, 16 ), new THREE.MeshBasicMaterial( { map: texture } ) );
-				backgroundMesh.geometry.scale( - 1, 1, 1 );
-				scene.add( backgroundMesh );
+				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
 
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
+				// background
+
+				var options = {
+					resolution: 1024,
+
+					generateMipmaps: true,
+					minFilter: THREE.LinearMipMapLinearFilter,
+					magFilter: THREE.LinearFilter
+				};
+
+				scene.background = new THREE.CubemapGenerator( renderer ).fromEquirectangular( texture, options );
+
+				//
 
 				cubeCamera1 = new THREE.CubeCamera( 1, 1000, 256 );
 				cubeCamera1.renderTarget.texture.generateMipmaps = true;
@@ -198,13 +209,11 @@
 				if ( count % 2 === 0 ) {
 
 					material.envMap = cubeCamera1.renderTarget.texture;
-					backgroundMesh.position.copy( cubeCamera2.position );
 					cubeCamera2.update( renderer, scene );
 
 				} else {
 
 					material.envMap = cubeCamera2.renderTarget.texture;
-					backgroundMesh.position.copy( cubeCamera1.position );
 					cubeCamera1.update( renderer, scene );
 
 				}
@@ -213,7 +222,6 @@
 
 				sphere.visible = true;
 
-				backgroundMesh.position.copy( camera.position );
 				renderer.render( scene, camera );
 
 			}