Browse Source

add read float buffer example

the example reads the background texture point under the mouse and
displays the value on the window.
Nicolas Raynaud 10 năm trước cách đây
mục cha
commit
e0209c066d
2 tập tin đã thay đổi với 302 bổ sung8 xóa
  1. 9 8
      build/three.min.js
  2. 293 0
      examples/webgl_read_float_buffer.html

+ 9 - 8
build/three.min.js

@@ -604,14 +604,15 @@ c.__webglTexture)};this.setRenderTarget=function(a){var b=a instanceof THREE.Web
 [];J.bindTexture(r.TEXTURE_CUBE_MAP,d.__webglTexture);w(r.TEXTURE_CUBE_MAP,a.texture,e);for(d=0;6>d;d++)c.__webglFramebuffer[d]=r.createFramebuffer(),c.__webglRenderbuffer[d]=r.createRenderbuffer(),J.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+d,0,g,a.width,a.height,0,g,h,null),D(c.__webglFramebuffer[d],a,r.TEXTURE_CUBE_MAP_POSITIVE_X+d),G(c.__webglRenderbuffer[d],a);a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_CUBE_MAP)}else c.__webglFramebuffer=r.createFramebuffer(),c.__webglRenderbuffer=
 a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:r.createRenderbuffer(),J.bindTexture(r.TEXTURE_2D,d.__webglTexture),w(r.TEXTURE_2D,a.texture,e),J.texImage2D(r.TEXTURE_2D,0,g,a.width,a.height,0,g,h,null),D(c.__webglFramebuffer,a,r.TEXTURE_2D),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_ATTACHMENT,r.RENDERBUFFER,c.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_STENCIL_ATTACHMENT,r.RENDERBUFFER,
 c.__webglRenderbuffer):G(c.__webglRenderbuffer,a),a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_2D);b?J.bindTexture(r.TEXTURE_CUBE_MAP,null):J.bindTexture(r.TEXTURE_2D,null);r.bindRenderbuffer(r.RENDERBUFFER,null);r.bindFramebuffer(r.FRAMEBUFFER,null)}a?(c=V.get(a),d=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,c=a.width,e=a.height,h=g=0):(d=null,c=pa,e=qa,g=na,h=oa);d!==ia&&(r.bindFramebuffer(r.FRAMEBUFFER,d),r.viewport(g,h,c,e),ia=d);b&&(d=V.get(a.texture),r.framebufferTexture2D(r.FRAMEBUFFER,
-r.COLOR_ATTACHMENT0,r.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,d.__webglTexture,0));Ca=c;Da=e};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(V.get(a).__webglFramebuffer){var g=!1;V.get(a).__webglFramebuffer!==ia&&(r.bindFramebuffer(r.FRAMEBUFFER,V.get(a).__webglFramebuffer),g=!0);a.texture.format!==THREE.RGBAFormat&&A(a.texture.format)!==
-r.getParameter(r.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):a.texture.type!==THREE.UnsignedByteType&&A(a.texture.type)!==r.getParameter(r.IMPLEMENTATION_COLOR_READ_TYPE)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type."):(r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE?r.readPixels(b,c,d,
-e,A(a.texture.format),A(a.texture.type),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."),g&&r.bindFramebuffer(r.FRAMEBUFFER,ia))}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");return S.get("OES_texture_float")};this.supportsHalfFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");
-return S.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return S.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");return S.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC=
-function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return S.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return S.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return ga.vertexTextures};this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");
-return S.get("ANGLE_instanced_arrays")};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")};Object.defineProperties(this,{shadowMapEnabled:{get:function(){return ha.enabled},
-set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");ha.enabled=a}},shadowMapType:{get:function(){return ha.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");ha.type=a}},shadowMapCullFace:{get:function(){return ha.cullFace},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");ha.cullFace=a}},shadowMapDebug:{get:function(){return ha.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.");
-ha.debug=a}}})};THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;c=c||{};void 0===c.minFilter&&(c.minFilter=THREE.LinearFilter);this.texture=new THREE.Texture(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null};
+r.COLOR_ATTACHMENT0,r.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,d.__webglTexture,0));Ca=c;Da=e};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if(V.get(a).__webglFramebuffer){var g=!1;V.get(a).__webglFramebuffer!==ia&&(r.bindFramebuffer(r.FRAMEBUFFER,V.get(a).__webglFramebuffer),g=!0);try{a.texture.format!==THREE.RGBAFormat&&A(a.texture.format)!==
+r.getParameter(r.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):a.texture.type===THREE.UnsignedByteType||A(a.texture.type)===r.getParameter(r.IMPLEMENTATION_COLOR_READ_TYPE)||a.texture.type===THREE.FloatType&&S.get("WEBGL_color_buffer_float")||a.texture.type===THREE.HalfFloatType&&S.get("EXT_color_buffer_half_float")?r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE?r.readPixels(b,
+c,d,e,A(a.texture.format),A(a.texture.type),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{g&&r.bindFramebuffer(r.FRAMEBUFFER,ia)}}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");
+return S.get("OES_texture_float")};this.supportsHalfFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return S.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return S.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");
+return S.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return S.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return S.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return ga.vertexTextures};
+this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");return S.get("ANGLE_instanced_arrays")};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};
+this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")};Object.defineProperties(this,{shadowMapEnabled:{get:function(){return ha.enabled},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");ha.enabled=a}},shadowMapType:{get:function(){return ha.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");ha.type=a}},shadowMapCullFace:{get:function(){return ha.cullFace},
+set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");ha.cullFace=a}},shadowMapDebug:{get:function(){return ha.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.");ha.debug=a}}})};
+THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;c=c||{};void 0===c.minFilter&&(c.minFilter=THREE.LinearFilter);this.texture=new THREE.Texture(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null};
 THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,get wrapS(){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");return this.texture.wrapS},set wrapS(a){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");this.texture.wrapS=a},get wrapT(){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");return this.texture.wrapT},set wrapT(a){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");this.texture.wrapT=a},
 get magFilter(){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");return this.texture.magFilter},set magFilter(a){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");this.texture.magFilter=a},get minFilter(){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");return this.texture.minFilter},set minFilter(a){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");this.texture.minFilter=a},get anisotropy(){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");
 return this.texture.anisotropy},set anisotropy(a){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");this.texture.anisotropy=a},get offset(){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");return this.texture.offset},set offset(a){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");this.texture.offset=a},get repeat(){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");return this.texture.repeat},set repeat(a){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");

+ 293 - 0
examples/webgl_read_float_buffer.html

@@ -0,0 +1,293 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - read float pixels</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 {
+				color: #ffffff;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+				font-weight: bold;
+				background-color: #000000;
+				margin: 0px;
+				overflow: hidden;
+			}
+
+			#info {
+				position: absolute;
+				top: 0px; width: 100%;
+				padding: 5px;
+			}
+
+			a {
+				color: #ffffff;
+			}
+
+		</style>
+	</head>
+	<body>
+
+		<div id="container"></div>
+		<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> read float pixels webgl example</div>
+
+		<script src="../build/three.min.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/stats.min.js"></script>
+
+		<script id="fragment_shader_screen" type="x-shader/x-fragment">
+
+			varying vec2 vUv;
+			uniform sampler2D tDiffuse;
+
+			void main() {
+
+				gl_FragColor = texture2D( tDiffuse, vUv );
+
+			}
+
+		</script>
+
+		<script id="fragment_shader_pass_1" type="x-shader/x-fragment">
+
+			varying vec2 vUv;
+			uniform float time;
+
+			void main() {
+
+				float r = vUv.x;
+				if( vUv.y < 0.5 ) r = 0.0;
+				float g = vUv.y;
+				if( vUv.x < 0.5 ) g = 0.0;
+
+				gl_FragColor = vec4( r, g, time, 1.0 );
+
+			}
+
+		</script>
+
+		<script id="vertexShader" type="x-shader/x-vertex">
+
+			varying vec2 vUv;
+
+			void main() {
+
+				vUv = uv;
+				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+			}
+
+		</script>
+
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var container, stats;
+
+			var cameraRTT, camera, sceneRTT, sceneScreen, scene, renderer, zmesh1, zmesh2;
+
+			var mouseX = 0, mouseY = 0;
+
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
+
+			var rtTexture, material, quad;
+
+			var delta = 0.01;
+            var valueNode;
+            
+			init();
+			animate();
+
+			function init() {
+
+				container = document.getElementById( 'container' );
+
+				camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 10000 );
+				camera.position.z = 100;
+
+				cameraRTT = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 );
+				cameraRTT.position.z = 100;
+
+				//
+
+				scene = new THREE.Scene();
+				sceneRTT = new THREE.Scene();
+				sceneScreen = new THREE.Scene();
+
+				var light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( 0, 0, 1 ).normalize();
+				sceneRTT.add( light );
+
+				light = new THREE.DirectionalLight( 0xffaaaa, 1.5 );
+				light.position.set( 0, 0, -1 ).normalize();
+				sceneRTT.add( light );
+
+                rtTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat, type:THREE.FloatType } );
+
+				material = new THREE.ShaderMaterial( {
+
+					uniforms: { time: { type: "f", value: 0.0 } },
+					vertexShader: document.getElementById( 'vertexShader' ).textContent,
+					fragmentShader: document.getElementById( 'fragment_shader_pass_1' ).textContent
+
+				} );
+
+				var materialScreen = new THREE.ShaderMaterial( {
+
+					uniforms: { tDiffuse: { type: "t", value: rtTexture } },
+					vertexShader: document.getElementById( 'vertexShader' ).textContent,
+					fragmentShader: document.getElementById( 'fragment_shader_screen' ).textContent,
+
+					depthWrite: false
+
+				} );
+
+				var plane = new THREE.PlaneBufferGeometry( window.innerWidth, window.innerHeight );
+
+				quad = new THREE.Mesh( plane, material );
+				quad.position.z = -100;
+				sceneRTT.add( quad );
+
+				var geometry = new THREE.TorusGeometry( 100, 25, 15, 30 );
+
+				var mat1 = new THREE.MeshPhongMaterial( { color: 0x555555, specular: 0xffaa00, shininess: 5 } );
+				var mat2 = new THREE.MeshPhongMaterial( { color: 0x550000, specular: 0xff2200, shininess: 5 } );
+
+				zmesh1 = new THREE.Mesh( geometry, mat1 );
+				zmesh1.position.set( 0, 0, 100 );
+				zmesh1.scale.set( 1.5, 1.5, 1.5 );
+				sceneRTT.add( zmesh1 );
+
+				zmesh2 = new THREE.Mesh( geometry, mat2 );
+				zmesh2.position.set( 0, 150, 100 );
+				zmesh2.scale.set( 0.75, 0.75, 0.75 );
+				sceneRTT.add( zmesh2 );
+
+				quad = new THREE.Mesh( plane, materialScreen );
+				quad.position.z = -100;
+				sceneScreen.add( quad );
+
+				var n = 5,
+					geometry = new THREE.SphereGeometry( 10, 64, 32 ),
+					material2 = new THREE.MeshBasicMaterial( { color: 0xffffff, map: rtTexture } );
+
+				for( var j = 0; j < n; j ++ ) {
+
+					for( var i = 0; i < n; i ++ ) {
+
+						mesh = new THREE.Mesh( geometry, material2 );
+
+						mesh.position.x = ( i - ( n - 1 ) / 2 ) * 20;
+						mesh.position.y = ( j - ( n - 1 ) / 2 ) * 20;
+						mesh.position.z = 0;
+
+						mesh.rotation.y = - Math.PI / 2;
+
+						scene.add( mesh );
+
+					}
+
+				}
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.autoClear = false;
+
+				container.appendChild( renderer.domElement );
+
+				stats = new Stats();
+				stats.domElement.style.position = 'absolute';
+				stats.domElement.style.top = '0px';
+				container.appendChild( stats.domElement );
+                
+                var valueDiv = document.createElement('div');
+                valueDiv.style.position = 'absolute';
+                valueDiv.style.top = '0px';
+                valueDiv.style.right = '0px';
+                valueDiv.style.width = '500px';
+                valueDiv.style.height = '300px';
+                valueDiv.style.fontSize = '60px';
+                container.appendChild( valueDiv );
+                valueNode = document.createTextNode('');
+                valueDiv.appendChild(valueNode);
+                
+
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+
+			}
+
+			function onDocumentMouseMove( event ) {
+
+				mouseX = ( event.clientX - windowHalfX );
+				mouseY = ( event.clientY - windowHalfY );
+
+			}
+
+			//
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				render();
+				stats.update();
+
+			}
+
+			function render() {
+
+				var time = Date.now() * 0.0015;
+
+				camera.position.x += ( mouseX - camera.position.x ) * .05;
+				camera.position.y += ( - mouseY - camera.position.y ) * .05;
+
+				camera.lookAt( scene.position );
+
+				if ( zmesh1 && zmesh2 ) {
+
+					zmesh1.rotation.y = - time;
+					zmesh2.rotation.y = - time + Math.PI / 2;
+
+				}
+
+				if ( material.uniforms.time.value > 1 || material.uniforms.time.value < 0 ) {
+
+					delta *= -1;
+
+				}
+
+				material.uniforms.time.value += delta;
+
+				renderer.clear();
+
+				// Render first scene into texture
+
+				renderer.render( sceneRTT, cameraRTT, rtTexture, true );
+
+				// Render full screen quad with generated texture
+
+				renderer.render( sceneScreen, cameraRTT );
+
+				// Render second scene to screen
+				// (using first scene as regular texture)
+
+				renderer.render( scene, camera );
+                
+                
+                var read = new Float32Array(4);
+                renderer.readRenderTargetPixels(rtTexture, windowHalfX + mouseX, windowHalfY - mouseY, 1, 1, read);
+                
+                valueNode.nodeValue ='r:' + read[0] +' g:' + read[1] + ' b:' + read[2];
+
+			}
+
+		</script>
+	</body>
+</html>