Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	| /** | |
| * @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 ) { | |
| options = 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 ); | |
| var scene = new THREE.Scene(); | |
| var boxMesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 1, 1, 1 ), getShader() ); | |
| boxMesh.material.side = THREE.BackSide; | |
| scene.add( boxMesh ); | |
| var EquirectangularToCubeGenerator = function ( sourceTexture, options ) { | |
| options = options || {}; | |
| this.sourceTexture = sourceTexture; | |
| this.resolution = options.resolution || 512; | |
| this.views = [ | |
| { t: [ 1, 0, 0 ], u: [ 0, - 1, 0 ] }, | |
| { t: [ - 1, 0, 0 ], u: [ 0, - 1, 0 ] }, | |
| { t: [ 0, 1, 0 ], u: [ 0, 0, 1 ] }, | |
| { t: [ 0, - 1, 0 ], u: [ 0, 0, - 1 ] }, | |
| { t: [ 0, 0, 1 ], u: [ 0, - 1, 0 ] }, | |
| { t: [ 0, 0, - 1 ], u: [ 0, - 1, 0 ] }, | |
| ]; | |
| var params = { | |
| format: options.format || this.sourceTexture.format, | |
| magFilter: this.sourceTexture.magFilter, | |
| minFilter: this.sourceTexture.minFilter, | |
| type: options.type || this.sourceTexture.type, | |
| generateMipmaps: this.sourceTexture.generateMipmaps, | |
| anisotropy: this.sourceTexture.anisotropy, | |
| encoding: this.sourceTexture.encoding | |
| }; | |
| this.renderTarget = new THREE.WebGLRenderTargetCube( this.resolution, this.resolution, params ); | |
| }; | |
| EquirectangularToCubeGenerator.prototype = { | |
| constructor: EquirectangularToCubeGenerator, | |
| update: function ( renderer ) { | |
| var currentRenderTarget = renderer.getRenderTarget(); | |
| boxMesh.material.uniforms.equirectangularMap.value = this.sourceTexture; | |
| for ( var i = 0; i < 6; i ++ ) { | |
| var v = this.views[ i ]; | |
| camera.position.set( 0, 0, 0 ); | |
| camera.up.set( v.u[ 0 ], v.u[ 1 ], v.u[ 2 ] ); | |
| camera.lookAt( v.t[ 0 ], v.t[ 1 ], v.t[ 2 ] ); | |
| renderer.setRenderTarget( this.renderTarget, i ); | |
| renderer.clear(); | |
| renderer.render( scene, camera ); | |
| } | |
| renderer.setRenderTarget( currentRenderTarget ); | |
| return this.renderTarget.texture; | |
| }, | |
| dispose: function () { | |
| this.renderTarget.dispose(); | |
| } | |
| }; | |
| function getShader() { | |
| var shaderMaterial = new THREE.ShaderMaterial( { | |
| uniforms: { | |
| "equirectangularMap": { value: null }, | |
| }, | |
| vertexShader: | |
| "varying vec3 localPosition;\n\ | |
| \n\ | |
| void main() {\n\ | |
| localPosition = position;\n\ | |
| gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\ | |
| }", | |
| fragmentShader: | |
| "#include <common>\n\ | |
| varying vec3 localPosition;\n\ | |
| uniform sampler2D equirectangularMap;\n\ | |
| \n\ | |
| vec2 EquirectangularSampleUV(vec3 v) {\n\ | |
| vec2 uv = vec2(atan(v.z, v.x), asin(v.y));\n\ | |
| uv *= vec2(0.1591, 0.3183); // inverse atan\n\ | |
| uv += 0.5;\n\ | |
| return uv;\n\ | |
| }\n\ | |
| \n\ | |
| void main() {\n\ | |
| vec2 uv = EquirectangularSampleUV(normalize(localPosition));\n\ | |
| gl_FragColor = texture2D(equirectangularMap, uv);\n\ | |
| }", | |
| blending: THREE.NoBlending | |
| } ); | |
| shaderMaterial.type = 'EquirectangularToCubeGenerator'; | |
| return shaderMaterial; | |
| } | |
| return EquirectangularToCubeGenerator; | |
| } )(); | |